4 * by ]d : Original idea and basic initial code
5 * Pascal Hofstee : Code for wheeldrawing and calculating
7 * Primary coder of this Color Panel.
8 * Alban Hertroys : Optimizations for algorithms for color-
9 * wheel. Also custom ColorPalettes and
10 * magnifying glass. Secondary coder ;)
11 * Alfredo K. Kojima : For pointing out memory-allocation
12 * problems and similair code-issues
13 * Marco van Hylckama-Vlieg : For once again doing the artwork ;-)
19 * - Look at further optimization of colorWheel matrix calculation.
20 * It appears to be rather symmetric in angles of 60 degrees,
21 * while it is optimized in angles of 120 degrees.
22 * - Custom color-lists and custom colors in custom colo-lists.
27 #include "../src/config.h"
33 #include <sys/types.h>
38 /* BUG There's something fishy with shaped windows */
41 #define SHAPE_WAS_DEFINED
48 #include <X11/extensions/shape.h>
53 # define PATH_MAX 1024
57 char *WMColorPanelColorChangedNotification
= "WMColorPanelColorChangedNotification";
62 #define NO_MEMORY_ERR "Color Panel: Could not allocate memory"
63 #define NO_FILE_ERR "Color Panel: Could not find file"
64 #define X_ERR "Color Panel: X failed request"
68 * Bitmaps for magnifying glass cursor
72 #define Cursor_x_hot 11
73 #define Cursor_y_hot 11
74 #define Cursor_width 32
75 #define Cursor_height 32
76 static unsigned char Cursor_bits
[] = {
77 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
78 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
79 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
80 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
81 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
82 0x00,0x08,0x00,0x50,0x00,0x10,0x00,0x88,0x00,0x20,0x00,0x5c,0x01,0xc0,0x81,
83 0x3b,0x02,0x00,0x7e,0x70,0x05,0x00,0x00,0xe0,0x08,0x00,0x00,0xc0,0x15,0x00,
84 0x00,0x80,0x23,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x5c,
85 0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x70};
87 /* Cursor shape-mask */
88 #define Cursor_shape_width 32
89 #define Cursor_shape_height 32
90 static unsigned char Cursor_shape_bits
[] = {
91 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
92 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
93 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
94 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
95 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
96 0x00,0x08,0x00,0x70,0x00,0x10,0x00,0xf8,0x00,0x20,0x00,0xfc,0x01,0xc0,0x81,
97 0xfb,0x03,0x00,0x7e,0xf0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x1f,0x00,
98 0x00,0x80,0x3f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfc,
99 0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70};
101 /* Clip-mask for magnified pixels */
102 #define Cursor_mask_width 24
103 #define Cursor_mask_height 24
104 static unsigned char Cursor_mask_bits
[] = {
105 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07,
106 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
107 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
108 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f,
109 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f,
110 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00};
113 typedef struct MovingView
{
114 WMView
*view
; /* The view this is all about */
115 XImage
*image
; /* What's under the view */
116 XImage
*dirtyRect
; /* Storage of overlapped image area */
117 Pixmap magPix
; /* Magnified part of pixmap */
118 RColor color
; /* Color of a pixel in the image */
119 int x
, y
; /* Position of view */
122 typedef struct CPColor
{
123 RColor rgb
; /* The RGB values of the color */
124 RHSVColor hsv
; /* The HSV values of the color */
125 enum { /* Which one was last set ? */
133 typedef struct WheelMatrix
{
134 unsigned int width
, height
; /* Size of the colorwheel */
135 unsigned char *data
[3]; /* Wheel data (R,G,B) */
136 unsigned char values
[256]; /* Precalculated values R,G & B = 0-255 */
139 typedef struct W_ColorPanel
{
147 WMColorWell
*colorWell
;
148 WMButton
*magnifyBtn
;
150 WMButton
*slidersBtn
;
151 WMButton
*customPaletteBtn
;
152 WMButton
*colorListBtn
;
154 /* Magnifying Glass */
155 MovingView
*magnifyGlass
;
157 /* ColorWheel Panel */
159 WMSlider
*wheelBrightnessS
;
164 WMFrame
*seperatorFrm
;
169 /* Gray Scale Panel */
173 WMSlider
*grayBrightnessS
;
174 WMTextField
*grayBrightnessT
;
175 WMButton
*grayPresetBtn
[7];
184 WMTextField
*rgbRedT
;
185 WMTextField
*rgbGreenT
;
186 WMTextField
*rgbBlueT
;
193 WMSlider
*cmykMagentaS
;
194 WMSlider
*cmykYellowS
;
195 WMSlider
*cmykBlackS
;
196 WMTextField
*cmykCyanT
;
197 WMTextField
*cmykMagentaT
;
198 WMTextField
*cmykYellowT
;
199 WMTextField
*cmykBlackT
;
204 WMSlider
*hsbSaturationS
;
205 WMSlider
*hsbBrightnessS
;
206 WMTextField
*hsbHueT
;
207 WMTextField
*hsbSaturationT
;
208 WMTextField
*hsbBrightnessT
;
210 /* Custom Palette Panel*/
211 WMFrame
*customPaletteFrm
;
212 WMPopUpButton
*customPaletteHistoryBtn
;
213 WMFrame
*customPaletteContentFrm
;
214 WMPopUpButton
*customPaletteMenuBtn
;
215 WMView
*customPaletteContentView
;
217 /* Color List Panel */
218 WMFrame
*colorListFrm
;
219 WMPopUpButton
*colorListHistoryBtn
;
220 WMList
*colorListContentLst
;
221 WMPopUpButton
*colorListColorMenuBtn
;
222 WMPopUpButton
*colorListListMenuBtn
;
224 /* Look-Up Tables and Images */
225 wheelMatrix
*wheelMtrx
;
228 Pixmap selectionBackImg
;
229 RImage
*customPaletteImg
;
232 /* Common Data Fields */
233 CPColor color
; /* Current color */
234 WMColorPanelMode mode
; /* Current color selection mode */
235 WMColorPanelMode slidersmode
; /* Current color sel. mode sliders panel */
236 WMColorPanelMode lastChanged
; /* Panel that last changed the color */
237 int colx
, coly
; /* (x,y) of sel.-marker in WheelMode */
238 int palx
, paly
; /* (x,y) of sel.-marker in
240 float palXRatio
, palYRatio
; /* Ratios in x & y between
244 char *configurationPath
;
247 unsigned int continuous
:1;
248 unsigned int dragging
:1;
257 CPmenuNewFromClipboard
258 } customPaletteMenuItem
;
269 #define colorWheelSize 150
270 #define customPaletteWidth 182
271 #define customPaletteHeight 106
272 #define knobThickness 8
274 #define SPECTRUM_WIDTH 511
275 #define SPECTRUM_HEIGHT 360
277 #define COLORWHEEL_PART 1
278 #define CUSTOMPALETTE_PART 2
282 #define RGBTXT "/usr/X11R6/lib/X11/rgb.txt"
285 #define MAX_LENGTH 1024
287 static int fetchFile(char* toPath
, char *imageSrcFile
,
288 char *imageDestFileName
);
289 char *generateNewFilename(char *curName
);
290 void convertCPColor(CPColor
*color
);
291 RColor
ulongToRColor(WMScreen
*scr
, unsigned long value
);
292 unsigned char getShift(unsigned char value
);
294 static void modeButtonCallback(WMWidget
*w
, void *data
);
295 static int getPickerPart(W_ColorPanel
*panel
, int x
, int y
);
296 static void readConfiguration(W_ColorPanel
*panel
);
297 static void readXColors(W_ColorPanel
*panel
);
299 static void closeWindowCallback(WMWidget
*w
, void *data
);
301 static Cursor
magnifyGrabPointer(W_ColorPanel
*panel
);
302 static WMPoint
magnifyInitialize(W_ColorPanel
*panel
);
303 static void magnifyPutCursor(WMWidget
*w
, void *data
);
304 static Pixmap
magnifyCreatePixmap(WMColorPanel
*panel
);
305 static void magnifyGetImageStored(W_ColorPanel
*panel
, int x1
, int y1
,
307 static XImage
* magnifyGetImage(WMScreen
*scr
, XImage
*image
, int x
, int y
,
310 static wheelMatrix
* wheelCreateMatrix(unsigned int width
, unsigned int height
);
311 static void wheelDestroyMatrix(wheelMatrix
*matrix
);
312 static void wheelInitMatrix(W_ColorPanel
*panel
);
313 static void wheelCalculateValues(W_ColorPanel
*panel
, int maxvalue
);
314 static void wheelRender(W_ColorPanel
*panel
);
315 static Bool
wheelInsideColorWheel(W_ColorPanel
*panel
, unsigned long ofs
);
316 static void wheelPaint(W_ColorPanel
*panel
);
318 static void wheelHandleEvents(XEvent
*event
, void *data
);
319 static void wheelHandleActionEvents(XEvent
*event
, void *data
);
320 static void wheelBrightnessSliderCallback(WMWidget
*w
, void *data
);
321 static void wheelUpdateSelection(W_ColorPanel
*panel
);
322 static void wheelUndrawSelection(W_ColorPanel
*panel
);
324 static void wheelPositionSelection(W_ColorPanel
*panel
, int x
, int y
);
325 static void wheelPositionSelectionOutBounds(W_ColorPanel
*panel
, int x
, int y
);
326 static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel
*panel
);
327 static void wheelUpdateBrightnessGradient(W_ColorPanel
*panel
, CPColor topColor
);
329 static void grayBrightnessSliderCallback(WMWidget
*w
, void *data
);
330 static void grayPresetButtonCallback(WMWidget
*w
, void *data
);
331 static void grayBrightnessTextFieldCallback(void *observerData
,
332 WMNotification
*notification
);
334 static void rgbSliderCallback(WMWidget
*w
, void *data
);
335 static void rgbTextFieldCallback(void *observerData
,
336 WMNotification
*notification
);
338 static void cmykSliderCallback(WMWidget
*w
, void *data
);
339 static void cmykTextFieldCallback(void *observerData
,
340 WMNotification
*notification
);
342 static void hsbSliderCallback(WMWidget
*w
, void *data
);
343 static void hsbTextFieldCallback(void *observerData
,
344 WMNotification
*notification
);
345 static void hsbUpdateBrightnessGradient(W_ColorPanel
*panel
);
346 static void hsbUpdateSaturationGradient(W_ColorPanel
*panel
);
347 static void hsbUpdateHueGradient(W_ColorPanel
*panel
);
349 static void customRenderSpectrum(W_ColorPanel
*panel
);
350 static void customSetPalette(W_ColorPanel
*panel
);
351 static void customPaletteHandleEvents(XEvent
*event
, void *data
);
352 static void customPaletteHandleActionEvents(XEvent
*event
, void *data
);
353 static void customPalettePositionSelection(W_ColorPanel
*panel
, int x
, int y
);
354 static void customPalettePositionSelectionOutBounds(W_ColorPanel
*panel
,
356 static void customPaletteMenuCallback(WMWidget
*w
, void *data
);
357 static void customPaletteHistoryCallback(WMWidget
*w
, void *data
);
359 static void customPaletteMenuNewFromFile(W_ColorPanel
*panel
);
360 static void customPaletteMenuRename(W_ColorPanel
*panel
);
361 static void customPaletteMenuRemove(W_ColorPanel
*panel
);
363 static void colorListPaintItem(WMList
*lPtr
, int index
, Drawable d
, char *text
,
364 int state
, WMRect
*rect
);
365 static void colorListSelect(WMWidget
*w
, void *data
);
366 static void colorListColorMenuCallback(WMWidget
*w
, void *data
);
367 static void colorListListMenuCallback(WMWidget
*w
, void *data
);
368 static void colorListListMenuNew(W_ColorPanel
*panel
);
370 static void wheelInit(W_ColorPanel
*panel
);
371 static void grayInit(W_ColorPanel
*panel
);
372 static void rgbInit(W_ColorPanel
*panel
);
373 static void cmykInit(W_ColorPanel
*panel
);
374 static void hsbInit(W_ColorPanel
*panel
);
379 WMSetColorPanelAction(WMColorPanel
*panel
, WMAction2
*action
, void *data
)
381 panel
->action
= action
;
382 panel
->clientData
= data
;
386 makeColorPanel(WMScreen
*scrPtr
, char *name
)
393 WMColor
*textcolor
, *graybuttoncolor
;
395 GC bgc
= WMColorGC(scrPtr
->black
);
396 GC wgc
= WMColorGC(scrPtr
->white
);
399 panel
= wmalloc(sizeof(WMColorPanel
));
400 memset(panel
, 0, sizeof(WMColorPanel
));
402 panel
->color
.rgb
.red
= 0;
403 panel
->color
.rgb
.green
= 0;
404 panel
->color
.rgb
.blue
= 0;
405 panel
->color
.hsv
.hue
= 0;
406 panel
->color
.hsv
.saturation
= 0;
407 panel
->color
.hsv
.value
= 0;
408 panel
->color
.set
= cpNone
; /* Color has not been set yet */
410 panel
->font8
= WMSystemFontOfSize(scrPtr
, 8);
411 panel
->font12
= WMSystemFontOfSize(scrPtr
, 12);
413 panel
->win
= WMCreateWindowWithStyle(scrPtr
, name
,
414 WMTitledWindowMask
| WMClosableWindowMask
| WMResizableWindowMask
);
415 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
416 WMSetWindowTitle(panel
->win
, "Colors");
417 WMSetWindowCloseAction(panel
->win
, closeWindowCallback
, panel
);
420 /* Set Default ColorPanel Mode(s) */
421 panel
->mode
= WMWheelModeColorPanel
;
422 panel
->lastChanged
= 0;
423 panel
->slidersmode
= WMRGBModeColorPanel
;
424 panel
->configurationPath
= wstrappend(wusergnusteppath(),
427 /* Some General Purpose Widgets */
428 panel
->colorWell
= WMCreateColorWell(panel
->win
);
429 WMResizeWidget(panel
->colorWell
, 134, 36);
430 WSetColorWellBordered(panel
->colorWell
, False
);
431 WMMoveWidget(panel
->colorWell
, 56, 4);
433 panel
->magnifyBtn
= WMCreateCustomButton(panel
->win
,
434 WBBStateLightMask
|WBBStateChangeMask
);
435 WMResizeWidget(panel
->magnifyBtn
, 46, 36);
436 WMMoveWidget(panel
->magnifyBtn
, 6,4);
437 WMSetButtonAction(panel
->magnifyBtn
, magnifyPutCursor
, panel
);
438 WMSetButtonImagePosition(panel
->magnifyBtn
, WIPImageOnly
);
439 WMSetButtonImage(panel
->magnifyBtn
, scrPtr
->magnifyIcon
);
441 panel
->wheelBtn
= WMCreateCustomButton(panel
->win
,
442 WBBStateLightMask
|WBBStateChangeMask
);
443 WMResizeWidget(panel
->wheelBtn
, 46, 32);
444 WMMoveWidget(panel
->wheelBtn
, 6, 44);
445 WMSetButtonAction(panel
->wheelBtn
, modeButtonCallback
, panel
);
446 WMSetButtonImagePosition(panel
->wheelBtn
, WIPImageOnly
);
447 WMSetButtonImage(panel
->wheelBtn
, scrPtr
->wheelIcon
);
449 panel
->slidersBtn
= WMCreateCustomButton(panel
->win
,
450 WBBStateLightMask
|WBBStateChangeMask
);
451 WMResizeWidget(panel
->slidersBtn
, 46, 32);
452 WMMoveWidget(panel
->slidersBtn
, 52, 44);
453 WMSetButtonAction(panel
->slidersBtn
, modeButtonCallback
, panel
);
454 WMSetButtonImagePosition(panel
->slidersBtn
, WIPImageOnly
);
455 WMSetButtonImage(panel
->slidersBtn
, scrPtr
->rgbIcon
);
457 panel
->customPaletteBtn
= WMCreateCustomButton(panel
->win
,
458 WBBStateLightMask
|WBBStateChangeMask
);
459 WMResizeWidget(panel
->customPaletteBtn
, 46, 32);
460 WMMoveWidget(panel
->customPaletteBtn
, 98, 44);
461 WMSetButtonAction(panel
->customPaletteBtn
, modeButtonCallback
, panel
);
462 WMSetButtonImagePosition(panel
->customPaletteBtn
, WIPImageOnly
);
463 WMSetButtonImage(panel
->customPaletteBtn
, scrPtr
->customPaletteIcon
);
465 panel
->colorListBtn
= WMCreateCustomButton(panel
->win
,
466 WBBStateLightMask
|WBBStateChangeMask
);
467 WMResizeWidget(panel
->colorListBtn
, 46, 32);
468 WMMoveWidget(panel
->colorListBtn
, 144, 44);
469 WMSetButtonAction(panel
->colorListBtn
, modeButtonCallback
, panel
);
470 WMSetButtonImagePosition(panel
->colorListBtn
, WIPImageOnly
);
471 WMSetButtonImage(panel
->colorListBtn
, scrPtr
->colorListIcon
);
473 /* Let's Group some of them together */
474 WMGroupButtons(panel
->wheelBtn
, panel
->slidersBtn
);
475 WMGroupButtons(panel
->wheelBtn
, panel
->customPaletteBtn
);
476 WMGroupButtons(panel
->wheelBtn
, panel
->colorListBtn
);
478 /* Widgets for the ColorWheel Panel */
479 panel
->wheelFrm
= WMCreateFrame(panel
->win
);
480 WMSetFrameRelief(panel
->wheelFrm
, WRFlat
);
481 WMResizeWidget(panel
->wheelFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
482 WMMoveWidget(panel
->wheelFrm
, 5, 80);
484 panel
->wheelView
= W_CreateView(W_VIEW(panel
->wheelFrm
));
485 /* XXX Can we create a view ? */
486 W_ResizeView(panel
->wheelView
, colorWheelSize
+4, colorWheelSize
+4);
487 W_MoveView(panel
->wheelView
, 0, 0);
489 /* Create an event handler to handle expose/click events in ColorWheel */
490 WMCreateEventHandler(panel
->wheelView
,
491 ButtonPressMask
|ButtonReleaseMask
|EnterWindowMask
|
492 LeaveWindowMask
|ButtonMotionMask
, wheelHandleActionEvents
, panel
);
494 WMCreateEventHandler(panel
->wheelView
, ExposureMask
, wheelHandleEvents
,
497 panel
->wheelBrightnessS
= WMCreateSlider(panel
->wheelFrm
);
498 WMResizeWidget(panel
->wheelBrightnessS
, 16, 153);
499 WMMoveWidget(panel
->wheelBrightnessS
, 5+colorWheelSize
+14, 1);
500 WMSetSliderMinValue(panel
->wheelBrightnessS
, 0);
501 WMSetSliderMaxValue(panel
->wheelBrightnessS
, 255);
502 WMSetSliderAction(panel
->wheelBrightnessS
, wheelBrightnessSliderCallback
,
504 WMSetSliderKnobThickness(panel
->wheelBrightnessS
, knobThickness
);
506 panel
->wheelMtrx
= wheelCreateMatrix(colorWheelSize
+4, colorWheelSize
+4);
507 wheelInitMatrix(panel
);
510 /* Widgets for the Slider Panels */
511 panel
->slidersFrm
= WMCreateFrame(panel
->win
);
512 WMSetFrameRelief(panel
->slidersFrm
, WRFlat
);
513 WMResizeWidget(panel
->slidersFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
514 WMMoveWidget(panel
->slidersFrm
, 4, 80);
516 panel
->seperatorFrm
= WMCreateFrame(panel
->slidersFrm
);
517 WMSetFrameRelief(panel
->seperatorFrm
, WRPushed
);
518 WMResizeWidget(panel
->seperatorFrm
, PWIDTH
- 8, 2);
519 WMMoveWidget(panel
->seperatorFrm
, 0, 1);
521 panel
->grayBtn
= WMCreateCustomButton(panel
->slidersFrm
,
522 WBBStateLightMask
|WBBStateChangeMask
);
523 WMResizeWidget(panel
->grayBtn
, 46, 24);
524 WMMoveWidget(panel
->grayBtn
, 1, 8);
525 WMSetButtonAction(panel
->grayBtn
, modeButtonCallback
, panel
);
526 WMSetButtonImagePosition(panel
->grayBtn
, WIPImageOnly
);
527 WMSetButtonImage(panel
->grayBtn
, scrPtr
->grayIcon
);
529 panel
->rgbBtn
= WMCreateCustomButton(panel
->slidersFrm
,
530 WBBStateLightMask
|WBBStateChangeMask
);
531 WMResizeWidget(panel
->rgbBtn
, 46, 24);
532 WMMoveWidget(panel
->rgbBtn
, 47, 8);
533 WMSetButtonAction(panel
->rgbBtn
, modeButtonCallback
, panel
);
534 WMSetButtonImagePosition(panel
->rgbBtn
, WIPImageOnly
);
535 WMSetButtonImage(panel
->rgbBtn
, scrPtr
->rgbIcon
);
537 panel
->cmykBtn
= WMCreateCustomButton(panel
->slidersFrm
,
538 WBBStateLightMask
|WBBStateChangeMask
);
539 WMResizeWidget(panel
->cmykBtn
, 46, 24);
540 WMMoveWidget(panel
->cmykBtn
, 93, 8);
541 WMSetButtonAction(panel
->cmykBtn
, modeButtonCallback
, panel
);
542 WMSetButtonImagePosition(panel
->cmykBtn
, WIPImageOnly
);
543 WMSetButtonImage(panel
->cmykBtn
, scrPtr
->cmykIcon
);
545 panel
->hsbBtn
= WMCreateCustomButton(panel
->slidersFrm
,
546 WBBStateLightMask
|WBBStateChangeMask
);
547 WMResizeWidget(panel
->hsbBtn
, 46, 24);
548 WMMoveWidget(panel
->hsbBtn
, 139, 8);
549 WMSetButtonAction(panel
->hsbBtn
, modeButtonCallback
, panel
);
550 WMSetButtonImagePosition(panel
->hsbBtn
, WIPImageOnly
);
551 WMSetButtonImage(panel
->hsbBtn
, scrPtr
->hsbIcon
);
553 /* Let's Group the Slider Panel Buttons Together */
554 WMGroupButtons(panel
->grayBtn
, panel
->rgbBtn
);
555 WMGroupButtons(panel
->grayBtn
, panel
->cmykBtn
);
556 WMGroupButtons(panel
->grayBtn
, panel
->hsbBtn
);
558 textcolor
= WMDarkGrayColor(scrPtr
);
560 /* Widgets for GrayScale Panel */
561 panel
->grayFrm
= WMCreateFrame(panel
->slidersFrm
);
562 WMSetFrameRelief(panel
->grayFrm
, WRFlat
);
563 WMResizeWidget(panel
->grayFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
564 WMMoveWidget(panel
->grayFrm
, 0, 34);
566 panel
->grayMinL
= WMCreateLabel(panel
->grayFrm
);
567 WMResizeWidget(panel
->grayMinL
, 20, 10);
568 WMMoveWidget(panel
->grayMinL
, 2, 2);
569 WMSetLabelText(panel
->grayMinL
, "0");
570 WMSetLabelTextAlignment(panel
->grayMinL
, WALeft
);
571 WMSetLabelTextColor(panel
->grayMinL
, textcolor
);
572 WMSetLabelFont(panel
->grayMinL
, panel
->font8
);
574 panel
->grayMaxL
= WMCreateLabel(panel
->grayFrm
);
575 WMResizeWidget(panel
->grayMaxL
, 40, 10);
576 WMMoveWidget(panel
->grayMaxL
, 104, 2);
577 WMSetLabelText(panel
->grayMaxL
, "100");
578 WMSetLabelTextAlignment(panel
->grayMaxL
, WARight
);
579 WMSetLabelTextColor(panel
->grayMaxL
, textcolor
);
580 WMSetLabelFont(panel
->grayMaxL
, panel
->font8
);
582 panel
->grayBrightnessS
= WMCreateSlider(panel
->grayFrm
);
583 WMResizeWidget(panel
->grayBrightnessS
, 141, 16);
584 WMMoveWidget(panel
->grayBrightnessS
, 2, 14);
585 WMSetSliderMinValue(panel
->grayBrightnessS
, 0);
586 WMSetSliderMaxValue(panel
->grayBrightnessS
, 100);
587 WMSetSliderKnobThickness(panel
->grayBrightnessS
, knobThickness
);
588 WMSetSliderAction(panel
->grayBrightnessS
, grayBrightnessSliderCallback
,
599 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
600 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
601 RDestroyImage(image
);
604 W_PaintText(W_VIEW(panel
->grayBrightnessS
), pixmap
->pixmap
,
605 panel
->font12
, 2, 0, 100, WALeft
, WMColorGC(scrPtr
->white
),
606 False
, "Brightness", strlen("Brightness"));
608 wwarning(NO_MEMORY_ERR
);
610 WMSetSliderImage(panel
->grayBrightnessS
, pixmap
);
611 WMReleasePixmap(pixmap
);
613 panel
->grayBrightnessT
= WMCreateTextField(panel
->grayFrm
);
614 WMResizeWidget(panel
->grayBrightnessT
, 40, 18);
615 WMMoveWidget(panel
->grayBrightnessT
, 146, 13);
616 WMSetTextFieldAlignment(panel
->grayBrightnessT
, WALeft
);
617 WMAddNotificationObserver(grayBrightnessTextFieldCallback
, panel
,
618 WMTextDidEndEditingNotification
, panel
->grayBrightnessT
);
620 for (i
=0; i
< 7; i
++) {
621 pixmap
= WMCreatePixmap(scrPtr
, 13, 13, scrPtr
->depth
, False
);
623 graybuttoncolor
= WMCreateRGBColor(scrPtr
, (255/6)*i
<< 8,
624 (255/6)*i
<< 8, (255/6)*i
<< 8, True
);
625 WMPaintColorSwatch(graybuttoncolor
, pixmap
->pixmap
, 0, 0, 15, 15);
626 WMReleaseColor(graybuttoncolor
);
628 panel
->grayPresetBtn
[i
] = WMCreateCommandButton(panel
->grayFrm
);
629 WMResizeWidget(panel
->grayPresetBtn
[i
], 20, 24);
630 WMMoveWidget(panel
->grayPresetBtn
[i
], 2+(i
*20), 34);
631 WMSetButtonAction(panel
->grayPresetBtn
[i
],
632 grayPresetButtonCallback
, panel
);
633 WMSetButtonImage(panel
->grayPresetBtn
[i
], pixmap
);
634 WMSetButtonImagePosition(panel
->grayPresetBtn
[i
], WIPImageOnly
);
635 WMReleasePixmap(pixmap
);
639 /* End of GrayScale Panel */
641 /* Widgets for RGB Panel */
642 panel
->rgbFrm
= WMCreateFrame(panel
->slidersFrm
);
643 WMSetFrameRelief(panel
->rgbFrm
, WRFlat
);
644 WMResizeWidget(panel
->rgbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
645 WMMoveWidget(panel
->rgbFrm
, 0, 34);
647 panel
->rgbMinL
= WMCreateLabel(panel
->rgbFrm
);
648 WMResizeWidget(panel
->rgbMinL
, 20, 10);
649 WMMoveWidget(panel
->rgbMinL
, 2, 2);
650 WMSetLabelText(panel
->rgbMinL
, "0");
651 WMSetLabelTextAlignment(panel
->rgbMinL
, WALeft
);
652 WMSetLabelTextColor(panel
->rgbMinL
, textcolor
);
653 WMSetLabelFont(panel
->rgbMinL
, panel
->font8
);
655 panel
->rgbMaxL
= WMCreateLabel(panel
->rgbFrm
);
656 WMResizeWidget(panel
->rgbMaxL
, 40, 10);
657 WMMoveWidget(panel
->rgbMaxL
, 104, 2);
658 WMSetLabelText(panel
->rgbMaxL
, "255");
659 WMSetLabelTextAlignment(panel
->rgbMaxL
, WARight
);
660 WMSetLabelTextColor(panel
->rgbMaxL
, textcolor
);
661 WMSetLabelFont(panel
->rgbMaxL
, panel
->font8
);
663 panel
->rgbRedS
= WMCreateSlider(panel
->rgbFrm
);
664 WMResizeWidget(panel
->rgbRedS
, 141, 16);
665 WMMoveWidget(panel
->rgbRedS
, 2, 14);
666 WMSetSliderMinValue(panel
->rgbRedS
, 0);
667 WMSetSliderMaxValue(panel
->rgbRedS
, 255);
668 WMSetSliderKnobThickness(panel
->rgbRedS
, knobThickness
);
669 WMSetSliderAction(panel
->rgbRedS
, rgbSliderCallback
, panel
);
675 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
676 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
677 RDestroyImage(image
);
680 W_PaintText(W_VIEW(panel
->rgbRedS
), pixmap
->pixmap
, panel
->font12
,
681 2, 0, 100, WALeft
, WMColorGC(scrPtr
->white
), False
, "Red",
684 wwarning(NO_MEMORY_ERR
);
686 WMSetSliderImage(panel
->rgbRedS
, pixmap
);
687 WMReleasePixmap(pixmap
);
689 panel
->rgbRedT
= WMCreateTextField(panel
->rgbFrm
);
690 WMResizeWidget(panel
->rgbRedT
, 40, 18);
691 WMMoveWidget(panel
->rgbRedT
, 146, 13);
692 WMSetTextFieldAlignment(panel
->rgbRedT
, WALeft
);
693 WMAddNotificationObserver(rgbTextFieldCallback
, panel
,
694 WMTextDidEndEditingNotification
, panel
->rgbRedT
);
696 panel
->rgbGreenS
= WMCreateSlider(panel
->rgbFrm
);
697 WMResizeWidget(panel
->rgbGreenS
, 141, 16);
698 WMMoveWidget(panel
->rgbGreenS
, 2, 36);
699 WMSetSliderMinValue(panel
->rgbGreenS
, 0);
700 WMSetSliderMaxValue(panel
->rgbGreenS
, 255);
701 WMSetSliderKnobThickness(panel
->rgbGreenS
, knobThickness
);
702 WMSetSliderAction(panel
->rgbGreenS
, rgbSliderCallback
, panel
);
708 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
709 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
710 RDestroyImage(image
);
713 W_PaintText(W_VIEW(panel
->rgbGreenS
), pixmap
->pixmap
, panel
->font12
,
714 2, 0, 100, WALeft
, WMColorGC(scrPtr
->white
), False
, "Green",
717 wwarning(NO_MEMORY_ERR
);
719 WMSetSliderImage(panel
->rgbGreenS
, pixmap
);
720 WMReleasePixmap(pixmap
);
722 panel
->rgbGreenT
= WMCreateTextField(panel
->rgbFrm
);
723 WMResizeWidget(panel
->rgbGreenT
, 40, 18);
724 WMMoveWidget(panel
->rgbGreenT
, 146, 35);
725 WMSetTextFieldAlignment(panel
->rgbGreenT
, WALeft
);
726 WMAddNotificationObserver(rgbTextFieldCallback
, panel
,
727 WMTextDidEndEditingNotification
, panel
->rgbGreenT
);
730 panel
->rgbBlueS
= WMCreateSlider(panel
->rgbFrm
);
731 WMResizeWidget(panel
->rgbBlueS
, 141, 16);
732 WMMoveWidget(panel
->rgbBlueS
, 2, 58);
733 WMSetSliderMinValue(panel
->rgbBlueS
, 0);
734 WMSetSliderMaxValue(panel
->rgbBlueS
, 255);
735 WMSetSliderKnobThickness(panel
->rgbBlueS
, knobThickness
);
736 WMSetSliderAction(panel
->rgbBlueS
, rgbSliderCallback
, panel
);
742 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
743 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
744 RDestroyImage(image
);
747 W_PaintText(W_VIEW(panel
->rgbBlueS
), pixmap
->pixmap
, panel
->font12
,
748 2, 0, 100, WALeft
, WMColorGC(scrPtr
->white
), False
, "Blue",
751 wwarning(NO_MEMORY_ERR
);
753 WMSetSliderImage(panel
->rgbBlueS
, pixmap
);
754 WMReleasePixmap(pixmap
);
756 panel
->rgbBlueT
= WMCreateTextField(panel
->rgbFrm
);
757 WMResizeWidget(panel
->rgbBlueT
, 40, 18);
758 WMMoveWidget(panel
->rgbBlueT
, 146, 57);
759 WMSetTextFieldAlignment(panel
->rgbBlueT
, WALeft
);
760 WMAddNotificationObserver(rgbTextFieldCallback
, panel
,
761 WMTextDidEndEditingNotification
, panel
->rgbBlueT
);
762 /* End of RGB Panel */
764 /* Widgets for CMYK Panel */
765 panel
->cmykFrm
= WMCreateFrame(panel
->slidersFrm
);
766 WMSetFrameRelief(panel
->cmykFrm
, WRFlat
);
767 WMResizeWidget(panel
->cmykFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
768 WMMoveWidget(panel
->cmykFrm
, 0, 34);
770 panel
->cmykMinL
= WMCreateLabel(panel
->cmykFrm
);
771 WMResizeWidget(panel
->cmykMinL
, 20, 10);
772 WMMoveWidget(panel
->cmykMinL
, 2, 2);
773 WMSetLabelText(panel
->cmykMinL
, "0");
774 WMSetLabelTextAlignment(panel
->cmykMinL
, WALeft
);
775 WMSetLabelTextColor(panel
->cmykMinL
, textcolor
);
776 WMSetLabelFont(panel
->cmykMinL
, panel
->font8
);
778 panel
->cmykMaxL
= WMCreateLabel(panel
->cmykFrm
);
779 WMResizeWidget(panel
->cmykMaxL
, 40, 10);
780 WMMoveWidget(panel
->cmykMaxL
, 104, 2);
781 WMSetLabelText(panel
->cmykMaxL
, "100");
782 WMSetLabelTextAlignment(panel
->cmykMaxL
, WARight
);
783 WMSetLabelTextColor(panel
->cmykMaxL
, textcolor
);
784 WMSetLabelFont(panel
->cmykMaxL
, panel
->font8
);
786 panel
->cmykCyanS
= WMCreateSlider(panel
->cmykFrm
);
787 WMResizeWidget(panel
->cmykCyanS
, 141, 16);
788 WMMoveWidget(panel
->cmykCyanS
, 2, 14);
789 WMSetSliderMinValue(panel
->cmykCyanS
, 0);
790 WMSetSliderMaxValue(panel
->cmykCyanS
, 100);
791 WMSetSliderKnobThickness(panel
->cmykCyanS
, knobThickness
);
792 WMSetSliderAction(panel
->cmykCyanS
, cmykSliderCallback
, panel
);
802 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
803 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
804 RDestroyImage(image
);
807 W_PaintText(W_VIEW(panel
->cmykCyanS
), pixmap
->pixmap
, panel
->font12
,
808 2, 0, 100, WALeft
, WMColorGC(scrPtr
->black
), False
, "Cyan",
811 wwarning(NO_MEMORY_ERR
);
813 WMSetSliderImage(panel
->cmykCyanS
, pixmap
);
814 WMReleasePixmap(pixmap
);
816 panel
->cmykCyanT
= WMCreateTextField(panel
->cmykFrm
);
817 WMResizeWidget(panel
->cmykCyanT
, 40, 18);
818 WMMoveWidget(panel
->cmykCyanT
, 146, 13);
819 WMSetTextFieldAlignment(panel
->cmykCyanT
, WALeft
);
820 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
821 WMTextDidEndEditingNotification
, panel
->cmykCyanT
);
824 panel
->cmykMagentaS
= WMCreateSlider(panel
->cmykFrm
);
825 WMResizeWidget(panel
->cmykMagentaS
, 141, 16);
826 WMMoveWidget(panel
->cmykMagentaS
, 2, 36);
827 WMSetSliderMinValue(panel
->cmykMagentaS
, 0);
828 WMSetSliderMaxValue(panel
->cmykMagentaS
, 100);
829 WMSetSliderKnobThickness(panel
->cmykMagentaS
, knobThickness
);
830 WMSetSliderAction(panel
->cmykMagentaS
, cmykSliderCallback
, panel
);
836 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
837 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
838 RDestroyImage(image
);
841 W_PaintText(W_VIEW(panel
->cmykMagentaS
), pixmap
->pixmap
, panel
->font12
,
842 2, 0, 100, WALeft
, WMColorGC(scrPtr
->black
), False
, "Magenta",
845 wwarning(NO_MEMORY_ERR
);
847 WMSetSliderImage(panel
->cmykMagentaS
, pixmap
);
848 WMReleasePixmap(pixmap
);
850 panel
->cmykMagentaT
= WMCreateTextField(panel
->cmykFrm
);
851 WMResizeWidget(panel
->cmykMagentaT
, 40, 18);
852 WMMoveWidget(panel
->cmykMagentaT
, 146, 35);
853 WMSetTextFieldAlignment(panel
->cmykMagentaT
, WALeft
);
854 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
855 WMTextDidEndEditingNotification
, panel
->cmykMagentaT
);
858 panel
->cmykYellowS
= WMCreateSlider(panel
->cmykFrm
);
859 WMResizeWidget(panel
->cmykYellowS
, 141, 16);
860 WMMoveWidget(panel
->cmykYellowS
, 2, 58);
861 WMSetSliderMinValue(panel
->cmykYellowS
, 0);
862 WMSetSliderMaxValue(panel
->cmykYellowS
, 100);
863 WMSetSliderKnobThickness(panel
->cmykYellowS
, knobThickness
);
864 WMSetSliderAction(panel
->cmykYellowS
, cmykSliderCallback
, panel
);
870 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
871 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
872 RDestroyImage(image
);
875 W_PaintText(W_VIEW(panel
->cmykYellowS
), pixmap
->pixmap
, panel
->font12
,
876 2, 0, 100, WALeft
, WMColorGC(scrPtr
->black
), False
, "Yellow",
879 wwarning(NO_MEMORY_ERR
);
881 WMSetSliderImage(panel
->cmykYellowS
, pixmap
);
882 WMReleasePixmap(pixmap
);
884 panel
->cmykYellowT
= WMCreateTextField(panel
->cmykFrm
);
885 WMResizeWidget(panel
->cmykYellowT
, 40, 18);
886 WMMoveWidget(panel
->cmykYellowT
, 146, 57);
887 WMSetTextFieldAlignment(panel
->cmykYellowT
, WALeft
);
888 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
889 WMTextDidEndEditingNotification
, panel
->cmykYellowT
);
892 panel
->cmykBlackS
= WMCreateSlider(panel
->cmykFrm
);
893 WMResizeWidget(panel
->cmykBlackS
, 141, 16);
894 WMMoveWidget(panel
->cmykBlackS
, 2, 80);
895 WMSetSliderMinValue(panel
->cmykBlackS
, 0);
896 WMSetSliderMaxValue(panel
->cmykBlackS
, 100);
897 WMSetSliderValue(panel
->cmykBlackS
, 0);
898 WMSetSliderKnobThickness(panel
->cmykBlackS
, knobThickness
);
899 WMSetSliderAction(panel
->cmykBlackS
, cmykSliderCallback
, panel
);
905 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
906 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
907 RDestroyImage(image
);
910 W_PaintText(W_VIEW(panel
->cmykBlackS
), pixmap
->pixmap
, panel
->font12
,
911 2, 0, 100, WALeft
, WMColorGC(scrPtr
->black
), False
, "Black",
914 wwarning(NO_MEMORY_ERR
);
916 WMSetSliderImage(panel
->cmykBlackS
, pixmap
);
917 WMReleasePixmap(pixmap
);
919 panel
->cmykBlackT
= WMCreateTextField(panel
->cmykFrm
);
920 WMResizeWidget(panel
->cmykBlackT
, 40, 18);
921 WMMoveWidget(panel
->cmykBlackT
, 146, 79);
922 WMSetTextFieldAlignment(panel
->cmykBlackT
, WALeft
);
923 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
924 WMTextDidEndEditingNotification
, panel
->cmykBlackT
);
925 /* End of CMYK Panel */
927 /* Widgets for HSB Panel */
928 panel
->hsbFrm
= WMCreateFrame(panel
->slidersFrm
);
929 WMSetFrameRelief(panel
->hsbFrm
, WRFlat
);
930 WMResizeWidget(panel
->hsbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
931 WMMoveWidget(panel
->hsbFrm
, 0, 34);
933 panel
->hsbHueS
= WMCreateSlider(panel
->hsbFrm
);
934 WMResizeWidget(panel
->hsbHueS
, 141, 16);
935 WMMoveWidget(panel
->hsbHueS
, 2, 14);
936 WMSetSliderMinValue(panel
->hsbHueS
, 0);
937 WMSetSliderMaxValue(panel
->hsbHueS
, 359);
938 WMSetSliderKnobThickness(panel
->hsbHueS
, knobThickness
);
939 WMSetSliderAction(panel
->hsbHueS
, hsbSliderCallback
, panel
);
941 panel
->hsbHueT
= WMCreateTextField(panel
->hsbFrm
);
942 WMResizeWidget(panel
->hsbHueT
, 40, 18);
943 WMMoveWidget(panel
->hsbHueT
, 146, 13);
944 WMSetTextFieldAlignment(panel
->hsbHueT
, WALeft
);
945 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
946 WMTextDidEndEditingNotification
, panel
->hsbHueT
);
949 panel
->hsbSaturationS
= WMCreateSlider(panel
->hsbFrm
);
950 WMResizeWidget(panel
->hsbSaturationS
, 141, 16);
951 WMMoveWidget(panel
->hsbSaturationS
, 2, 36);
952 WMSetSliderMinValue(panel
->hsbSaturationS
, 0);
953 WMSetSliderMaxValue(panel
->hsbSaturationS
, 100);
954 WMSetSliderKnobThickness(panel
->hsbSaturationS
, knobThickness
);
955 WMSetSliderAction(panel
->hsbSaturationS
, hsbSliderCallback
, panel
);
957 panel
->hsbSaturationT
= WMCreateTextField(panel
->hsbFrm
);
958 WMResizeWidget(panel
->hsbSaturationT
, 40, 18);
959 WMMoveWidget(panel
->hsbSaturationT
, 146, 35);
960 WMSetTextFieldAlignment(panel
->hsbSaturationT
, WALeft
);
961 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
962 WMTextDidEndEditingNotification
, panel
->hsbSaturationT
);
965 panel
->hsbBrightnessS
= WMCreateSlider(panel
->hsbFrm
);
966 WMResizeWidget(panel
->hsbBrightnessS
, 141, 16);
967 WMMoveWidget(panel
->hsbBrightnessS
, 2, 58);
968 WMSetSliderMinValue(panel
->hsbBrightnessS
, 0);
969 WMSetSliderMaxValue(panel
->hsbBrightnessS
, 100);
970 WMSetSliderKnobThickness(panel
->hsbBrightnessS
, knobThickness
);
971 WMSetSliderAction(panel
->hsbBrightnessS
, hsbSliderCallback
, panel
);
973 panel
->hsbBrightnessT
= WMCreateTextField(panel
->hsbFrm
);
974 WMResizeWidget(panel
->hsbBrightnessT
, 40, 18);
975 WMMoveWidget(panel
->hsbBrightnessT
, 146, 57);
976 WMSetTextFieldAlignment(panel
->hsbBrightnessT
, WALeft
);
977 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
978 WMTextDidEndEditingNotification
, panel
->hsbBrightnessT
);
979 /* End of HSB Panel */
982 WMReleaseColor(textcolor
);
984 /* Widgets for the CustomPalette Panel */
985 panel
->customPaletteFrm
= WMCreateFrame(panel
->win
);
986 WMSetFrameRelief(panel
->customPaletteFrm
, WRFlat
);
987 WMResizeWidget(panel
->customPaletteFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
988 WMMoveWidget(panel
->customPaletteFrm
, 5, 80);
990 panel
->customPaletteHistoryBtn
= WMCreatePopUpButton(
991 panel
->customPaletteFrm
);
992 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, "Spectrum");
993 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
994 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
)-1);
995 WMSetPopUpButtonAction(panel
->customPaletteHistoryBtn
,
996 customPaletteHistoryCallback
, panel
);
997 WMResizeWidget(panel
->customPaletteHistoryBtn
, PWIDTH
- 8, 20);
998 WMMoveWidget(panel
->customPaletteHistoryBtn
, 0, 0);
1000 panel
->customPaletteContentFrm
= WMCreateFrame(panel
->customPaletteFrm
);
1001 WMSetFrameRelief(panel
->customPaletteContentFrm
, WRSunken
);
1002 WMResizeWidget(panel
->customPaletteContentFrm
, PWIDTH
- 8, PHEIGHT
- 156);
1003 WMMoveWidget(panel
->customPaletteContentFrm
, 0, 23);
1005 panel
->customPaletteContentView
= W_CreateView(
1006 W_VIEW(panel
->customPaletteContentFrm
));
1007 /* XXX Test if we can create a view */
1008 W_ResizeView(panel
->customPaletteContentView
, customPaletteWidth
,
1009 customPaletteHeight
);
1010 W_MoveView(panel
->customPaletteContentView
, 2, 2);
1012 /* Create event handler to handle expose/click events in CustomPalette */
1013 WMCreateEventHandler(panel
->customPaletteContentView
,
1014 ButtonPressMask
|ButtonReleaseMask
|EnterWindowMask
| LeaveWindowMask
|
1015 ButtonMotionMask
, customPaletteHandleActionEvents
, panel
);
1017 WMCreateEventHandler(panel
->customPaletteContentView
, ExposureMask
,
1018 customPaletteHandleEvents
, panel
);
1020 panel
->customPaletteMenuBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
1021 WMSetPopUpButtonPullsDown(panel
->customPaletteMenuBtn
, 1);
1022 WMSetPopUpButtonText(panel
->customPaletteMenuBtn
, "Palette");
1023 WMSetPopUpButtonAction(panel
->customPaletteMenuBtn
,
1024 customPaletteMenuCallback
, panel
);
1025 WMResizeWidget(panel
->customPaletteMenuBtn
, PWIDTH
- 8, 20);
1026 WMMoveWidget(panel
->customPaletteMenuBtn
, 0, PHEIGHT
- 130);
1028 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "New from File...");
1029 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "Rename...");
1030 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "Remove");
1031 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "Copy");
1032 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "New from Clipboard");
1034 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, 0);
1035 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, 0);
1036 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuCopy
, 0);
1037 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
,
1038 CPmenuNewFromClipboard
, 0);
1040 customRenderSpectrum(panel
);
1041 panel
->currentPalette
= 0;
1042 panel
->palx
= customPaletteWidth
/2;
1043 panel
->paly
= customPaletteHeight
/2;
1046 /* Widgets for the ColorList Panel */
1047 panel
->colorListFrm
= WMCreateFrame(panel
->win
);
1048 WMSetFrameRelief(panel
->colorListFrm
, WRFlat
);
1049 WMResizeWidget(panel
->colorListFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
1050 WMMoveWidget(panel
->colorListFrm
, 5, 80);
1052 panel
->colorListHistoryBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1053 WMAddPopUpButtonItem(panel
->colorListHistoryBtn
, "X11-Colors");
1054 WMSetPopUpButtonSelectedItem(panel
->colorListHistoryBtn
,
1055 WMGetPopUpButtonNumberOfItems(panel
->colorListHistoryBtn
)-1);
1056 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
1057 * colorListHistoryCallback, panel); */
1058 WMResizeWidget(panel
->colorListHistoryBtn
, PWIDTH
- 8, 20);
1059 WMMoveWidget(panel
->colorListHistoryBtn
, 0, 0);
1061 panel
->colorListContentLst
= WMCreateList(panel
->colorListFrm
);
1062 WMSetListAction(panel
->colorListContentLst
, colorListSelect
, panel
);
1063 WMSetListUserDrawProc(panel
->colorListContentLst
, colorListPaintItem
);
1064 WMResizeWidget(panel
->colorListContentLst
, PWIDTH
- 8, PHEIGHT
- 156);
1065 WMMoveWidget(panel
->colorListContentLst
, 0, 23);
1066 WMHangData(panel
->colorListContentLst
, panel
);
1068 panel
->colorListColorMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1069 WMSetPopUpButtonPullsDown(panel
->colorListColorMenuBtn
, 1);
1070 WMSetPopUpButtonText(panel
->colorListColorMenuBtn
, "Color");
1071 WMSetPopUpButtonAction(panel
->colorListColorMenuBtn
,
1072 colorListColorMenuCallback
, panel
);
1073 WMResizeWidget(panel
->colorListColorMenuBtn
, (PWIDTH
- 16)/2, 20);
1074 WMMoveWidget(panel
->colorListColorMenuBtn
, 0, PHEIGHT
- 130);
1076 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, "Add...");
1077 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, "Rename...");
1078 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, "Remove");
1080 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuAdd
, 0);
1081 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRename
, 0);
1082 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRemove
, 0);
1084 panel
->colorListListMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1085 WMSetPopUpButtonPullsDown(panel
->colorListListMenuBtn
, 1);
1086 WMSetPopUpButtonText(panel
->colorListListMenuBtn
, "List");
1087 WMSetPopUpButtonAction(panel
->colorListListMenuBtn
,
1088 colorListListMenuCallback
, panel
);
1089 WMResizeWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16)/2, 20);
1090 WMMoveWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16)/2 + 8,
1093 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, "New...");
1094 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, "Rename...");
1095 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, "Remove");
1097 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRename
, 0);
1098 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRemove
, 0);
1100 WMRealizeWidget(panel
->win
);
1101 WMMapSubwidgets(panel
->win
);
1103 WMMapSubwidgets(panel
->wheelFrm
);
1104 WMMapSubwidgets(panel
->slidersFrm
);
1105 WMMapSubwidgets(panel
->grayFrm
);
1106 WMMapSubwidgets(panel
->rgbFrm
);
1107 WMMapSubwidgets(panel
->cmykFrm
);
1108 WMMapSubwidgets(panel
->hsbFrm
);
1109 WMMapSubwidgets(panel
->customPaletteFrm
);
1110 WMMapSubwidgets(panel
->customPaletteContentFrm
);
1111 WMMapSubwidgets(panel
->colorListFrm
);
1113 /* Pixmap to indicate selection positions
1114 * wheelframe MUST be mapped.
1116 panel
->selectionImg
= XCreatePixmap(scrPtr
->display
,
1117 WMWidgetXID(panel
->win
), 4, 4, scrPtr
->depth
);
1118 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, bgc
, 0, 0, 4, 4);
1119 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, wgc
, 1, 1, 2, 2);
1121 readConfiguration(panel
);
1129 WMGetColorPanel(WMScreen
*scrPtr
)
1131 WMColorPanel
*panel
;
1133 if (scrPtr
->sharedColorPanel
)
1134 return scrPtr
->sharedColorPanel
;
1136 panel
= makeColorPanel(scrPtr
, "colorPanel");
1138 scrPtr
->sharedColorPanel
= panel
;
1145 WMFreeColorPanel(WMColorPanel
*panel
)
1147 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1149 if (panel
== scr
->sharedColorPanel
) {
1150 scr
->sharedColorPanel
= NULL
;
1156 WMRemoveNotificationObserver(panel
);
1157 WMUnmapWidget(panel
->win
);
1160 WMReleaseFont(panel
->font8
);
1161 WMReleaseFont(panel
->font12
);
1164 wheelDestroyMatrix(panel
->wheelMtrx
);
1165 if (panel
->wheelImg
)
1166 XFreePixmap(scr
->display
, panel
->wheelImg
);
1167 if (panel
->selectionImg
)
1168 XFreePixmap(scr
->display
, panel
->selectionImg
);
1169 if (panel
->selectionBackImg
)
1170 XFreePixmap(scr
->display
, panel
->selectionBackImg
);
1171 RDestroyImage(panel
->customPaletteImg
);
1174 if (panel
->lastBrowseDir
)
1175 wfree(panel
->lastBrowseDir
);
1176 if (panel
->configurationPath
)
1177 wfree(panel
->configurationPath
);
1179 WMDestroyWidget(panel
->win
);
1186 WMCloseColorPanel(WMColorPanel
*panel
)
1188 WMFreeColorPanel(panel
);
1193 WMShowColorPanel(WMColorPanel
*panel
)
1195 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1196 WMColor
*white
= WMWhiteColor(scr
);
1198 if (panel
->color
.set
== cpNone
)
1199 WMSetColorPanelColor(panel
, white
);
1200 WMReleaseColor(white
);
1202 if (panel
->mode
!= WMWheelModeColorPanel
)
1203 WMPerformButtonClick(panel
->wheelBtn
);
1205 WMMapWidget(panel
->win
);
1210 closeWindowCallback(WMWidget
*w
, void *data
)
1212 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
1214 WMCloseColorPanel(panel
);
1219 readConfiguration(W_ColorPanel
*panel
)
1221 /* XXX Doesn't take care of "invalid" files */
1225 struct stat stat_buf
;
1228 if (stat(panel
->configurationPath
, &stat_buf
)!=0) {
1229 if (mkdir(panel
->configurationPath
,
1230 S_IRWXU
|S_IRGRP
|S_IROTH
|S_IXGRP
|S_IXOTH
)!=0) {
1231 wsyserror("Color Panel: Could not create directory %s needed"
1232 " to store configurations", panel
->configurationPath
);
1233 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1234 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1235 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1236 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1238 "Could not create ColorPanel configuration directory",
1244 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1245 wwarning(NO_FILE_ERR
, "%s", panel
->configurationPath
);
1249 while ((dp
= readdir(dPtr
)) != NULL
) {
1250 unsigned int perm_mask
;
1251 char *path
= wstrappend(panel
->configurationPath
,
1254 if (dp
->d_name
[0] != '.') {
1255 item
= WMGetPopUpButtonNumberOfItems(
1256 panel
->customPaletteHistoryBtn
);
1257 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1259 perm_mask
= (access(path
, R_OK
) == 0);
1260 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
,
1265 (void)closedir(dPtr
);
1270 readXColors(W_ColorPanel
*panel
)
1272 struct stat stat_buf
;
1274 char line
[MAX_LENGTH
];
1275 int red
, green
, blue
;
1280 if (stat(RGBTXT
, &stat_buf
) != 0) {
1281 wsyserror(NO_FILE_ERR
, " %s", RGBTXT
);
1285 if ((rgbtxt
= fopen(RGBTXT
, "r"))) {
1286 while (fgets(line
, MAX_LENGTH
, rgbtxt
)) {
1287 if (sscanf(line
, "%d%d%d %[^\n]", &red
, &green
, &blue
, name
)) {
1288 color
= wmalloc(sizeof(RColor
));
1289 color
->red
= (unsigned char)red
;
1290 color
->green
= (unsigned char)green
;
1291 color
->blue
= (unsigned char)blue
;
1292 item
= WMAddListItem(panel
->colorListContentLst
, name
);
1293 item
->clientData
= (void *)color
;
1299 wsyserror(NO_FILE_ERR
, "%s", RGBTXT
);
1306 WMSetColorPanelPickerMode(WMColorPanel
*panel
, WMColorPanelMode mode
)
1308 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1310 if (mode
!= WMWheelModeColorPanel
) {
1311 WMUnmapWidget(panel
->wheelFrm
);
1312 if (panel
->selectionBackImg
) {
1313 XFreePixmap(WMWidgetScreen(panel
->win
)->display
,
1314 panel
->selectionBackImg
);
1315 panel
->selectionBackImg
= None
;
1318 if (mode
!= WMGrayModeColorPanel
)
1319 WMUnmapWidget(panel
->grayFrm
);
1320 if (mode
!= WMRGBModeColorPanel
)
1321 WMUnmapWidget(panel
->rgbFrm
);
1322 if (mode
!= WMCMYKModeColorPanel
)
1323 WMUnmapWidget(panel
->cmykFrm
);
1324 if (mode
!= WMHSBModeColorPanel
)
1325 WMUnmapWidget(panel
->hsbFrm
);
1326 if (mode
!= WMCustomPaletteModeColorPanel
) {
1327 WMUnmapWidget(panel
->customPaletteFrm
);
1328 if (panel
->selectionBackImg
) {
1329 XFreePixmap(WMWidgetScreen(panel
->win
)->display
,
1330 panel
->selectionBackImg
);
1331 panel
->selectionBackImg
= None
;
1334 if (mode
!= WMColorListModeColorPanel
)
1335 WMUnmapWidget(panel
->colorListFrm
);
1336 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1337 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1338 WMUnmapWidget(panel
->slidersFrm
);
1340 panel
->slidersmode
= mode
;
1342 if (mode
== WMWheelModeColorPanel
) {
1343 WMMapWidget(panel
->wheelFrm
);
1344 WMSetButtonSelected(panel
->wheelBtn
, True
);
1345 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1349 } else if (mode
== WMGrayModeColorPanel
) {
1350 WMMapWidget(panel
->slidersFrm
);
1351 WMSetButtonSelected(panel
->slidersBtn
, True
);
1352 WMMapWidget(panel
->grayFrm
);
1353 WMSetButtonSelected(panel
->grayBtn
, True
);
1354 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1355 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1357 } else if (mode
== WMRGBModeColorPanel
) {
1358 WMMapWidget(panel
->slidersFrm
);
1359 WMSetButtonSelected(panel
->slidersBtn
, True
);
1360 WMMapWidget(panel
->rgbFrm
);
1361 WMSetButtonSelected(panel
->rgbBtn
, True
);
1362 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1363 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1365 } else if (mode
== WMCMYKModeColorPanel
) {
1366 WMMapWidget(panel
->slidersFrm
);
1367 WMSetButtonSelected(panel
->slidersBtn
, True
);
1368 WMMapWidget(panel
->cmykFrm
);
1369 WMSetButtonSelected(panel
->cmykBtn
, True
);
1370 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1371 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1373 } else if (mode
== WMHSBModeColorPanel
) {
1374 WMMapWidget(panel
->slidersFrm
);
1375 WMSetButtonSelected(panel
->slidersBtn
, True
);
1376 WMMapWidget(panel
->hsbFrm
);
1377 WMSetButtonSelected(panel
->hsbBtn
, True
);
1378 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1379 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1381 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1382 WMMapWidget(panel
->customPaletteFrm
);
1383 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1384 customSetPalette(panel
);
1385 } else if (mode
== WMColorListModeColorPanel
) {
1386 WMMapWidget(panel
->colorListFrm
);
1387 WMSetButtonSelected(panel
->colorListBtn
, True
);
1395 WMGetColorPanelColor(WMColorPanel
*panel
)
1397 return WMGetColorWellColor(panel
->colorWell
);
1402 WMSetColorPanelColor(WMColorPanel
*panel
, WMColor
*color
)
1404 WMSetColorWellColor(panel
->colorWell
, color
);
1406 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1407 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1408 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1409 panel
->color
.set
= cpRGB
;
1411 if (panel
->mode
== panel
->lastChanged
)
1412 panel
->lastChanged
= 0;
1414 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1419 updateSwatch(WMColorPanel
*panel
, CPColor color
)
1421 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1424 if (color
.set
!= cpRGB
)
1425 convertCPColor(&color
);
1427 panel
->color
= color
;
1429 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8,
1430 color
.rgb
.green
<< 8,
1431 color
.rgb
.blue
<< 8, True
);
1433 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1434 WMReleaseColor(wellcolor
);
1436 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1438 (*panel
->action
)(panel
, panel
->clientData
);
1440 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
,
1446 modeButtonCallback(WMWidget
*w
, void *data
)
1448 W_ColorPanel
*panel
= (W_ColorPanel
*)(data
);
1450 if (w
== panel
->wheelBtn
)
1451 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1452 else if (w
== panel
->slidersBtn
)
1453 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1454 else if (w
== panel
->customPaletteBtn
)
1455 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1456 else if (w
== panel
->colorListBtn
)
1457 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1458 else if (w
== panel
->grayBtn
)
1459 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1460 else if (w
== panel
->rgbBtn
)
1461 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1462 else if (w
== panel
->cmykBtn
)
1463 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1464 else if (w
== panel
->hsbBtn
)
1465 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1469 /****************** Magnifying Cursor Functions *******************/
1472 magnifyGetImage(WMScreen
*scr
, XImage
*image
, int x
, int y
, int w
, int h
)
1474 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1475 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1476 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1478 if (!(image
&& image
->data
)) {
1479 /* The image in panel->magnifyGlass->image does not exist yet.
1480 * Grab one from the screen (not beyond) and use it from now on.
1482 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1485 w
, h
, AllPlanes
, ZPixmap
)))
1491 /* Coordinate correction for back pixmap
1492 * if magnifying glass is at screen-borders
1495 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1496 * Hatched area is beyond screen border.
1498 * |<-Cursor_x_hot->|
1499 * ________________|_____
1500 * |/ / / / / / /| | |
1501 * | / / / / / / |(x,y) |
1502 * |/_/_/_/_/_/_/|________|
1503 * |<----x0----->|<--w0-->|
1507 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1509 * Hatched area is beyond screen border
1511 * |<-Cursor_x_hot->|
1512 * ________________|_______________
1513 * | | | / / / / / /|
1514 * | (x,y)|/ / / / / / |
1515 * |___________________|_/_/_/_/_/_/|
1516 * |<-------w0-------->| |
1517 * |<---------------w--|----------->|
1522 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1523 x0
= Cursor_x_hot
- x
;
1527 if (displayWidth
-1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1528 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1531 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1532 y0
= Cursor_y_hot
- y
;
1536 if (displayHeight
-1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1537 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1539 /* end of coordinate correction */
1542 /* Grab an image from the screen, clipped if necessary,
1543 * and put it in the existing panel->magnifyGlass->image
1544 * with the corresponding clipping offset.
1546 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1547 x
- Cursor_x_hot
+ x0
,
1548 y
- Cursor_y_hot
+ y0
,
1549 w0
, h0
, AllPlanes
, ZPixmap
,
1558 magnifyGetImageStored(WMColorPanel
*panel
, int x1
, int y1
, int x2
, int y2
)
1560 /* (x1, y1) = topleft corner of existing rectangle
1561 * (x2, y2) = topleft corner of new position
1564 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1565 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1567 const int dx
= abs(x2
- x1
),
1570 const int x_min
= Cursor_x_hot
,
1571 y_min
= Cursor_y_hot
,
1572 x_max
= DisplayWidth(scr
->display
, scr
->screen
) -1 -
1573 (Cursor_mask_width
- Cursor_x_hot
),
1574 y_max
= DisplayHeight(scr
->display
, scr
->screen
) -1 -
1575 (Cursor_mask_height
- Cursor_y_hot
);
1577 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1578 return; /* No movement */
1590 width
= Cursor_mask_width
- dx
;
1591 height
= Cursor_mask_height
- dy
;
1593 /* If the traversed distance is larger than the size of the magnifying
1594 * glass contents, there is no need to do dirty rectangles. A whole new
1595 * rectangle can be grabbed (unless that rectangle falls partially
1597 * Destroying the image and setting it to NULL will achieve that later on.
1599 * Of course, grabbing an XImage beyond the borders of the screen will
1600 * cause trouble, this is considdered a special case. Part of the screen
1601 * is grabbed, but there is no need for dirty rectangles.
1603 if ((width
<= 0) || (height
<= 0)) {
1604 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1605 if (panel
->magnifyGlass
->image
)
1606 XDestroyImage(panel
->magnifyGlass
->image
);
1607 panel
->magnifyGlass
->image
= NULL
;
1610 if (panel
->magnifyGlass
->image
) {
1611 /* Get dirty rectangle from panel->magnifyGlass->image */
1612 panel
->magnifyGlass
->dirtyRect
=
1613 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1614 if (!panel
->magnifyGlass
->dirtyRect
) {
1616 return; /* X returned a NULL from XSubImage */
1621 /* Get image from screen */
1622 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
,
1623 Cursor_mask_width
, Cursor_mask_height
);
1624 if (image
) { /* Only reassign if a *new* image was grabbed */
1625 panel
->magnifyGlass
->image
= image
;
1629 /* Copy previously stored rectangle on covered part of image */
1630 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1633 /* "width" and "height" are used as coordinates here,
1634 * and run from [0...width-1] and [0...height-1] respectively.
1638 old_height
= height
;
1640 for (; width
>= 0; width
--)
1641 for (height
= old_height
; height
>= 0; height
--)
1642 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1643 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1644 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1645 panel
->magnifyGlass
->dirtyRect
= NULL
;
1653 magnifyCreatePixmap(WMColorPanel
*panel
)
1655 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1660 unsigned long color
;
1662 if (!panel
->magnifyGlass
->image
)
1665 if (!panel
->magnifyGlass
->magPix
)
1669 * Copy an area of only 5x5 pixels from the center of the image.
1671 for (u
= 0; u
< 5; u
++) {
1672 for (v
= 0; v
< 5; v
++) {
1673 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1675 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1677 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1678 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1680 /* The center square must eventually be centered around the
1681 * hotspot. The image needs shifting to achieve this. The amount of
1682 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1685 * ^------- center of center square == Cursor_x_hot
1687 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1689 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1690 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1695 return panel
->magnifyGlass
->magPix
;
1697 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
,
1698 Cursor_mask_height
, scr
->depth
);
1702 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1703 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1705 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1706 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1707 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1708 /* (2,2) puts center pixel on center of glass */
1717 magnifyCreateView(W_ColorPanel
*panel
)
1719 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1722 magView
= W_CreateTopView(scr
);
1726 magView
->self
= panel
->win
;
1727 magView
->flags
.topLevel
= 1;
1728 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1729 magView
->attribs
.override_redirect
= True
;
1730 magView
->attribs
.save_under
= True
;
1732 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1734 W_RealizeView(magView
);
1741 magnifyGrabPointer(W_ColorPanel
*panel
)
1743 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1744 Pixmap magPixmap
, magPixmap2
;
1746 XColor fgColor
= {0, 0,0,0, DoRed
|DoGreen
|DoBlue
};
1747 XColor bgColor
= {0, 0xbf00, 0xa000, 0x5000, DoRed
|DoGreen
|DoBlue
};
1749 /* Cursor creation stuff */
1750 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1751 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1752 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1753 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1755 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1756 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1758 XFreePixmap(scr
->display
, magPixmap
);
1759 XFreePixmap(scr
->display
, magPixmap2
);
1761 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1763 /* Set up Pointer */
1764 XGrabPointer (scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1765 PointerMotionMask
| ButtonPressMask
,
1766 GrabModeAsync
, GrabModeAsync
,
1767 scr
->rootWin
, magCursor
, CurrentTime
);
1774 magnifyInitialize(W_ColorPanel
*panel
)
1776 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1779 Pixmap pixmap
, clip_mask
;
1781 Window root_return
, child_return
;
1783 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1784 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1786 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1787 5*5 -1, 5*5 -1, scr
->depth
);
1789 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
,
1790 &x
, &y
, &u
, &v
, &mask
);
1792 panel
->magnifyGlass
->image
= NULL
;
1794 /* Clipmask to make magnified view-contents circular */
1796 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1797 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1799 /* Clip circle in glass cursor */
1800 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1801 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1804 XFreePixmap(scr
->display
, clip_mask
);
1806 /* Draw initial magnifying glass contents */
1807 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1809 pixmap
= magnifyCreatePixmap(panel
);
1810 XSetWindowBackgroundPixmap(scr
->display
,
1811 WMViewXID(panel
->magnifyGlass
->view
),
1813 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1814 XFlush(scr
->display
);
1817 XFreePixmap(scr
->display
, pixmap
);
1828 magnifyPutCursor(WMWidget
*w
, void *data
)
1830 W_ColorPanel
*panel
= (W_ColorPanel
*)(data
);
1831 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1835 WMPoint initialPosition
;
1837 /* Destroy wheelBackImg, so it'll update properly */
1838 if (panel
->selectionBackImg
) {
1839 XFreePixmap(WMWidgetScreen(panel
->win
)->display
,
1840 panel
->selectionBackImg
);
1841 panel
->selectionBackImg
= None
;
1844 /* Create magnifying glass */
1845 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1846 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1847 if (!panel
->magnifyGlass
->view
)
1850 initialPosition
= magnifyInitialize(panel
);
1851 panel
->magnifyGlass
->x
= initialPosition
.x
;
1852 panel
->magnifyGlass
->y
= initialPosition
.y
;
1854 W_MoveView(panel
->magnifyGlass
->view
,
1855 panel
->magnifyGlass
->x
- Cursor_x_hot
,
1856 panel
->magnifyGlass
->y
- Cursor_y_hot
);
1857 W_MapView(panel
->magnifyGlass
->view
);
1859 magCursor
= magnifyGrabPointer(panel
);
1861 while (panel
->magnifyGlass
->image
)
1863 WMNextEvent(scr
->display
, &event
);
1865 /* Pack motion events */
1866 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1872 XDestroyImage(panel
->magnifyGlass
->image
);
1873 panel
->magnifyGlass
->image
= NULL
;
1875 if (event
.xbutton
.button
== Button1
) {
1876 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1877 panel
->color
.set
= cpRGB
;
1878 updateSwatch(panel
, panel
->color
);
1880 switch (panel
->mode
) {
1881 case WMWheelModeColorPanel
:
1886 case WMGrayModeColorPanel
:
1889 case WMRGBModeColorPanel
:
1892 case WMCMYKModeColorPanel
:
1895 case WMHSBModeColorPanel
:
1901 panel
->lastChanged
= panel
->mode
;
1903 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1907 while (XPending(event
.xmotion
.display
)) {
1909 XPeekEvent(event
.xmotion
.display
, &ev
);
1910 if (ev
.type
== MotionNotify
)
1911 XNextEvent(event
.xmotion
.display
, &event
);
1916 /* Get a "dirty rectangle" */
1917 magnifyGetImageStored( panel
,
1918 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1919 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1921 /* Update coordinates */
1922 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1923 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1926 W_MoveView(panel
->magnifyGlass
->view
,
1927 panel
->magnifyGlass
->x
- Cursor_x_hot
,
1928 panel
->magnifyGlass
->y
- Cursor_y_hot
);
1930 /* Put new image (with magn.) in view */
1931 pixmap
= magnifyCreatePixmap(panel
);
1932 if (pixmap
!= None
) {
1933 /* Change the window background */
1934 XSetWindowBackgroundPixmap(scr
->display
,
1935 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1936 /* Force an Expose (handled by X) */
1937 XClearWindow(scr
->display
,
1938 WMViewXID(panel
->magnifyGlass
->view
));
1939 /* Synchronize the event queue, so the Expose is handled NOW */
1940 XFlush(scr
->display
);
1942 XFreePixmap(scr
->display
, pixmap
);
1947 /* Try XQueryPointer for this !!! It returns windows that the pointer
1948 * is over. Note: We found this solving the invisible donkey cap bug
1950 #if 0 /* As it is impossible to make this work in all cases,
1951 * we consider it confusing. Therefore we disabled it.
1953 case FocusOut
: /* fall through */
1956 * Color Panel window (panel->win) lost or received focus.
1957 * We need to update the pixmap in the magnifying glass.
1959 * BUG Doesn't work with focus switches between two windows
1960 * if none of them is the color panel.
1962 XUngrabPointer(scr
->display
, CurrentTime
);
1963 W_UnmapView(panel
->magnifyGlass
->view
);
1965 magnifyInitialize(panel
);
1967 W_MapView(panel
->magnifyGlass
->view
);
1968 XGrabPointer (scr
->display
, panel
->magnifyGlass
->view
->window
,
1969 True
, PointerMotionMask
| ButtonPressMask
,
1970 GrabModeAsync
, GrabModeAsync
,
1971 scr
->rootWin
, magCursor
, CurrentTime
);
1975 WMHandleEvent(&event
);
1980 XUngrabPointer(scr
->display
, CurrentTime
);
1981 XFreeCursor(scr
->display
, magCursor
);
1983 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1984 panel
->magnifyGlass
->magPix
= None
;
1986 W_UnmapView(panel
->magnifyGlass
->view
);
1987 W_DestroyView(panel
->magnifyGlass
->view
);
1988 panel
->magnifyGlass
->view
= NULL
;
1990 wfree(panel
->magnifyGlass
);
1995 /****************** ColorWheel Functions ************************/
1998 wheelCreateMatrix(unsigned int width
, unsigned int height
)
2000 wheelMatrix
*matrix
= NULL
;
2003 assert((width
> 0) && (height
> 0));
2005 matrix
= wmalloc(sizeof(wheelMatrix
));
2006 memset(matrix
, 0, sizeof(wheelMatrix
));
2007 matrix
->width
= width
;
2008 matrix
->height
= height
;
2010 for (i
= 0; i
< 3; i
++) {
2011 matrix
->data
[i
] = wmalloc(width
*height
*sizeof(unsigned char));
2019 wheelDestroyMatrix(wheelMatrix
*matrix
)
2026 for (i
= 0; i
< 3; i
++) {
2027 if (matrix
->data
[i
])
2028 wfree(matrix
->data
[i
]);
2035 wheelInitMatrix(W_ColorPanel
*panel
)
2039 unsigned char *rp
, *gp
, *bp
;
2045 const int cw_halfsize
= (colorWheelSize
+ 4)/2,
2046 cw_sqsize
= (colorWheelSize
+4) * (colorWheelSize
+4),
2047 uchar_shift
= getShift(sizeof(unsigned char));
2049 if (!panel
->wheelMtrx
)
2052 cpColor
.hsv
.value
= 255;
2053 cpColor
.set
= cpHSV
;
2056 ofs
[1] = -(colorWheelSize
+ 4);
2058 /* offsets are counterclockwise (in triangles).
2061 * _______________________________________
2062 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
2063 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
2064 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
2065 * o | | | | | | | | | | | | | | | | | | | | | [3]
2069 * |\ /| <-- triangles
2075 for (y
= 0; y
< cw_halfsize
; y
++) {
2076 for (x
= y
; x
< (colorWheelSize
+4-y
); x
++) {
2077 /* (xcor, ycor) is (x,y) relative to center of matrix */
2078 xcor
= 2 * x
- 4 - colorWheelSize
;
2079 ycor
= 2 * y
- 4 - colorWheelSize
;
2081 /* RColor.saturation is unsigned char and will wrap after 255 */
2083 sqrtf( (float)(xcor
*xcor
) + (float)(ycor
*ycor
)) /
2084 (float)colorWheelSize
);
2086 cpColor
.hsv
.saturation
= (unsigned char)sat
;
2088 ofs
[0]++; /* top quarter of matrix*/
2089 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
2090 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
2091 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
2095 dhue
[0] = rint(atan((float)ycor
/ (float)xcor
) *
2096 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
2100 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
2101 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
2102 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
2103 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
2105 for (i
= 0; i
< 4; i
++) {
2106 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
2107 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
2108 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
2110 cpColor
.hsv
.hue
= dhue
[i
];
2111 convertCPColor(&cpColor
);
2113 *rp
= (unsigned char)(cpColor
.rgb
.red
);
2114 *gp
= (unsigned char)(cpColor
.rgb
.green
);
2115 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
2119 for (i
= 0; i
< 4; i
++) {
2120 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
2121 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
2122 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
2124 *rp
= (unsigned char)0;
2125 *gp
= (unsigned char)0;
2126 *bp
= (unsigned char)0;
2132 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2*y
);
2138 wheelCalculateValues(W_ColorPanel
*panel
, int maxvalue
)
2143 for (i
= 0; i
< 256; i
++) {
2144 /* We divide by 128 in advance, and check whether that number divides
2145 * by 2 properly. If not, we add one to round the number correctly
2147 v
= (i
*maxvalue
) >> 7;
2148 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) +(v
& 0x01));
2154 wheelRender(W_ColorPanel
*panel
)
2156 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2159 unsigned char *rp
, *gp
, *bp
;
2161 unsigned long ofs
= 0;
2162 unsigned char shift
= getShift(sizeof(unsigned char));
2164 image
= RCreateImage(colorWheelSize
+4, colorWheelSize
+4, False
);
2166 wwarning(NO_MEMORY_ERR
);
2170 /* TODO Make this transparent istead of gray */
2171 gray
.red
= gray
.green
= gray
.blue
= 0xaa;
2173 for (y
= 0; y
< colorWheelSize
+4; y
++) {
2174 for (x
= 0; x
< colorWheelSize
+4; x
++) {
2175 rp
= image
->data
[0] + (ofs
<< shift
);
2176 gp
= image
->data
[1] + (ofs
<< shift
);
2177 bp
= image
->data
[2] + (ofs
<< shift
);
2179 if (wheelInsideColorWheel(panel
, ofs
)) {
2180 *rp
= (unsigned int)(panel
->wheelMtrx
->values
[
2181 panel
->wheelMtrx
->data
[0][ofs
] ]);
2182 *gp
= (unsigned int)(panel
->wheelMtrx
->values
[
2183 panel
->wheelMtrx
->data
[1][ofs
] ]);
2184 *bp
= (unsigned int)(panel
->wheelMtrx
->values
[
2185 panel
->wheelMtrx
->data
[2][ofs
] ]);
2188 *rp
= (unsigned char)(gray
.red
);
2189 *gp
= (unsigned char)(gray
.green
);
2190 *bp
= (unsigned char)(gray
.blue
);
2196 if (panel
->wheelImg
)
2197 XFreePixmap(scr
->display
, panel
->wheelImg
);
2199 panel
->wheelImg
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
2200 colorWheelSize
+4, colorWheelSize
+4, scr
->depth
);
2201 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2203 /* Check if backimage exists. If it doesn't, allocate and fill it */
2204 if (!panel
->selectionBackImg
) {
2205 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2206 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2207 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2208 scr
->copyGC
, panel
->colx
-2, panel
->coly
-2, 4, 4, 0, 0);
2209 /* -2 is hot spot correction */
2212 RDestroyImage(image
);
2217 wheelInsideColorWheel(W_ColorPanel
*panel
, unsigned long ofs
)
2219 return ((panel
->wheelMtrx
->data
[0][ofs
] != 0) &&
2220 (panel
->wheelMtrx
->data
[1][ofs
] != 0) &&
2221 (panel
->wheelMtrx
->data
[2][ofs
] != 0));
2226 wheelPaint (W_ColorPanel
*panel
)
2228 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2230 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->wheelView
->window
,
2231 scr
->copyGC
, 0, 0, colorWheelSize
+4, colorWheelSize
+4, 0, 0);
2233 /* Draw selection image */
2234 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2235 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
-2, panel
->coly
-2);
2240 wheelHandleEvents(XEvent
*event
, void *data
)
2242 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2244 switch (event
->type
) {
2246 if (event
->xexpose
.count
!= 0) /* TODO Improve */
2255 wheelHandleActionEvents(XEvent
*event
, void *data
)
2257 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2259 switch (event
->type
) {
2261 if (getPickerPart(panel
, event
->xbutton
.x
, event
->xbutton
.y
) ==
2264 panel
->lastChanged
= WMWheelModeColorPanel
;
2265 panel
->flags
.dragging
= 1;
2267 wheelPositionSelection(panel
, event
->xbutton
.x
, event
->xbutton
.y
);
2272 panel
->flags
.dragging
= 0;
2273 if (!panel
->flags
.continuous
) {
2275 (*panel
->action
)(panel
, panel
->clientData
);
2280 if (panel
->flags
.dragging
) {
2281 if (getPickerPart(panel
, event
->xmotion
.x
, event
->xmotion
.y
) ==
2283 wheelPositionSelection(panel
, event
->xmotion
.x
,
2287 wheelPositionSelectionOutBounds(panel
, event
->xmotion
.x
,
2296 getPickerPart(W_ColorPanel
*panel
, int x
, int y
)
2304 if (panel
->mode
== WMWheelModeColorPanel
) {
2305 if ((lx
>= 2) && (lx
<= 2+colorWheelSize
) && (ly
>= 2) &&
2306 (ly
<= 2+colorWheelSize
)) {
2308 ofs
= ly
*panel
->wheelMtrx
->width
+lx
;
2310 if (wheelInsideColorWheel(panel
, ofs
))
2311 return COLORWHEEL_PART
;
2315 if (panel
->mode
== WMCustomPaletteModeColorPanel
) {
2316 if ((lx
>= 2) && (lx
< customPaletteWidth
-2) && (ly
>= 2) &&
2317 (ly
< customPaletteHeight
-2)) {
2318 return CUSTOMPALETTE_PART
;
2327 wheelBrightnessSliderCallback(WMWidget
*w
, void *data
)
2331 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2333 value
= 255-WMGetSliderValue(panel
->wheelBrightnessS
);
2335 wheelCalculateValues(panel
, value
);
2337 if (panel
->color
.set
== cpRGB
) {
2338 convertCPColor(&panel
->color
);
2339 panel
->color
.set
= cpHSV
;
2342 panel
->color
.hsv
.value
= value
;
2346 wheelUpdateSelection(panel
);
2351 wheelUpdateSelection(W_ColorPanel
*panel
)
2353 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2355 updateSwatch(panel
, panel
->color
);
2356 panel
->lastChanged
= WMWheelModeColorPanel
;
2358 /* Redraw color selector (and make a backup of the part it will cover) */
2359 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2360 scr
->copyGC
, panel
->colx
-2, panel
->coly
-2, 4, 4, 0, 0);
2361 /* "-2" is correction for hotspot location */
2362 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2363 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
-2, panel
->coly
-2);
2369 wheelUndrawSelection(W_ColorPanel
*panel
)
2371 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2373 XCopyArea(scr
->display
, panel
->selectionBackImg
, panel
->wheelView
->window
,
2374 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
-2, panel
->coly
-2);
2379 wheelPositionSelection(W_ColorPanel
*panel
, int x
, int y
)
2381 unsigned long ofs
= (y
* panel
->wheelMtrx
->width
)+ x
;
2383 panel
->color
.rgb
.red
= panel
->wheelMtrx
->values
[
2384 panel
->wheelMtrx
->data
[0][ofs
] ];
2386 panel
->color
.rgb
.green
= panel
->wheelMtrx
->values
[
2387 panel
->wheelMtrx
->data
[1][ofs
] ];
2389 panel
->color
.rgb
.blue
= panel
->wheelMtrx
->values
[
2390 panel
->wheelMtrx
->data
[2][ofs
] ];
2391 panel
->color
.set
= cpRGB
;
2393 wheelUndrawSelection(panel
);
2398 wheelUpdateSelection(panel
);
2399 wheelUpdateBrightnessGradientFromLocation(panel
);
2403 wheelPositionSelectionOutBounds(W_ColorPanel
*panel
, int x
, int y
)
2409 xcor
= x
* 2 - colorWheelSize
- 4;
2410 ycor
= y
* 2 - colorWheelSize
- 4;
2412 panel
->color
.hsv
.saturation
= 255;
2413 panel
->color
.hsv
.value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2416 hue
= rint(atan(- (float)ycor
/ (float)xcor
) * (180.0/M_PI
));
2427 if ((xcor
> 0) && (ycor
> 0))
2430 panel
->color
.hsv
.hue
= hue
;
2431 panel
->color
.set
= cpHSV
;
2432 convertCPColor(&panel
->color
);
2434 wheelUndrawSelection(panel
);
2436 panel
->colx
= 2 + rint((colorWheelSize
* (1.0 +
2437 cos( panel
->color
.hsv
.hue
* (M_PI
/180.0) ))) / 2.0);
2438 /* "+2" because of "colorWheelSize + 4" */
2439 panel
->coly
= 2 + rint((colorWheelSize
* (1.0 +
2440 sin(- panel
->color
.hsv
.hue
* (M_PI
/180.0) ))) / 2.0);
2442 wheelUpdateSelection(panel
);
2443 cpColor
= panel
->color
;
2444 wheelUpdateBrightnessGradient(panel
, cpColor
);
2448 wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
*panel
)
2453 ofs
= panel
->coly
* panel
->wheelMtrx
->width
+ panel
->colx
;
2455 from
.rgb
.red
= panel
->wheelMtrx
->data
[0][ofs
];
2456 from
.rgb
.green
= panel
->wheelMtrx
->data
[1][ofs
];
2457 from
.rgb
.blue
= panel
->wheelMtrx
->data
[2][ofs
];
2460 wheelUpdateBrightnessGradient(panel
, from
);
2464 wheelUpdateBrightnessGradient(W_ColorPanel
*panel
, CPColor topColor
)
2468 WMPixmap
*sliderPxmp
;
2470 to
.red
= to
.green
= to
.blue
= 0;
2472 if (topColor
.set
== cpHSV
) {
2473 topColor
.hsv
.value
= 255;
2474 convertCPColor(&topColor
);
2477 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2478 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
),
2480 RDestroyImage(sliderImg
);
2481 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2482 WMReleasePixmap(sliderPxmp
);
2485 /****************** Grayscale Panel Functions ***************/
2488 grayBrightnessSliderCallback(WMWidget
*w
, void *data
)
2493 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2495 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2497 sprintf(tmp
, "%d", value
);
2499 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2500 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55*value
);
2501 cpColor
.set
= cpRGB
;
2503 updateSwatch(panel
, cpColor
);
2504 panel
->lastChanged
= WMGrayModeColorPanel
;
2508 grayPresetButtonCallback(WMWidget
*w
, void *data
)
2514 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2517 if (w
== panel
->grayPresetBtn
[i
])
2522 value
= rint((100.0*i
)/6.0);
2523 sprintf(tmp
, "%d", value
);
2525 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2526 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
=
2527 rint((255.0*i
)/6.0);
2528 cpColor
.set
= cpRGB
;
2530 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0*i
)/6.0));
2532 updateSwatch(panel
, cpColor
);
2533 panel
->lastChanged
= WMGrayModeColorPanel
;
2537 grayBrightnessTextFieldCallback(void *observerData
,
2538 WMNotification
*notification
)
2543 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2545 value
= atoi(WMGetTextFieldText(panel
->grayBrightnessT
));
2551 sprintf(tmp
, "%d", value
);
2552 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2553 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2555 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
=
2556 rint((255.0*value
)/100.0);
2557 cpColor
.set
= cpRGB
;
2559 updateSwatch(panel
, cpColor
);
2560 panel
->lastChanged
= WMGrayModeColorPanel
;
2563 /******************* RGB Panel Functions *****************/
2566 rgbSliderCallback(WMWidget
*w
, void *data
)
2571 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2573 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2574 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2575 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2577 sprintf(tmp
, "%d", value
[0]);
2578 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2579 sprintf(tmp
, "%d", value
[1]);
2580 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2581 sprintf(tmp
, "%d", value
[2]);
2582 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2584 cpColor
.rgb
.red
= value
[0];
2585 cpColor
.rgb
.green
= value
[1];
2586 cpColor
.rgb
.blue
= value
[2];
2587 cpColor
.set
= cpRGB
;
2589 updateSwatch(panel
, cpColor
);
2590 panel
->lastChanged
= WMRGBModeColorPanel
;
2594 rgbTextFieldCallback(void *observerData
, WMNotification
*notification
)
2600 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2602 value
[0] = atoi(WMGetTextFieldText(panel
->rgbRedT
));
2603 value
[1] = atoi(WMGetTextFieldText(panel
->rgbGreenT
));
2604 value
[2] = atoi(WMGetTextFieldText(panel
->rgbBlueT
));
2606 for (n
=0; n
< 3; n
++) {
2613 sprintf(tmp
, "%d", value
[0]);
2614 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2615 sprintf(tmp
, "%d", value
[1]);
2616 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2617 sprintf(tmp
, "%d", value
[2]);
2618 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2620 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2621 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2622 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2624 cpColor
.rgb
.red
= value
[0];
2625 cpColor
.rgb
.green
= value
[1];
2626 cpColor
.rgb
.blue
= value
[2];
2627 cpColor
.set
= cpRGB
;
2629 updateSwatch(panel
, cpColor
);
2630 panel
->lastChanged
= WMRGBModeColorPanel
;
2634 /******************* CMYK Panel Functions *****************/
2637 cmykSliderCallback(WMWidget
*w
, void *data
)
2642 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2645 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2646 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2647 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2648 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2650 sprintf(tmp
, "%d", value
[0]);
2651 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2652 sprintf(tmp
, "%d", value
[1]);
2653 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2654 sprintf(tmp
, "%d", value
[2]);
2655 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2656 sprintf(tmp
, "%d", value
[3]);
2657 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2659 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2660 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2661 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2662 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2663 cpColor
.set
= cpRGB
;
2665 updateSwatch(panel
, cpColor
);
2666 panel
->lastChanged
= WMCMYKModeColorPanel
;
2670 cmykTextFieldCallback(void *observerData
, WMNotification
*notification
)
2677 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2679 value
[0] = atoi(WMGetTextFieldText(panel
->cmykCyanT
));
2680 value
[1] = atoi(WMGetTextFieldText(panel
->cmykMagentaT
));
2681 value
[2] = atoi(WMGetTextFieldText(panel
->cmykYellowT
));
2682 value
[3] = atoi(WMGetTextFieldText(panel
->cmykBlackT
));
2684 for (n
=0; n
< 4; n
++) {
2691 sprintf(tmp
, "%d", value
[0]);
2692 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2694 sprintf(tmp
, "%d", value
[1]);
2695 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2697 sprintf(tmp
, "%d", value
[2]);
2698 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2700 sprintf(tmp
, "%d", value
[3]);
2701 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2703 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2704 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2705 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2706 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2708 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2709 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2710 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2711 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2712 cpColor
.set
= cpRGB
;
2714 updateSwatch(panel
, cpColor
);
2715 panel
->lastChanged
= WMCMYKModeColorPanel
;
2718 /********************** HSB Panel Functions ***********************/
2721 hsbSliderCallback(WMWidget
*w
, void *data
)
2726 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2728 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2729 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2730 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2732 sprintf(tmp
, "%d", value
[0]);
2733 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2734 sprintf(tmp
, "%d", value
[1]);
2735 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2736 sprintf(tmp
, "%d", value
[2]);
2737 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2739 cpColor
.hsv
.hue
= value
[0];
2740 cpColor
.hsv
.saturation
= value
[1]*2.55;
2741 cpColor
.hsv
.value
= value
[2]*2.55;
2742 cpColor
.set
= cpHSV
;
2744 convertCPColor(&cpColor
);
2746 panel
->lastChanged
= WMHSBModeColorPanel
;
2747 updateSwatch(panel
, cpColor
);
2749 if (w
!= panel
->hsbBrightnessS
)
2750 hsbUpdateBrightnessGradient(panel
);
2751 if (w
!= panel
->hsbSaturationS
)
2752 hsbUpdateSaturationGradient(panel
);
2753 if (w
!= panel
->hsbHueS
)
2754 hsbUpdateHueGradient(panel
);
2758 hsbTextFieldCallback(void *observerData
, WMNotification
*notification
)
2764 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2766 value
[0] = atoi(WMGetTextFieldText(panel
->hsbHueT
));
2767 value
[1] = atoi(WMGetTextFieldText(panel
->hsbSaturationT
));
2768 value
[2] = atoi(WMGetTextFieldText(panel
->hsbBrightnessT
));
2775 for (n
=1; n
< 3; n
++) {
2782 sprintf(tmp
, "%d", value
[0]);
2783 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2784 sprintf(tmp
, "%d", value
[1]);
2785 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2786 sprintf(tmp
, "%d", value
[2]);
2787 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2789 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2790 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2791 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2793 cpColor
.hsv
.hue
= value
[0];
2794 cpColor
.hsv
.saturation
= value
[1]*2.55;
2795 cpColor
.hsv
.value
= value
[2]*2.55;
2796 cpColor
.set
= cpHSV
;
2798 convertCPColor(&cpColor
);
2800 panel
->lastChanged
= WMHSBModeColorPanel
;
2801 updateSwatch(panel
, cpColor
);
2803 hsbUpdateBrightnessGradient(panel
);
2804 hsbUpdateSaturationGradient(panel
);
2805 hsbUpdateHueGradient(panel
);
2809 hsbUpdateBrightnessGradient(W_ColorPanel
*panel
)
2811 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2815 WMPixmap
*sliderPxmp
;
2817 from
.red
= from
.green
= from
.blue
= 0;
2818 to
.hsv
= panel
->color
.hsv
;
2822 convertCPColor(&to
);
2824 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2825 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2826 RDestroyImage(sliderImg
);
2829 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2830 panel
->font12
, 2, 0, 100, WALeft
, WMColorGC(scr
->white
),
2831 False
, "Brightness", strlen("Brightness"));
2833 wwarning(NO_MEMORY_ERR
);
2835 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2836 WMReleasePixmap(sliderPxmp
);
2840 hsbUpdateSaturationGradient(W_ColorPanel
*panel
)
2842 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2846 WMPixmap
*sliderPxmp
;
2848 from
.hsv
= panel
->color
.hsv
;
2849 from
.hsv
.saturation
= 0;
2851 convertCPColor(&from
);
2853 to
.hsv
= panel
->color
.hsv
;
2854 to
.hsv
.saturation
= 255;
2856 convertCPColor(&to
);
2858 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
),
2860 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2861 RDestroyImage(sliderImg
);
2864 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2865 panel
->font12
, 2, 0, 100, WALeft
,
2866 WMColorGC(from
.hsv
.value
< 128 ? scr
->white
: scr
->black
), False
,
2867 "Saturation", strlen("Saturation"));
2869 wwarning(NO_MEMORY_ERR
);
2871 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2872 WMReleasePixmap(sliderPxmp
);
2876 hsbUpdateHueGradient(W_ColorPanel
*panel
)
2878 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2879 RColor
**colors
= NULL
;
2882 WMPixmap
*sliderPxmp
;
2885 hsvcolor
= panel
->color
.hsv
;
2887 colors
= wmalloc(sizeof(RColor
*)*(8));
2888 for (i
=0; i
<7; i
++) {
2889 hsvcolor
.hue
= (360*i
)/6;
2890 colors
[i
] = wmalloc(sizeof(RColor
));
2891 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2895 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2896 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2897 RDestroyImage(sliderImg
);
2900 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2901 panel
->font12
, 2, 0, 100, WALeft
,
2902 WMColorGC(hsvcolor
.value
< 128 ? scr
->white
: scr
->black
), False
,
2903 "Hue", strlen("Hue"));
2905 wwarning(NO_MEMORY_ERR
);
2907 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2908 WMReleasePixmap(sliderPxmp
);
2916 /*************** Custom Palette Functions ****************/
2919 customRenderSpectrum(W_ColorPanel
*panel
)
2924 unsigned char *rp
, *gp
, *bp
;
2927 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, 0);
2929 for (y
=0; y
<360; y
++) {
2930 cpColor
.hsv
.hue
= y
;
2931 cpColor
.hsv
.saturation
= 0;
2932 cpColor
.hsv
.value
= 255;
2933 cpColor
.set
= cpHSV
;
2935 for (x
=0; x
<511; x
++) {
2936 ofs
= (y
* 511) + x
;
2938 convertCPColor(&cpColor
);
2940 rp
= spectrum
->data
[0] + ofs
;
2941 gp
= spectrum
->data
[1] + ofs
;
2942 bp
= spectrum
->data
[2] + ofs
;
2944 *rp
= (unsigned char)cpColor
.rgb
.red
;
2945 *gp
= (unsigned char)cpColor
.rgb
.green
;
2946 *bp
= (unsigned char)cpColor
.rgb
.blue
;
2949 cpColor
.hsv
.saturation
++;
2952 cpColor
.hsv
.value
--;
2955 if (panel
->customPaletteImg
) {
2956 RDestroyImage(panel
->customPaletteImg
);
2957 panel
->customPaletteImg
= NULL
;
2959 panel
->customPaletteImg
= spectrum
;
2965 customSetPalette(W_ColorPanel
*panel
)
2967 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2972 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
,
2973 customPaletteHeight
, scr
->depth
);
2975 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
,
2976 customPaletteHeight
);
2977 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2978 RDestroyImage(scaledImg
);
2980 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2981 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2983 /* Check backimage exists. If it doesn't, allocate and fill it */
2984 if (!panel
->selectionBackImg
) {
2985 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2986 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2989 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2990 panel
->palx
-2, panel
->paly
-2, 4, 4, 0, 0);
2991 XCopyArea(scr
->display
, panel
->selectionImg
,
2992 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0 , 0, 4, 4,
2993 panel
->palx
-2, panel
->paly
-2);
2994 XFreePixmap(scr
->display
, image
);
2996 panel
->palXRatio
= (float)(panel
->customPaletteImg
->width
) /
2997 (float)(customPaletteWidth
);
2998 panel
->palYRatio
= (float)(panel
->customPaletteImg
->height
) /
2999 (float)(customPaletteHeight
);
3001 item
= WMGetPopUpButtonSelectedItem (panel
->customPaletteHistoryBtn
);
3006 customPalettePositionSelection(W_ColorPanel
*panel
, int x
, int y
)
3008 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3012 /* undraw selection */
3013 XCopyArea(scr
->display
, panel
->selectionBackImg
,
3014 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
3015 panel
->palx
-2, panel
->paly
-2);
3020 ofs
= rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) *
3021 panel
->customPaletteImg
->width
;
3023 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[0][ofs
];
3024 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[1][ofs
];
3025 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[2][ofs
];
3026 panel
->color
.set
= cpRGB
;
3028 updateSwatch(panel
, panel
->color
);
3029 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
3031 /* Redraw color selector (and make a backup of the part it will cover) */
3032 XCopyArea(scr
->display
, panel
->customPaletteContentView
->window
,
3033 panel
->selectionBackImg
, scr
->copyGC
, panel
->palx
-2, panel
->paly
-2,
3034 4, 4, 0, 0); /* "-2" is correction for hotspot location */
3035 XCopyArea(scr
->display
, panel
->selectionImg
,
3036 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
3037 panel
->palx
-2, panel
->paly
-2); /* see above */
3042 customPalettePositionSelectionOutBounds(W_ColorPanel
*panel
, int x
, int y
)
3048 if (x
>= customPaletteWidth
)
3049 x
= customPaletteWidth
-2;
3050 if (y
>= customPaletteHeight
)
3051 y
= customPaletteHeight
-2;
3053 customPalettePositionSelection(panel
, x
, y
);
3058 customPaletteHandleEvents(XEvent
*event
, void *data
)
3060 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3062 switch (event
->type
) {
3064 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
3066 customSetPalette(panel
);
3072 customPaletteHandleActionEvents(XEvent
*event
, void *data
)
3074 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3077 switch (event
->type
) {
3079 x
= event
->xbutton
.x
;
3080 y
= event
->xbutton
.y
;
3082 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
3083 panel
->flags
.dragging
= 1;
3084 customPalettePositionSelection(panel
, x
, y
);
3089 panel
->flags
.dragging
= 0;
3090 if (!panel
->flags
.continuous
) {
3092 (*panel
->action
)(panel
, panel
->clientData
);
3097 x
= event
->xmotion
.x
;
3098 y
= event
->xmotion
.y
;
3100 if (panel
->flags
.dragging
) {
3101 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
3102 customPalettePositionSelection(panel
, x
, y
);
3105 customPalettePositionSelectionOutBounds(panel
, x
, y
);
3113 customPaletteMenuCallback(WMWidget
*w
, void *data
)
3115 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3116 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
3119 case CPmenuNewFromFile
:
3120 customPaletteMenuNewFromFile(panel
);
3123 customPaletteMenuRename(panel
);
3126 customPaletteMenuRemove(panel
);
3130 case CPmenuNewFromClipboard
:
3137 customPaletteMenuNewFromFile(W_ColorPanel
*panel
)
3139 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3140 WMOpenPanel
*browseP
;
3142 char *filename
= NULL
;
3146 RImage
*tmpImg
= NULL
;
3148 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
,"\0") == 0))
3149 spath
= wexpandpath(wgethomedir());
3151 spath
= wexpandpath(panel
->lastBrowseDir
);
3153 browseP
= WMGetOpenPanel(scr
);
3154 WMSetFilePanelCanChooseDirectories(browseP
, 0);
3155 WMSetFilePanelCanChooseFiles(browseP
, 1);
3157 /* Get a filename */
3158 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
3159 "Open Palette", RSupportedFileFormats()) ) {
3160 filepath
= WMGetFilePanelFileName(browseP
);
3162 /* Get seperation position between path and filename */
3163 i
= strrchr(filepath
, '/') - filepath
+ 1;
3164 if (i
> strlen(filepath
))
3165 i
= strlen(filepath
);
3167 /* Store last browsed path */
3168 if (panel
->lastBrowseDir
)
3169 wfree(panel
->lastBrowseDir
);
3170 panel
->lastBrowseDir
= wmalloc((i
+1)*sizeof(char));
3171 strncpy(panel
->lastBrowseDir
, filepath
, i
);
3172 panel
->lastBrowseDir
[i
] = '\0';
3174 /* Get filename from path */
3175 filename
= wstrdup(filepath
+ i
);
3177 /* Check for duplicate files, and rename it if there are any */
3178 tmp
= wstrappend(panel
->configurationPath
, filename
);
3179 while (access (tmp
, F_OK
) == 0) {
3184 newName
= generateNewFilename(filename
);
3188 tmp
= wstrappend(panel
->configurationPath
, filename
);
3192 /* Copy image to $(gnustepdir)/Library/Colors/ &
3193 * Add filename to history menu */
3194 if (fetchFile (panel
->configurationPath
, filepath
, filename
) == 0) {
3196 /* filepath is a "local" path now the file has been copied */
3198 filepath
= wstrappend(panel
->configurationPath
, filename
);
3200 /* load the image & add menu entries */
3201 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
3203 if (panel
->customPaletteImg
)
3204 RDestroyImage(panel
->customPaletteImg
);
3205 panel
->customPaletteImg
= tmpImg
;
3207 customSetPalette(panel
);
3208 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
3210 panel
->currentPalette
= WMGetPopUpButtonNumberOfItems(
3211 panel
->customPaletteHistoryBtn
)-1;
3213 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3214 panel
->currentPalette
);
3217 tmp
= wstrappend(panel
->configurationPath
, filename
);
3219 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
3220 WMRunAlertPanel(scr
, panel
->win
, "File Error",
3221 "Invalid file format !", "OK", NULL
, NULL
);
3223 wsyserror("can't remove file %s", tmp
);
3224 WMRunAlertPanel(scr
, panel
->win
, "File Error",
3225 "Couldn't remove file from Configuration Directory !",
3233 WMFreeFilePanel(browseP
);
3240 customPaletteMenuRename(W_ColorPanel
*panel
)
3242 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3243 char *toName
= NULL
;
3245 char *toPath
, *fromPath
;
3249 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3250 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3252 toName
= WMRunInputPanel(scr
, panel
->win
, "Rename", "Rename palette to:",
3253 fromName
, "OK", "Cancel");
3257 /* As some people do certain stupid things... */
3258 if (strcmp(toName
, fromName
) == 0) {
3263 /* For normal people */
3264 fromPath
= wstrappend(panel
->configurationPath
, fromName
);
3265 toPath
= wstrappend(panel
->configurationPath
, toName
);
3267 if (access (toPath
, F_OK
) == 0) {
3268 /* Careful, this palette exists already */
3269 if (WMRunAlertPanel(scr
, panel
->win
, "Warning",
3270 "Palette already exists !\n\nOverwrite ?", "No", "Yes",
3272 /* "No" = 0, "Yes" = 1 */
3273 int items
= WMGetPopUpButtonNumberOfItems(
3274 panel
->customPaletteHistoryBtn
);
3278 /* Remove from History list too */
3280 while ((index
< items
) && (strcmp(WMGetPopUpButtonItem(
3281 panel
->customPaletteHistoryBtn
, index
),
3285 if (index
< items
) {
3286 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
,
3301 if ( rename(fromPath
, toPath
) != 0)
3302 wsyserror("Couldn't rename palette %s to %s\n", fromName
, toName
);
3304 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3305 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
,
3308 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3318 customPaletteMenuRemove(W_ColorPanel
*panel
)
3320 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3326 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3328 tmp
= wstrappend( "This will permanently remove the palette ",
3329 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3330 text
= wstrappend( tmp
,
3331 ".\n\nAre you sure you want to remove this palette ?");
3334 choice
= WMRunAlertPanel(scr
, panel
->win
, "Remove", text
, "Yes", "No",
3336 /* returns 0 (= "Yes") or 1 (="No") */
3341 tmp
= wstrappend(panel
->configurationPath
,
3342 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3344 if ( remove(tmp
) == 0) {
3345 /* item-1 always exists */
3346 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3349 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
,
3351 customSetPalette(panel
);
3353 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3356 wsyserror("Couldn't remove palette %s\n", tmp
);
3364 customPaletteHistoryCallback(WMWidget
*w
, void *data
)
3366 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3367 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3371 unsigned char perm_mask
;
3373 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3374 if (item
== panel
->currentPalette
)
3378 customRenderSpectrum(panel
);
3380 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
,
3382 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
,
3385 /* Load file from configpath */
3386 filename
= wstrappend( panel
->configurationPath
,
3387 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
) );
3389 /* If the file corresponding to the item does not exist,
3390 * remove it from the history list and select the next one.
3392 perm_mask
= (access(filename
, F_OK
) == 0);
3394 /* File does not exist */
3396 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3398 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3399 customPaletteHistoryCallback(w
, data
);
3404 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3406 if (panel
->customPaletteImg
) {
3407 RDestroyImage(panel
->customPaletteImg
);
3408 panel
->customPaletteImg
= NULL
;
3410 panel
->customPaletteImg
= tmp
;
3413 /* If the image is not writable, don't allow removing/renaming */
3414 perm_mask
= (access(filename
, W_OK
) == 0);
3415 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
,
3417 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
,
3422 customSetPalette(panel
);
3424 panel
->currentPalette
= item
;
3427 /************************* ColorList Panel Functions **********************/
3430 colorListPaintItem(WMList
*lPtr
, int index
, Drawable d
, char *text
,
3431 int state
, WMRect
*rect
)
3433 int width
, height
, x
, y
;
3434 RColor color
= *((RColor
*)WMGetListItem(lPtr
, index
)->clientData
);
3435 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3436 Display
*dpy
= WMScreenDisplay(scr
);
3437 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3438 WMColor
*white
= WMWhiteColor(scr
);
3439 WMColor
*black
= WMBlackColor(scr
);
3442 width
= rect
->size
.width
;
3443 height
= rect
->size
.height
;
3447 if (state
& WLDSSelected
)
3448 WMPaintColorSwatch(white
, d
, x
+15, y
, width
-15, height
);
3450 XClearArea(dpy
, d
, x
+15, y
, width
-15, height
, False
);
3452 fillColor
= WMCreateRGBColor(scr
, color
.red
*256, color
.green
*256,
3453 color
.blue
*256, False
);
3455 WMSetColorInGC(fillColor
, WMColorGC(fillColor
));
3456 WMPaintColorSwatch(fillColor
, d
, x
, y
, 15, 15);
3457 WMReleaseColor(fillColor
);
3459 WMDrawString(scr
, d
, WMColorGC(black
), panel
->font12
, x
+18, y
, text
,
3462 WMReleaseColor(white
);
3463 WMReleaseColor(black
);
3468 colorListSelect(WMWidget
*w
, void *data
)
3470 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3473 cpColor
.rgb
= *((RColor
*)WMGetListSelectedItem(w
)->clientData
);
3474 cpColor
.set
= cpRGB
;
3476 panel
->lastChanged
= WMColorListModeColorPanel
;
3477 updateSwatch(panel
, cpColor
);
3482 colorListColorMenuCallback(WMWidget
*w
, void *data
)
3484 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3485 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3499 colorListListMenuCallback(WMWidget
*w
, void *data
)
3501 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3502 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3506 /* New Color List */
3507 colorListListMenuNew(panel
);
3518 colorListListMenuNew(W_ColorPanel
*panel
)
3524 /*************** Panel Initialisation Functions *****************/
3527 wheelInit(W_ColorPanel
*panel
)
3529 if (panel
->color
.set
!= cpHSV
)
3530 convertCPColor(&panel
->color
);
3532 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3533 wheelUpdateBrightnessGradient(panel
, panel
->color
);
3535 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3536 (1 + ( panel
->color
.hsv
.saturation
/255.0) *
3537 cos( panel
->color
.hsv
.hue
* M_PI
/180.0)));
3538 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3539 (1 + ( panel
->color
.hsv
.saturation
/255.0) *
3540 sin(- panel
->color
.hsv
.hue
*M_PI
/180.0)));
3542 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3547 grayInit(W_ColorPanel
*panel
)
3552 if (panel
->color
.set
!= cpHSV
)
3553 convertCPColor(&panel
->color
);
3555 value
= rint(panel
->color
.hsv
.value
/2.55);
3556 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3558 sprintf(tmp
, "%d", value
);
3559 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3564 rgbInit(W_ColorPanel
*panel
)
3568 if (panel
->color
.set
!= cpRGB
)
3569 convertCPColor(&panel
->color
);
3571 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3572 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3573 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3575 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3576 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3577 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3578 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3579 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3580 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3585 cmykInit(W_ColorPanel
*panel
)
3590 if (panel
->color
.set
!= cpRGB
)
3591 convertCPColor(&panel
->color
);
3593 value
[0] = rint((255-panel
->color
.rgb
.red
)/2.55);
3594 value
[1] = rint((255-panel
->color
.rgb
.green
)/2.55);
3595 value
[2] = rint((255-panel
->color
.rgb
.blue
)/2.55);
3597 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3598 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3599 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3600 WMSetSliderValue(panel
->cmykBlackS
, 0);
3602 sprintf(tmp
, "%d", value
[0]);
3603 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3604 sprintf(tmp
, "%d", value
[1]);
3605 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3606 sprintf(tmp
, "%d", value
[2]);
3607 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3608 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3613 hsbInit(W_ColorPanel
*panel
)
3618 if (panel
->color
.set
!= cpHSV
)
3619 convertCPColor(&panel
->color
);
3621 value
[0] = panel
->color
.hsv
.hue
;
3622 value
[1] = rint(panel
->color
.hsv
.saturation
/2.55);
3623 value
[2] = rint(panel
->color
.hsv
.value
/2.55);
3625 WMSetSliderValue(panel
->hsbHueS
,value
[0]);
3626 WMSetSliderValue(panel
->hsbSaturationS
,value
[1]);
3627 WMSetSliderValue(panel
->hsbBrightnessS
,value
[2]);
3629 sprintf(tmp
, "%d", value
[0]);
3630 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3631 sprintf(tmp
, "%d", value
[1]);
3632 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3633 sprintf(tmp
, "%d", value
[2]);
3634 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3636 hsbUpdateBrightnessGradient(panel
);
3637 hsbUpdateSaturationGradient(panel
);
3638 hsbUpdateHueGradient(panel
);
3643 /************************** Common utility functions ************************/
3646 fetchFile(char *toPath
, char *srcFile
, char *destFile
)
3653 if ((src
= open(srcFile
, O_RDONLY
)) == 0) {
3654 wsyserror("Could not open %s", srcFile
);
3658 tmp
= wstrappend(toPath
, destFile
);
3659 if ((dest
= open( tmp
, O_RDWR
|O_CREAT
, S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
))
3661 wsyserror("Could not create %s", tmp
);
3669 while ((n
= read(src
, buf
, BUFSIZE
)) > 0)
3671 if (write (dest
, buf
, n
) != n
) {
3672 wsyserror("Write error on file %s", destFile
);
3682 generateNewFilename(char *curName
)
3696 ((ptr
= strrchr(ptr
, '{')) == 0) ||
3697 sscanf(ptr
, "{%i}%c", &n
, &c
) != 1
3699 return wstrappend(curName
, " {1}");
3701 baseLen
= ptr
- curName
-1;
3703 newName
= wmalloc(baseLen
+ 16);
3704 strncpy(newName
, curName
, baseLen
);
3705 newName
[baseLen
] = 0;
3707 sprintf(&newName
[baseLen
], " {%i}", n
+1);
3714 convertCPColor(CPColor
*color
)
3716 unsigned short old_hue
= 0;
3718 switch (color
->set
) {
3720 wwarning("Color Panel: Color unspecified");
3723 old_hue
= color
->hsv
.hue
;
3724 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3726 /* In black the hue is undefined, and may change by conversion
3727 * Same for white. */
3729 ((color
->rgb
.red
== 0) &&
3730 (color
->rgb
.green
== 0) &&
3731 (color
->rgb
.blue
== 0)) ||
3732 ((color
->rgb
.red
== 0) &&
3733 (color
->rgb
.green
== 0) &&
3734 (color
->rgb
.blue
== 255))
3736 color
->hsv
.hue
= old_hue
;
3739 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3745 #define ABS_SHIFT(val, shift) \
3746 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3749 ulongToRColor(WMScreen
*scr
, unsigned long value
)
3752 XColor
*xcolor
= NULL
;
3754 if (!(xcolor
= wmalloc(sizeof(XColor
)) )) {
3755 wwarning(NO_MEMORY_ERR
);
3762 xcolor
->pixel
= value
;
3763 XQueryColor(scr
->display
, scr
->rcontext
->cmap
, xcolor
);
3765 color
.red
= xcolor
->red
>> 8;
3766 color
.green
= xcolor
->green
>> 8;
3767 color
.blue
= xcolor
->blue
>> 8;
3776 getShift(unsigned char value
)
3778 unsigned char i
= -1;
3793 #ifdef SHAPE_WAS_DEFINED
3794 #undef SHAPE_WAS_DEFINED