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 90 degrees.
22 * - Custom color-lists and custom colors in custom color-lists.
33 #include <sys/types.h>
38 /* BUG There's something fishy with shaped windows */
39 /* Whithout shape extension the magnified image is completely broken -Dan */
42 # define SHAPE_WAS_DEFINED
49 # include <X11/extensions/shape.h>
54 # define PATH_MAX 1024
58 char *WMColorPanelColorChangedNotification
= "WMColorPanelColorChangedNotification";
62 * Bitmaps for magnifying glass cursor
66 #define Cursor_x_hot 11
67 #define Cursor_y_hot 11
68 #define Cursor_width 32
69 #define Cursor_height 32
70 static unsigned char Cursor_bits
[] = {
71 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
72 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
73 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
74 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
75 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
76 0x00,0x08,0x00,0x50,0x00,0x10,0x00,0x88,0x00,0x20,0x00,0x5c,0x01,0xc0,0x81,
77 0x3b,0x02,0x00,0x7e,0x70,0x05,0x00,0x00,0xe0,0x08,0x00,0x00,0xc0,0x15,0x00,
78 0x00,0x80,0x23,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x5c,
79 0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x70};
81 /* Cursor shape-mask */
82 #define Cursor_shape_width 32
83 #define Cursor_shape_height 32
84 static unsigned char Cursor_shape_bits
[] = {
85 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
86 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
87 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
88 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
89 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
90 0x00,0x08,0x00,0x70,0x00,0x10,0x00,0xf8,0x00,0x20,0x00,0xfc,0x01,0xc0,0x81,
91 0xfb,0x03,0x00,0x7e,0xf0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x1f,0x00,
92 0x00,0x80,0x3f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfc,
93 0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70};
95 /* Clip-mask for magnified pixels */
96 #define Cursor_mask_width 24
97 #define Cursor_mask_height 24
98 static unsigned char Cursor_mask_bits
[] = {
99 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07,
100 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
101 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
102 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f,
103 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f,
104 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00};
107 typedef struct MovingView
{
108 WMView
*view
; /* The view this is all about */
109 XImage
*image
; /* What's under the view */
110 XImage
*dirtyRect
; /* Storage of overlapped image area */
111 Pixmap magPix
; /* Magnified part of pixmap */
112 RColor color
; /* Color of a pixel in the image */
113 int x
, y
; /* Position of view */
116 typedef struct CPColor
{
117 RColor rgb
; /* The RGB values of the color */
118 RHSVColor hsv
; /* The HSV values of the color */
119 enum { /* Which one was last set ? */
127 typedef struct WheelMatrix
{
128 unsigned int width
, height
; /* Size of the colorwheel */
129 unsigned char *data
[3]; /* Wheel data (R,G,B) */
130 unsigned char values
[256]; /* Precalculated values R,G & B = 0-255 */
133 typedef struct W_ColorPanel
{
141 WMColorWell
*colorWell
;
142 WMButton
*magnifyBtn
;
144 WMButton
*slidersBtn
;
145 WMButton
*customPaletteBtn
;
146 WMButton
*colorListBtn
;
148 /* Magnifying Glass */
149 MovingView
*magnifyGlass
;
151 /* ColorWheel Panel */
153 WMSlider
*wheelBrightnessS
;
158 WMFrame
*seperatorFrm
;
163 /* Gray Scale Panel */
167 WMSlider
*grayBrightnessS
;
168 WMTextField
*grayBrightnessT
;
169 WMButton
*grayPresetBtn
[7];
178 WMTextField
*rgbRedT
;
179 WMTextField
*rgbGreenT
;
180 WMTextField
*rgbBlueT
;
187 WMSlider
*cmykMagentaS
;
188 WMSlider
*cmykYellowS
;
189 WMSlider
*cmykBlackS
;
190 WMTextField
*cmykCyanT
;
191 WMTextField
*cmykMagentaT
;
192 WMTextField
*cmykYellowT
;
193 WMTextField
*cmykBlackT
;
198 WMSlider
*hsbSaturationS
;
199 WMSlider
*hsbBrightnessS
;
200 WMTextField
*hsbHueT
;
201 WMTextField
*hsbSaturationT
;
202 WMTextField
*hsbBrightnessT
;
204 /* Custom Palette Panel*/
205 WMFrame
*customPaletteFrm
;
206 WMPopUpButton
*customPaletteHistoryBtn
;
207 WMFrame
*customPaletteContentFrm
;
208 WMPopUpButton
*customPaletteMenuBtn
;
209 WMView
*customPaletteContentView
;
211 /* Color List Panel */
212 WMFrame
*colorListFrm
;
213 WMPopUpButton
*colorListHistoryBtn
;
214 WMList
*colorListContentLst
;
215 WMPopUpButton
*colorListColorMenuBtn
;
216 WMPopUpButton
*colorListListMenuBtn
;
218 /* Look-Up Tables and Images */
219 wheelMatrix
*wheelMtrx
;
222 Pixmap selectionBackImg
;
223 RImage
*customPaletteImg
;
226 /* Common Data Fields */
227 CPColor color
; /* Current color */
228 WMColorPanelMode mode
; /* Current color selection mode */
229 WMColorPanelMode slidersmode
; /* Current color sel. mode sliders panel */
230 WMColorPanelMode lastChanged
; /* Panel that last changed the color */
231 int colx
, coly
; /* (x,y) of sel.-marker in WheelMode */
232 int palx
, paly
; /* (x,y) of sel.-marker in
234 double palXRatio
, palYRatio
; /* Ratios in x & y between
238 char *configurationPath
;
241 unsigned int continuous
:1;
242 unsigned int dragging
:1;
251 CPmenuNewFromClipboard
252 } customPaletteMenuItem
;
263 #define colorWheelSize 150
264 #define customPaletteWidth 182
265 #define customPaletteHeight 106
266 #define knobThickness 8
268 #define SPECTRUM_WIDTH 511
269 #define SPECTRUM_HEIGHT 360
271 #define COLORWHEEL_PART 1
272 #define CUSTOMPALETTE_PART 2
276 #define RGBTXT "/usr/X11R6/lib/X11/rgb.txt"
279 #define MAX_LENGTH 1024
283 #define M_PI 3.14159265358979323846
286 /* Silly hack for Windows systems with cygwin */
291 static int fetchFile(char* toPath
, char *imageSrcFile
,
292 char *imageDestFileName
);
293 char *generateNewFilename(char *curName
);
294 void convertCPColor(CPColor
*color
);
295 RColor
ulongToRColor(WMScreen
*scr
, unsigned long value
);
296 unsigned char getShift(unsigned char value
);
298 static void modeButtonCallback(WMWidget
*w
, void *data
);
299 static int getPickerPart(W_ColorPanel
*panel
, int x
, int y
);
300 static void readConfiguration(W_ColorPanel
*panel
);
301 static void readXColors(W_ColorPanel
*panel
);
303 static void closeWindowCallback(WMWidget
*w
, void *data
);
305 static Cursor
magnifyGrabPointer(W_ColorPanel
*panel
);
306 static WMPoint
magnifyInitialize(W_ColorPanel
*panel
);
307 static void magnifyPutCursor(WMWidget
*w
, void *data
);
308 static Pixmap
magnifyCreatePixmap(WMColorPanel
*panel
);
309 static void magnifyGetImageStored(W_ColorPanel
*panel
, int x1
, int y1
,
311 static XImage
* magnifyGetImage(WMScreen
*scr
, XImage
*image
, int x
, int y
,
314 static wheelMatrix
* wheelCreateMatrix(unsigned int width
, unsigned int height
);
315 static void wheelDestroyMatrix(wheelMatrix
*matrix
);
316 static void wheelInitMatrix(W_ColorPanel
*panel
);
317 static void wheelCalculateValues(W_ColorPanel
*panel
, int maxvalue
);
318 static void wheelRender(W_ColorPanel
*panel
);
319 static Bool
wheelInsideColorWheel(W_ColorPanel
*panel
, unsigned long ofs
);
320 static void wheelPaint(W_ColorPanel
*panel
);
322 static void wheelHandleEvents(XEvent
*event
, void *data
);
323 static void wheelHandleActionEvents(XEvent
*event
, void *data
);
324 static void wheelBrightnessSliderCallback(WMWidget
*w
, void *data
);
325 static void wheelUpdateSelection(W_ColorPanel
*panel
);
326 static void wheelUndrawSelection(W_ColorPanel
*panel
);
328 static void wheelPositionSelection(W_ColorPanel
*panel
, int x
, int y
);
329 static void wheelPositionSelectionOutBounds(W_ColorPanel
*panel
, int x
, int y
);
330 static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel
*panel
);
331 static void wheelUpdateBrightnessGradient(W_ColorPanel
*panel
, CPColor topColor
);
333 static void grayBrightnessSliderCallback(WMWidget
*w
, void *data
);
334 static void grayPresetButtonCallback(WMWidget
*w
, void *data
);
335 static void grayBrightnessTextFieldCallback(void *observerData
,
336 WMNotification
*notification
);
338 static void rgbSliderCallback(WMWidget
*w
, void *data
);
339 static void rgbTextFieldCallback(void *observerData
,
340 WMNotification
*notification
);
342 static void cmykSliderCallback(WMWidget
*w
, void *data
);
343 static void cmykTextFieldCallback(void *observerData
,
344 WMNotification
*notification
);
346 static void hsbSliderCallback(WMWidget
*w
, void *data
);
347 static void hsbTextFieldCallback(void *observerData
,
348 WMNotification
*notification
);
349 static void hsbUpdateBrightnessGradient(W_ColorPanel
*panel
);
350 static void hsbUpdateSaturationGradient(W_ColorPanel
*panel
);
351 static void hsbUpdateHueGradient(W_ColorPanel
*panel
);
353 static void customRenderSpectrum(W_ColorPanel
*panel
);
354 static void customSetPalette(W_ColorPanel
*panel
);
355 static void customPaletteHandleEvents(XEvent
*event
, void *data
);
356 static void customPaletteHandleActionEvents(XEvent
*event
, void *data
);
357 static void customPalettePositionSelection(W_ColorPanel
*panel
, int x
, int y
);
358 static void customPalettePositionSelectionOutBounds(W_ColorPanel
*panel
,
360 static void customPaletteMenuCallback(WMWidget
*w
, void *data
);
361 static void customPaletteHistoryCallback(WMWidget
*w
, void *data
);
363 static void customPaletteMenuNewFromFile(W_ColorPanel
*panel
);
364 static void customPaletteMenuRename(W_ColorPanel
*panel
);
365 static void customPaletteMenuRemove(W_ColorPanel
*panel
);
367 static void colorListPaintItem(WMList
*lPtr
, int index
, Drawable d
, char *text
,
368 int state
, WMRect
*rect
);
369 static void colorListSelect(WMWidget
*w
, void *data
);
370 static void colorListColorMenuCallback(WMWidget
*w
, void *data
);
371 static void colorListListMenuCallback(WMWidget
*w
, void *data
);
372 static void colorListListMenuNew(W_ColorPanel
*panel
);
374 static void wheelInit(W_ColorPanel
*panel
);
375 static void grayInit(W_ColorPanel
*panel
);
376 static void rgbInit(W_ColorPanel
*panel
);
377 static void cmykInit(W_ColorPanel
*panel
);
378 static void hsbInit(W_ColorPanel
*panel
);
383 WMSetColorPanelAction(WMColorPanel
*panel
, WMAction2
*action
, void *data
)
385 panel
->action
= action
;
386 panel
->clientData
= data
;
390 makeColorPanel(WMScreen
*scrPtr
, char *name
)
397 WMColor
*textcolor
, *graybuttoncolor
;
399 GC bgc
= WMColorGC(scrPtr
->black
);
400 GC wgc
= WMColorGC(scrPtr
->white
);
403 panel
= wmalloc(sizeof(WMColorPanel
));
404 memset(panel
, 0, sizeof(WMColorPanel
));
406 panel
->color
.rgb
.red
= 0;
407 panel
->color
.rgb
.green
= 0;
408 panel
->color
.rgb
.blue
= 0;
409 panel
->color
.hsv
.hue
= 0;
410 panel
->color
.hsv
.saturation
= 0;
411 panel
->color
.hsv
.value
= 0;
412 panel
->color
.set
= cpNone
; /* Color has not been set yet */
414 panel
->font8
= WMSystemFontOfSize(scrPtr
, 8);
415 panel
->font12
= WMSystemFontOfSize(scrPtr
, 12);
417 panel
->win
= WMCreateWindowWithStyle(scrPtr
, name
,
418 WMTitledWindowMask
| WMClosableWindowMask
| WMResizableWindowMask
);
419 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
420 WMSetWindowTitle(panel
->win
, _("Colors"));
421 WMSetWindowCloseAction(panel
->win
, closeWindowCallback
, panel
);
424 /* Set Default ColorPanel Mode(s) */
425 panel
->mode
= WMWheelModeColorPanel
;
426 panel
->lastChanged
= 0;
427 panel
->slidersmode
= WMRGBModeColorPanel
;
428 panel
->configurationPath
= wstrconcat(wusergnusteppath(),
431 /* Some General Purpose Widgets */
432 panel
->colorWell
= WMCreateColorWell(panel
->win
);
433 WMResizeWidget(panel
->colorWell
, 134, 36);
434 WSetColorWellBordered(panel
->colorWell
, False
);
435 WMMoveWidget(panel
->colorWell
, 56, 4);
437 panel
->magnifyBtn
= WMCreateCustomButton(panel
->win
,
438 WBBStateLightMask
|WBBStateChangeMask
);
439 WMResizeWidget(panel
->magnifyBtn
, 46, 36);
440 WMMoveWidget(panel
->magnifyBtn
, 6,4);
441 WMSetButtonAction(panel
->magnifyBtn
, magnifyPutCursor
, panel
);
442 WMSetButtonImagePosition(panel
->magnifyBtn
, WIPImageOnly
);
443 WMSetButtonImage(panel
->magnifyBtn
, scrPtr
->magnifyIcon
);
445 panel
->wheelBtn
= WMCreateCustomButton(panel
->win
,
446 WBBStateLightMask
|WBBStateChangeMask
);
447 WMResizeWidget(panel
->wheelBtn
, 46, 32);
448 WMMoveWidget(panel
->wheelBtn
, 6, 44);
449 WMSetButtonAction(panel
->wheelBtn
, modeButtonCallback
, panel
);
450 WMSetButtonImagePosition(panel
->wheelBtn
, WIPImageOnly
);
451 WMSetButtonImage(panel
->wheelBtn
, scrPtr
->wheelIcon
);
453 panel
->slidersBtn
= WMCreateCustomButton(panel
->win
,
454 WBBStateLightMask
|WBBStateChangeMask
);
455 WMResizeWidget(panel
->slidersBtn
, 46, 32);
456 WMMoveWidget(panel
->slidersBtn
, 52, 44);
457 WMSetButtonAction(panel
->slidersBtn
, modeButtonCallback
, panel
);
458 WMSetButtonImagePosition(panel
->slidersBtn
, WIPImageOnly
);
459 WMSetButtonImage(panel
->slidersBtn
, scrPtr
->rgbIcon
);
461 panel
->customPaletteBtn
= WMCreateCustomButton(panel
->win
,
462 WBBStateLightMask
|WBBStateChangeMask
);
463 WMResizeWidget(panel
->customPaletteBtn
, 46, 32);
464 WMMoveWidget(panel
->customPaletteBtn
, 98, 44);
465 WMSetButtonAction(panel
->customPaletteBtn
, modeButtonCallback
, panel
);
466 WMSetButtonImagePosition(panel
->customPaletteBtn
, WIPImageOnly
);
467 WMSetButtonImage(panel
->customPaletteBtn
, scrPtr
->customPaletteIcon
);
469 panel
->colorListBtn
= WMCreateCustomButton(panel
->win
,
470 WBBStateLightMask
|WBBStateChangeMask
);
471 WMResizeWidget(panel
->colorListBtn
, 46, 32);
472 WMMoveWidget(panel
->colorListBtn
, 144, 44);
473 WMSetButtonAction(panel
->colorListBtn
, modeButtonCallback
, panel
);
474 WMSetButtonImagePosition(panel
->colorListBtn
, WIPImageOnly
);
475 WMSetButtonImage(panel
->colorListBtn
, scrPtr
->colorListIcon
);
477 /* Let's Group some of them together */
478 WMGroupButtons(panel
->wheelBtn
, panel
->slidersBtn
);
479 WMGroupButtons(panel
->wheelBtn
, panel
->customPaletteBtn
);
480 WMGroupButtons(panel
->wheelBtn
, panel
->colorListBtn
);
482 /* Widgets for the ColorWheel Panel */
483 panel
->wheelFrm
= WMCreateFrame(panel
->win
);
484 WMSetFrameRelief(panel
->wheelFrm
, WRFlat
);
485 WMResizeWidget(panel
->wheelFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
486 WMMoveWidget(panel
->wheelFrm
, 5, 80);
488 panel
->wheelView
= W_CreateView(W_VIEW(panel
->wheelFrm
));
489 /* XXX Can we create a view ? */
490 W_ResizeView(panel
->wheelView
, colorWheelSize
+4, colorWheelSize
+4);
491 W_MoveView(panel
->wheelView
, 0, 0);
493 /* Create an event handler to handle expose/click events in ColorWheel */
494 WMCreateEventHandler(panel
->wheelView
,
495 ButtonPressMask
|ButtonReleaseMask
|EnterWindowMask
|
496 LeaveWindowMask
|ButtonMotionMask
, wheelHandleActionEvents
, panel
);
498 WMCreateEventHandler(panel
->wheelView
, ExposureMask
, wheelHandleEvents
,
501 panel
->wheelBrightnessS
= WMCreateSlider(panel
->wheelFrm
);
502 WMResizeWidget(panel
->wheelBrightnessS
, 16, 153);
503 WMMoveWidget(panel
->wheelBrightnessS
, 5+colorWheelSize
+14, 1);
504 WMSetSliderMinValue(panel
->wheelBrightnessS
, 0);
505 WMSetSliderMaxValue(panel
->wheelBrightnessS
, 255);
506 WMSetSliderAction(panel
->wheelBrightnessS
, wheelBrightnessSliderCallback
,
508 WMSetSliderKnobThickness(panel
->wheelBrightnessS
, knobThickness
);
510 panel
->wheelMtrx
= wheelCreateMatrix(colorWheelSize
+4, colorWheelSize
+4);
511 wheelInitMatrix(panel
);
514 /* Widgets for the Slider Panels */
515 panel
->slidersFrm
= WMCreateFrame(panel
->win
);
516 WMSetFrameRelief(panel
->slidersFrm
, WRFlat
);
517 WMResizeWidget(panel
->slidersFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
518 WMMoveWidget(panel
->slidersFrm
, 4, 80);
520 panel
->seperatorFrm
= WMCreateFrame(panel
->slidersFrm
);
521 WMSetFrameRelief(panel
->seperatorFrm
, WRPushed
);
522 WMResizeWidget(panel
->seperatorFrm
, PWIDTH
- 8, 2);
523 WMMoveWidget(panel
->seperatorFrm
, 0, 1);
525 panel
->grayBtn
= WMCreateCustomButton(panel
->slidersFrm
,
526 WBBStateLightMask
|WBBStateChangeMask
);
527 WMResizeWidget(panel
->grayBtn
, 46, 24);
528 WMMoveWidget(panel
->grayBtn
, 1, 8);
529 WMSetButtonAction(panel
->grayBtn
, modeButtonCallback
, panel
);
530 WMSetButtonImagePosition(panel
->grayBtn
, WIPImageOnly
);
531 WMSetButtonImage(panel
->grayBtn
, scrPtr
->grayIcon
);
533 panel
->rgbBtn
= WMCreateCustomButton(panel
->slidersFrm
,
534 WBBStateLightMask
|WBBStateChangeMask
);
535 WMResizeWidget(panel
->rgbBtn
, 46, 24);
536 WMMoveWidget(panel
->rgbBtn
, 47, 8);
537 WMSetButtonAction(panel
->rgbBtn
, modeButtonCallback
, panel
);
538 WMSetButtonImagePosition(panel
->rgbBtn
, WIPImageOnly
);
539 WMSetButtonImage(panel
->rgbBtn
, scrPtr
->rgbIcon
);
541 panel
->cmykBtn
= WMCreateCustomButton(panel
->slidersFrm
,
542 WBBStateLightMask
|WBBStateChangeMask
);
543 WMResizeWidget(panel
->cmykBtn
, 46, 24);
544 WMMoveWidget(panel
->cmykBtn
, 93, 8);
545 WMSetButtonAction(panel
->cmykBtn
, modeButtonCallback
, panel
);
546 WMSetButtonImagePosition(panel
->cmykBtn
, WIPImageOnly
);
547 WMSetButtonImage(panel
->cmykBtn
, scrPtr
->cmykIcon
);
549 panel
->hsbBtn
= WMCreateCustomButton(panel
->slidersFrm
,
550 WBBStateLightMask
|WBBStateChangeMask
);
551 WMResizeWidget(panel
->hsbBtn
, 46, 24);
552 WMMoveWidget(panel
->hsbBtn
, 139, 8);
553 WMSetButtonAction(panel
->hsbBtn
, modeButtonCallback
, panel
);
554 WMSetButtonImagePosition(panel
->hsbBtn
, WIPImageOnly
);
555 WMSetButtonImage(panel
->hsbBtn
, scrPtr
->hsbIcon
);
557 /* Let's Group the Slider Panel Buttons Together */
558 WMGroupButtons(panel
->grayBtn
, panel
->rgbBtn
);
559 WMGroupButtons(panel
->grayBtn
, panel
->cmykBtn
);
560 WMGroupButtons(panel
->grayBtn
, panel
->hsbBtn
);
562 textcolor
= WMDarkGrayColor(scrPtr
);
564 /* Widgets for GrayScale Panel */
565 panel
->grayFrm
= WMCreateFrame(panel
->slidersFrm
);
566 WMSetFrameRelief(panel
->grayFrm
, WRFlat
);
567 WMResizeWidget(panel
->grayFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
568 WMMoveWidget(panel
->grayFrm
, 0, 34);
570 panel
->grayMinL
= WMCreateLabel(panel
->grayFrm
);
571 WMResizeWidget(panel
->grayMinL
, 20, 10);
572 WMMoveWidget(panel
->grayMinL
, 2, 2);
573 WMSetLabelText(panel
->grayMinL
, "0");
574 WMSetLabelTextAlignment(panel
->grayMinL
, WALeft
);
575 WMSetLabelTextColor(panel
->grayMinL
, textcolor
);
576 WMSetLabelFont(panel
->grayMinL
, panel
->font8
);
578 panel
->grayMaxL
= WMCreateLabel(panel
->grayFrm
);
579 WMResizeWidget(panel
->grayMaxL
, 40, 10);
580 WMMoveWidget(panel
->grayMaxL
, 104, 2);
581 WMSetLabelText(panel
->grayMaxL
, "100");
582 WMSetLabelTextAlignment(panel
->grayMaxL
, WARight
);
583 WMSetLabelTextColor(panel
->grayMaxL
, textcolor
);
584 WMSetLabelFont(panel
->grayMaxL
, panel
->font8
);
586 panel
->grayBrightnessS
= WMCreateSlider(panel
->grayFrm
);
587 WMResizeWidget(panel
->grayBrightnessS
, 141, 16);
588 WMMoveWidget(panel
->grayBrightnessS
, 2, 14);
589 WMSetSliderMinValue(panel
->grayBrightnessS
, 0);
590 WMSetSliderMaxValue(panel
->grayBrightnessS
, 100);
591 WMSetSliderKnobThickness(panel
->grayBrightnessS
, knobThickness
);
592 WMSetSliderAction(panel
->grayBrightnessS
, grayBrightnessSliderCallback
,
603 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
604 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
605 RReleaseImage(image
);
608 W_PaintText(W_VIEW(panel
->grayBrightnessS
), pixmap
->pixmap
,
609 panel
->font12
, 2, 0, 100, WALeft
, scrPtr
->white
,
610 False
, _("Brightness"), strlen(_("Brightness")));
612 wwarning(_("Color Panel: Could not allocate memory"));
614 WMSetSliderImage(panel
->grayBrightnessS
, pixmap
);
615 WMReleasePixmap(pixmap
);
617 panel
->grayBrightnessT
= WMCreateTextField(panel
->grayFrm
);
618 WMResizeWidget(panel
->grayBrightnessT
, 40, 18);
619 WMMoveWidget(panel
->grayBrightnessT
, 146, 13);
620 WMSetTextFieldAlignment(panel
->grayBrightnessT
, WALeft
);
621 WMAddNotificationObserver(grayBrightnessTextFieldCallback
, panel
,
622 WMTextDidEndEditingNotification
, panel
->grayBrightnessT
);
624 for (i
=0; i
< 7; i
++) {
625 pixmap
= WMCreatePixmap(scrPtr
, 13, 13, scrPtr
->depth
, False
);
627 graybuttoncolor
= WMCreateRGBColor(scrPtr
, (255/6)*i
<< 8,
628 (255/6)*i
<< 8, (255/6)*i
<< 8, True
);
629 WMPaintColorSwatch(graybuttoncolor
, pixmap
->pixmap
, 0, 0, 15, 15);
630 WMReleaseColor(graybuttoncolor
);
632 panel
->grayPresetBtn
[i
] = WMCreateCommandButton(panel
->grayFrm
);
633 WMResizeWidget(panel
->grayPresetBtn
[i
], 20, 24);
634 WMMoveWidget(panel
->grayPresetBtn
[i
], 2+(i
*20), 34);
635 WMSetButtonAction(panel
->grayPresetBtn
[i
],
636 grayPresetButtonCallback
, panel
);
637 WMSetButtonImage(panel
->grayPresetBtn
[i
], pixmap
);
638 WMSetButtonImagePosition(panel
->grayPresetBtn
[i
], WIPImageOnly
);
639 WMReleasePixmap(pixmap
);
643 /* End of GrayScale Panel */
645 /* Widgets for RGB Panel */
646 panel
->rgbFrm
= WMCreateFrame(panel
->slidersFrm
);
647 WMSetFrameRelief(panel
->rgbFrm
, WRFlat
);
648 WMResizeWidget(panel
->rgbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
649 WMMoveWidget(panel
->rgbFrm
, 0, 34);
651 panel
->rgbMinL
= WMCreateLabel(panel
->rgbFrm
);
652 WMResizeWidget(panel
->rgbMinL
, 20, 10);
653 WMMoveWidget(panel
->rgbMinL
, 2, 2);
654 WMSetLabelText(panel
->rgbMinL
, "0");
655 WMSetLabelTextAlignment(panel
->rgbMinL
, WALeft
);
656 WMSetLabelTextColor(panel
->rgbMinL
, textcolor
);
657 WMSetLabelFont(panel
->rgbMinL
, panel
->font8
);
659 panel
->rgbMaxL
= WMCreateLabel(panel
->rgbFrm
);
660 WMResizeWidget(panel
->rgbMaxL
, 40, 10);
661 WMMoveWidget(panel
->rgbMaxL
, 104, 2);
662 WMSetLabelText(panel
->rgbMaxL
, "255");
663 WMSetLabelTextAlignment(panel
->rgbMaxL
, WARight
);
664 WMSetLabelTextColor(panel
->rgbMaxL
, textcolor
);
665 WMSetLabelFont(panel
->rgbMaxL
, panel
->font8
);
667 panel
->rgbRedS
= WMCreateSlider(panel
->rgbFrm
);
668 WMResizeWidget(panel
->rgbRedS
, 141, 16);
669 WMMoveWidget(panel
->rgbRedS
, 2, 14);
670 WMSetSliderMinValue(panel
->rgbRedS
, 0);
671 WMSetSliderMaxValue(panel
->rgbRedS
, 255);
672 WMSetSliderKnobThickness(panel
->rgbRedS
, knobThickness
);
673 WMSetSliderAction(panel
->rgbRedS
, rgbSliderCallback
, panel
);
679 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
680 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
681 RReleaseImage(image
);
684 W_PaintText(W_VIEW(panel
->rgbRedS
), pixmap
->pixmap
, panel
->font12
,
685 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Red"),
688 wwarning(_("Color Panel: Could not allocate memory"));
690 WMSetSliderImage(panel
->rgbRedS
, pixmap
);
691 WMReleasePixmap(pixmap
);
693 panel
->rgbRedT
= WMCreateTextField(panel
->rgbFrm
);
694 WMResizeWidget(panel
->rgbRedT
, 40, 18);
695 WMMoveWidget(panel
->rgbRedT
, 146, 13);
696 WMSetTextFieldAlignment(panel
->rgbRedT
, WALeft
);
697 WMAddNotificationObserver(rgbTextFieldCallback
, panel
,
698 WMTextDidEndEditingNotification
, panel
->rgbRedT
);
700 panel
->rgbGreenS
= WMCreateSlider(panel
->rgbFrm
);
701 WMResizeWidget(panel
->rgbGreenS
, 141, 16);
702 WMMoveWidget(panel
->rgbGreenS
, 2, 36);
703 WMSetSliderMinValue(panel
->rgbGreenS
, 0);
704 WMSetSliderMaxValue(panel
->rgbGreenS
, 255);
705 WMSetSliderKnobThickness(panel
->rgbGreenS
, knobThickness
);
706 WMSetSliderAction(panel
->rgbGreenS
, rgbSliderCallback
, panel
);
712 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
713 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
714 RReleaseImage(image
);
717 W_PaintText(W_VIEW(panel
->rgbGreenS
), pixmap
->pixmap
, panel
->font12
,
718 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Green"),
721 wwarning(_("Color Panel: Could not allocate memory"));
723 WMSetSliderImage(panel
->rgbGreenS
, pixmap
);
724 WMReleasePixmap(pixmap
);
726 panel
->rgbGreenT
= WMCreateTextField(panel
->rgbFrm
);
727 WMResizeWidget(panel
->rgbGreenT
, 40, 18);
728 WMMoveWidget(panel
->rgbGreenT
, 146, 35);
729 WMSetTextFieldAlignment(panel
->rgbGreenT
, WALeft
);
730 WMAddNotificationObserver(rgbTextFieldCallback
, panel
,
731 WMTextDidEndEditingNotification
, panel
->rgbGreenT
);
734 panel
->rgbBlueS
= WMCreateSlider(panel
->rgbFrm
);
735 WMResizeWidget(panel
->rgbBlueS
, 141, 16);
736 WMMoveWidget(panel
->rgbBlueS
, 2, 58);
737 WMSetSliderMinValue(panel
->rgbBlueS
, 0);
738 WMSetSliderMaxValue(panel
->rgbBlueS
, 255);
739 WMSetSliderKnobThickness(panel
->rgbBlueS
, knobThickness
);
740 WMSetSliderAction(panel
->rgbBlueS
, rgbSliderCallback
, panel
);
746 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
747 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
748 RReleaseImage(image
);
751 W_PaintText(W_VIEW(panel
->rgbBlueS
), pixmap
->pixmap
, panel
->font12
,
752 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Blue"),
755 wwarning(_("Color Panel: Could not allocate memory"));
757 WMSetSliderImage(panel
->rgbBlueS
, pixmap
);
758 WMReleasePixmap(pixmap
);
760 panel
->rgbBlueT
= WMCreateTextField(panel
->rgbFrm
);
761 WMResizeWidget(panel
->rgbBlueT
, 40, 18);
762 WMMoveWidget(panel
->rgbBlueT
, 146, 57);
763 WMSetTextFieldAlignment(panel
->rgbBlueT
, WALeft
);
764 WMAddNotificationObserver(rgbTextFieldCallback
, panel
,
765 WMTextDidEndEditingNotification
, panel
->rgbBlueT
);
766 /* End of RGB Panel */
768 /* Widgets for CMYK Panel */
769 panel
->cmykFrm
= WMCreateFrame(panel
->slidersFrm
);
770 WMSetFrameRelief(panel
->cmykFrm
, WRFlat
);
771 WMResizeWidget(panel
->cmykFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
772 WMMoveWidget(panel
->cmykFrm
, 0, 34);
774 panel
->cmykMinL
= WMCreateLabel(panel
->cmykFrm
);
775 WMResizeWidget(panel
->cmykMinL
, 20, 10);
776 WMMoveWidget(panel
->cmykMinL
, 2, 2);
777 WMSetLabelText(panel
->cmykMinL
, "0");
778 WMSetLabelTextAlignment(panel
->cmykMinL
, WALeft
);
779 WMSetLabelTextColor(panel
->cmykMinL
, textcolor
);
780 WMSetLabelFont(panel
->cmykMinL
, panel
->font8
);
782 panel
->cmykMaxL
= WMCreateLabel(panel
->cmykFrm
);
783 WMResizeWidget(panel
->cmykMaxL
, 40, 10);
784 WMMoveWidget(panel
->cmykMaxL
, 104, 2);
785 WMSetLabelText(panel
->cmykMaxL
, "100");
786 WMSetLabelTextAlignment(panel
->cmykMaxL
, WARight
);
787 WMSetLabelTextColor(panel
->cmykMaxL
, textcolor
);
788 WMSetLabelFont(panel
->cmykMaxL
, panel
->font8
);
790 panel
->cmykCyanS
= WMCreateSlider(panel
->cmykFrm
);
791 WMResizeWidget(panel
->cmykCyanS
, 141, 16);
792 WMMoveWidget(panel
->cmykCyanS
, 2, 14);
793 WMSetSliderMinValue(panel
->cmykCyanS
, 0);
794 WMSetSliderMaxValue(panel
->cmykCyanS
, 100);
795 WMSetSliderKnobThickness(panel
->cmykCyanS
, knobThickness
);
796 WMSetSliderAction(panel
->cmykCyanS
, cmykSliderCallback
, panel
);
806 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
807 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
808 RReleaseImage(image
);
811 W_PaintText(W_VIEW(panel
->cmykCyanS
), pixmap
->pixmap
, panel
->font12
,
812 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Cyan"),
815 wwarning(_("Color Panel: Could not allocate memory"));
817 WMSetSliderImage(panel
->cmykCyanS
, pixmap
);
818 WMReleasePixmap(pixmap
);
820 panel
->cmykCyanT
= WMCreateTextField(panel
->cmykFrm
);
821 WMResizeWidget(panel
->cmykCyanT
, 40, 18);
822 WMMoveWidget(panel
->cmykCyanT
, 146, 13);
823 WMSetTextFieldAlignment(panel
->cmykCyanT
, WALeft
);
824 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
825 WMTextDidEndEditingNotification
, panel
->cmykCyanT
);
828 panel
->cmykMagentaS
= WMCreateSlider(panel
->cmykFrm
);
829 WMResizeWidget(panel
->cmykMagentaS
, 141, 16);
830 WMMoveWidget(panel
->cmykMagentaS
, 2, 36);
831 WMSetSliderMinValue(panel
->cmykMagentaS
, 0);
832 WMSetSliderMaxValue(panel
->cmykMagentaS
, 100);
833 WMSetSliderKnobThickness(panel
->cmykMagentaS
, knobThickness
);
834 WMSetSliderAction(panel
->cmykMagentaS
, cmykSliderCallback
, panel
);
840 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
841 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
842 RReleaseImage(image
);
845 W_PaintText(W_VIEW(panel
->cmykMagentaS
), pixmap
->pixmap
, panel
->font12
,
846 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Magenta"),
847 strlen(_("Magenta")));
849 wwarning(_("Color Panel: Could not allocate memory"));
851 WMSetSliderImage(panel
->cmykMagentaS
, pixmap
);
852 WMReleasePixmap(pixmap
);
854 panel
->cmykMagentaT
= WMCreateTextField(panel
->cmykFrm
);
855 WMResizeWidget(panel
->cmykMagentaT
, 40, 18);
856 WMMoveWidget(panel
->cmykMagentaT
, 146, 35);
857 WMSetTextFieldAlignment(panel
->cmykMagentaT
, WALeft
);
858 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
859 WMTextDidEndEditingNotification
, panel
->cmykMagentaT
);
862 panel
->cmykYellowS
= WMCreateSlider(panel
->cmykFrm
);
863 WMResizeWidget(panel
->cmykYellowS
, 141, 16);
864 WMMoveWidget(panel
->cmykYellowS
, 2, 58);
865 WMSetSliderMinValue(panel
->cmykYellowS
, 0);
866 WMSetSliderMaxValue(panel
->cmykYellowS
, 100);
867 WMSetSliderKnobThickness(panel
->cmykYellowS
, knobThickness
);
868 WMSetSliderAction(panel
->cmykYellowS
, cmykSliderCallback
, panel
);
874 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
875 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
876 RReleaseImage(image
);
879 W_PaintText(W_VIEW(panel
->cmykYellowS
), pixmap
->pixmap
, panel
->font12
,
880 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Yellow"),
881 strlen(_("Yellow")));
883 wwarning(_("Color Panel: Could not allocate memory"));
885 WMSetSliderImage(panel
->cmykYellowS
, pixmap
);
886 WMReleasePixmap(pixmap
);
888 panel
->cmykYellowT
= WMCreateTextField(panel
->cmykFrm
);
889 WMResizeWidget(panel
->cmykYellowT
, 40, 18);
890 WMMoveWidget(panel
->cmykYellowT
, 146, 57);
891 WMSetTextFieldAlignment(panel
->cmykYellowT
, WALeft
);
892 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
893 WMTextDidEndEditingNotification
, panel
->cmykYellowT
);
896 panel
->cmykBlackS
= WMCreateSlider(panel
->cmykFrm
);
897 WMResizeWidget(panel
->cmykBlackS
, 141, 16);
898 WMMoveWidget(panel
->cmykBlackS
, 2, 80);
899 WMSetSliderMinValue(panel
->cmykBlackS
, 0);
900 WMSetSliderMaxValue(panel
->cmykBlackS
, 100);
901 WMSetSliderValue(panel
->cmykBlackS
, 0);
902 WMSetSliderKnobThickness(panel
->cmykBlackS
, knobThickness
);
903 WMSetSliderAction(panel
->cmykBlackS
, cmykSliderCallback
, panel
);
909 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
910 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
911 RReleaseImage(image
);
914 W_PaintText(W_VIEW(panel
->cmykBlackS
), pixmap
->pixmap
, panel
->font12
,
915 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Black"),
918 wwarning(_("Color Panel: Could not allocate memory"));
920 WMSetSliderImage(panel
->cmykBlackS
, pixmap
);
921 WMReleasePixmap(pixmap
);
923 panel
->cmykBlackT
= WMCreateTextField(panel
->cmykFrm
);
924 WMResizeWidget(panel
->cmykBlackT
, 40, 18);
925 WMMoveWidget(panel
->cmykBlackT
, 146, 79);
926 WMSetTextFieldAlignment(panel
->cmykBlackT
, WALeft
);
927 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
928 WMTextDidEndEditingNotification
, panel
->cmykBlackT
);
929 /* End of CMYK Panel */
931 /* Widgets for HSB Panel */
932 panel
->hsbFrm
= WMCreateFrame(panel
->slidersFrm
);
933 WMSetFrameRelief(panel
->hsbFrm
, WRFlat
);
934 WMResizeWidget(panel
->hsbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
935 WMMoveWidget(panel
->hsbFrm
, 0, 34);
937 panel
->hsbHueS
= WMCreateSlider(panel
->hsbFrm
);
938 WMResizeWidget(panel
->hsbHueS
, 141, 16);
939 WMMoveWidget(panel
->hsbHueS
, 2, 14);
940 WMSetSliderMinValue(panel
->hsbHueS
, 0);
941 WMSetSliderMaxValue(panel
->hsbHueS
, 359);
942 WMSetSliderKnobThickness(panel
->hsbHueS
, knobThickness
);
943 WMSetSliderAction(panel
->hsbHueS
, hsbSliderCallback
, panel
);
945 panel
->hsbHueT
= WMCreateTextField(panel
->hsbFrm
);
946 WMResizeWidget(panel
->hsbHueT
, 40, 18);
947 WMMoveWidget(panel
->hsbHueT
, 146, 13);
948 WMSetTextFieldAlignment(panel
->hsbHueT
, WALeft
);
949 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
950 WMTextDidEndEditingNotification
, panel
->hsbHueT
);
953 panel
->hsbSaturationS
= WMCreateSlider(panel
->hsbFrm
);
954 WMResizeWidget(panel
->hsbSaturationS
, 141, 16);
955 WMMoveWidget(panel
->hsbSaturationS
, 2, 36);
956 WMSetSliderMinValue(panel
->hsbSaturationS
, 0);
957 WMSetSliderMaxValue(panel
->hsbSaturationS
, 100);
958 WMSetSliderKnobThickness(panel
->hsbSaturationS
, knobThickness
);
959 WMSetSliderAction(panel
->hsbSaturationS
, hsbSliderCallback
, panel
);
961 panel
->hsbSaturationT
= WMCreateTextField(panel
->hsbFrm
);
962 WMResizeWidget(panel
->hsbSaturationT
, 40, 18);
963 WMMoveWidget(panel
->hsbSaturationT
, 146, 35);
964 WMSetTextFieldAlignment(panel
->hsbSaturationT
, WALeft
);
965 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
966 WMTextDidEndEditingNotification
, panel
->hsbSaturationT
);
969 panel
->hsbBrightnessS
= WMCreateSlider(panel
->hsbFrm
);
970 WMResizeWidget(panel
->hsbBrightnessS
, 141, 16);
971 WMMoveWidget(panel
->hsbBrightnessS
, 2, 58);
972 WMSetSliderMinValue(panel
->hsbBrightnessS
, 0);
973 WMSetSliderMaxValue(panel
->hsbBrightnessS
, 100);
974 WMSetSliderKnobThickness(panel
->hsbBrightnessS
, knobThickness
);
975 WMSetSliderAction(panel
->hsbBrightnessS
, hsbSliderCallback
, panel
);
977 panel
->hsbBrightnessT
= WMCreateTextField(panel
->hsbFrm
);
978 WMResizeWidget(panel
->hsbBrightnessT
, 40, 18);
979 WMMoveWidget(panel
->hsbBrightnessT
, 146, 57);
980 WMSetTextFieldAlignment(panel
->hsbBrightnessT
, WALeft
);
981 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
982 WMTextDidEndEditingNotification
, panel
->hsbBrightnessT
);
983 /* End of HSB Panel */
986 WMReleaseColor(textcolor
);
988 /* Widgets for the CustomPalette Panel */
989 panel
->customPaletteFrm
= WMCreateFrame(panel
->win
);
990 WMSetFrameRelief(panel
->customPaletteFrm
, WRFlat
);
991 WMResizeWidget(panel
->customPaletteFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
992 WMMoveWidget(panel
->customPaletteFrm
, 5, 80);
994 panel
->customPaletteHistoryBtn
= WMCreatePopUpButton(
995 panel
->customPaletteFrm
);
996 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, _("Spectrum"));
997 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
998 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
)-1);
999 WMSetPopUpButtonAction(panel
->customPaletteHistoryBtn
,
1000 customPaletteHistoryCallback
, panel
);
1001 WMResizeWidget(panel
->customPaletteHistoryBtn
, PWIDTH
- 8, 20);
1002 WMMoveWidget(panel
->customPaletteHistoryBtn
, 0, 0);
1004 panel
->customPaletteContentFrm
= WMCreateFrame(panel
->customPaletteFrm
);
1005 WMSetFrameRelief(panel
->customPaletteContentFrm
, WRSunken
);
1006 WMResizeWidget(panel
->customPaletteContentFrm
, PWIDTH
- 8, PHEIGHT
- 156);
1007 WMMoveWidget(panel
->customPaletteContentFrm
, 0, 23);
1009 panel
->customPaletteContentView
= W_CreateView(
1010 W_VIEW(panel
->customPaletteContentFrm
));
1011 /* XXX Test if we can create a view */
1012 W_ResizeView(panel
->customPaletteContentView
, customPaletteWidth
,
1013 customPaletteHeight
);
1014 W_MoveView(panel
->customPaletteContentView
, 2, 2);
1016 /* Create event handler to handle expose/click events in CustomPalette */
1017 WMCreateEventHandler(panel
->customPaletteContentView
,
1018 ButtonPressMask
|ButtonReleaseMask
|EnterWindowMask
| LeaveWindowMask
|
1019 ButtonMotionMask
, customPaletteHandleActionEvents
, panel
);
1021 WMCreateEventHandler(panel
->customPaletteContentView
, ExposureMask
,
1022 customPaletteHandleEvents
, panel
);
1024 panel
->customPaletteMenuBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
1025 WMSetPopUpButtonPullsDown(panel
->customPaletteMenuBtn
, 1);
1026 WMSetPopUpButtonText(panel
->customPaletteMenuBtn
, _("Palette"));
1027 WMSetPopUpButtonAction(panel
->customPaletteMenuBtn
,
1028 customPaletteMenuCallback
, panel
);
1029 WMResizeWidget(panel
->customPaletteMenuBtn
, PWIDTH
- 8, 20);
1030 WMMoveWidget(panel
->customPaletteMenuBtn
, 0, PHEIGHT
- 130);
1032 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from File..."));
1033 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Rename..."));
1034 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Remove"));
1035 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Copy"));
1036 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from Clipboard"));
1038 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, 0);
1039 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, 0);
1040 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuCopy
, 0);
1041 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
,
1042 CPmenuNewFromClipboard
, 0);
1044 customRenderSpectrum(panel
);
1045 panel
->currentPalette
= 0;
1046 panel
->palx
= customPaletteWidth
/2;
1047 panel
->paly
= customPaletteHeight
/2;
1050 /* Widgets for the ColorList Panel */
1051 panel
->colorListFrm
= WMCreateFrame(panel
->win
);
1052 WMSetFrameRelief(panel
->colorListFrm
, WRFlat
);
1053 WMResizeWidget(panel
->colorListFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
1054 WMMoveWidget(panel
->colorListFrm
, 5, 80);
1056 panel
->colorListHistoryBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1057 WMAddPopUpButtonItem(panel
->colorListHistoryBtn
, _("X11-Colors"));
1058 WMSetPopUpButtonSelectedItem(panel
->colorListHistoryBtn
,
1059 WMGetPopUpButtonNumberOfItems(panel
->colorListHistoryBtn
)-1);
1060 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
1061 * colorListHistoryCallback, panel); */
1062 WMResizeWidget(panel
->colorListHistoryBtn
, PWIDTH
- 8, 20);
1063 WMMoveWidget(panel
->colorListHistoryBtn
, 0, 0);
1065 panel
->colorListContentLst
= WMCreateList(panel
->colorListFrm
);
1066 WMSetListAction(panel
->colorListContentLst
, colorListSelect
, panel
);
1067 WMSetListUserDrawProc(panel
->colorListContentLst
, colorListPaintItem
);
1068 WMResizeWidget(panel
->colorListContentLst
, PWIDTH
- 8, PHEIGHT
- 156);
1069 WMMoveWidget(panel
->colorListContentLst
, 0, 23);
1070 WMHangData(panel
->colorListContentLst
, panel
);
1072 panel
->colorListColorMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1073 WMSetPopUpButtonPullsDown(panel
->colorListColorMenuBtn
, 1);
1074 WMSetPopUpButtonText(panel
->colorListColorMenuBtn
, _("Color"));
1075 WMSetPopUpButtonAction(panel
->colorListColorMenuBtn
,
1076 colorListColorMenuCallback
, panel
);
1077 WMResizeWidget(panel
->colorListColorMenuBtn
, (PWIDTH
- 16)/2, 20);
1078 WMMoveWidget(panel
->colorListColorMenuBtn
, 0, PHEIGHT
- 130);
1080 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Add..."));
1081 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Rename..."));
1082 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Remove"));
1084 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuAdd
, 0);
1085 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRename
, 0);
1086 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRemove
, 0);
1088 panel
->colorListListMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1089 WMSetPopUpButtonPullsDown(panel
->colorListListMenuBtn
, 1);
1090 WMSetPopUpButtonText(panel
->colorListListMenuBtn
, _("List"));
1091 WMSetPopUpButtonAction(panel
->colorListListMenuBtn
,
1092 colorListListMenuCallback
, panel
);
1093 WMResizeWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16)/2, 20);
1094 WMMoveWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16)/2 + 8,
1097 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("New..."));
1098 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Rename..."));
1099 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Remove"));
1101 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuAdd
, 0);
1102 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRename
, 0);
1103 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRemove
, 0);
1105 WMRealizeWidget(panel
->win
);
1106 WMMapSubwidgets(panel
->win
);
1108 WMMapSubwidgets(panel
->wheelFrm
);
1109 WMMapSubwidgets(panel
->slidersFrm
);
1110 WMMapSubwidgets(panel
->grayFrm
);
1111 WMMapSubwidgets(panel
->rgbFrm
);
1112 WMMapSubwidgets(panel
->cmykFrm
);
1113 WMMapSubwidgets(panel
->hsbFrm
);
1114 WMMapSubwidgets(panel
->customPaletteFrm
);
1115 WMMapSubwidgets(panel
->customPaletteContentFrm
);
1116 WMMapSubwidgets(panel
->colorListFrm
);
1118 /* Pixmap to indicate selection positions
1119 * wheelframe MUST be mapped.
1121 panel
->selectionImg
= XCreatePixmap(scrPtr
->display
,
1122 WMWidgetXID(panel
->win
), 4, 4, scrPtr
->depth
);
1123 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, bgc
, 0, 0, 4, 4);
1124 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, wgc
, 1, 1, 2, 2);
1126 readConfiguration(panel
);
1134 WMGetColorPanel(WMScreen
*scrPtr
)
1136 WMColorPanel
*panel
;
1138 if (scrPtr
->sharedColorPanel
)
1139 return scrPtr
->sharedColorPanel
;
1141 panel
= makeColorPanel(scrPtr
, "colorPanel");
1143 scrPtr
->sharedColorPanel
= panel
;
1150 WMFreeColorPanel(WMColorPanel
*panel
)
1152 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1154 if (panel
== scr
->sharedColorPanel
) {
1155 scr
->sharedColorPanel
= NULL
;
1161 WMRemoveNotificationObserver(panel
);
1162 WMUnmapWidget(panel
->win
);
1165 WMReleaseFont(panel
->font8
);
1166 WMReleaseFont(panel
->font12
);
1169 wheelDestroyMatrix(panel
->wheelMtrx
);
1170 if (panel
->wheelImg
)
1171 XFreePixmap(scr
->display
, panel
->wheelImg
);
1172 if (panel
->selectionImg
)
1173 XFreePixmap(scr
->display
, panel
->selectionImg
);
1174 if (panel
->selectionBackImg
)
1175 XFreePixmap(scr
->display
, panel
->selectionBackImg
);
1176 RReleaseImage(panel
->customPaletteImg
);
1179 if (panel
->lastBrowseDir
)
1180 wfree(panel
->lastBrowseDir
);
1181 if (panel
->configurationPath
)
1182 wfree(panel
->configurationPath
);
1184 WMDestroyWidget(panel
->win
);
1191 WMCloseColorPanel(WMColorPanel
*panel
)
1193 WMFreeColorPanel(panel
);
1198 WMShowColorPanel(WMColorPanel
*panel
)
1200 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1201 WMColor
*white
= WMWhiteColor(scr
);
1203 if (panel
->color
.set
== cpNone
)
1204 WMSetColorPanelColor(panel
, white
);
1205 WMReleaseColor(white
);
1207 if (panel
->mode
!= WMWheelModeColorPanel
)
1208 WMPerformButtonClick(panel
->wheelBtn
);
1210 WMMapWidget(panel
->win
);
1215 closeWindowCallback(WMWidget
*w
, void *data
)
1217 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
1219 WMCloseColorPanel(panel
);
1224 readConfiguration(W_ColorPanel
*panel
)
1226 /* XXX Doesn't take care of "invalid" files */
1230 struct stat stat_buf
;
1233 if (stat(panel
->configurationPath
, &stat_buf
)!=0) {
1234 if (mkdir(panel
->configurationPath
,
1235 S_IRWXU
|S_IRGRP
|S_IROTH
|S_IXGRP
|S_IXOTH
)!=0) {
1236 wsyserror(_("Color Panel: Could not create directory %s needed"
1237 " to store configurations"), panel
->configurationPath
);
1238 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1239 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1240 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1241 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1243 _("Could not create ColorPanel configuration directory"),
1244 _("OK"), NULL
, NULL
);
1249 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1250 wwarning(_("Color Panel: Could not find file"), "%s", panel
->configurationPath
);
1254 while ((dp
= readdir(dPtr
)) != NULL
) {
1255 unsigned int perm_mask
;
1256 char *path
= wstrconcat(panel
->configurationPath
,
1259 if (dp
->d_name
[0] != '.') {
1260 item
= WMGetPopUpButtonNumberOfItems(
1261 panel
->customPaletteHistoryBtn
);
1262 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1264 perm_mask
= (access(path
, R_OK
) == 0);
1265 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
,
1270 (void)closedir(dPtr
);
1275 readXColors(W_ColorPanel
*panel
)
1277 struct stat stat_buf
;
1279 char line
[MAX_LENGTH
];
1280 int red
, green
, blue
;
1285 if (stat(RGBTXT
, &stat_buf
) != 0) {
1286 wsyserror(_("Color Panel: Could not find file"), " %s", RGBTXT
);
1290 if ((rgbtxt
= fopen(RGBTXT
, "rb"))) {
1291 while (fgets(line
, MAX_LENGTH
, rgbtxt
)) {
1292 if (sscanf(line
, "%d%d%d %[^\n]", &red
, &green
, &blue
, name
)) {
1293 color
= wmalloc(sizeof(RColor
));
1294 color
->red
= (unsigned char)red
;
1295 color
->green
= (unsigned char)green
;
1296 color
->blue
= (unsigned char)blue
;
1297 item
= WMAddListItem(panel
->colorListContentLst
, name
);
1298 item
->clientData
= (void *)color
;
1304 wsyserror(_("Color Panel: Could not find file"), "%s", RGBTXT
);
1311 WMSetColorPanelPickerMode(WMColorPanel
*panel
, WMColorPanelMode mode
)
1313 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1315 if (mode
!= WMWheelModeColorPanel
) {
1316 WMUnmapWidget(panel
->wheelFrm
);
1317 if (panel
->selectionBackImg
) {
1318 XFreePixmap(WMWidgetScreen(panel
->win
)->display
,
1319 panel
->selectionBackImg
);
1320 panel
->selectionBackImg
= None
;
1323 if (mode
!= WMGrayModeColorPanel
)
1324 WMUnmapWidget(panel
->grayFrm
);
1325 if (mode
!= WMRGBModeColorPanel
)
1326 WMUnmapWidget(panel
->rgbFrm
);
1327 if (mode
!= WMCMYKModeColorPanel
)
1328 WMUnmapWidget(panel
->cmykFrm
);
1329 if (mode
!= WMHSBModeColorPanel
)
1330 WMUnmapWidget(panel
->hsbFrm
);
1331 if (mode
!= WMCustomPaletteModeColorPanel
) {
1332 WMUnmapWidget(panel
->customPaletteFrm
);
1333 if (panel
->selectionBackImg
) {
1334 XFreePixmap(WMWidgetScreen(panel
->win
)->display
,
1335 panel
->selectionBackImg
);
1336 panel
->selectionBackImg
= None
;
1339 if (mode
!= WMColorListModeColorPanel
)
1340 WMUnmapWidget(panel
->colorListFrm
);
1341 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1342 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1343 WMUnmapWidget(panel
->slidersFrm
);
1345 panel
->slidersmode
= mode
;
1347 if (mode
== WMWheelModeColorPanel
) {
1348 WMMapWidget(panel
->wheelFrm
);
1349 WMSetButtonSelected(panel
->wheelBtn
, True
);
1350 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1354 } else if (mode
== WMGrayModeColorPanel
) {
1355 WMMapWidget(panel
->slidersFrm
);
1356 WMSetButtonSelected(panel
->slidersBtn
, True
);
1357 WMMapWidget(panel
->grayFrm
);
1358 WMSetButtonSelected(panel
->grayBtn
, True
);
1359 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1360 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1362 } else if (mode
== WMRGBModeColorPanel
) {
1363 WMMapWidget(panel
->slidersFrm
);
1364 WMSetButtonSelected(panel
->slidersBtn
, True
);
1365 WMMapWidget(panel
->rgbFrm
);
1366 WMSetButtonSelected(panel
->rgbBtn
, True
);
1367 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1368 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1370 } else if (mode
== WMCMYKModeColorPanel
) {
1371 WMMapWidget(panel
->slidersFrm
);
1372 WMSetButtonSelected(panel
->slidersBtn
, True
);
1373 WMMapWidget(panel
->cmykFrm
);
1374 WMSetButtonSelected(panel
->cmykBtn
, True
);
1375 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1376 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1378 } else if (mode
== WMHSBModeColorPanel
) {
1379 WMMapWidget(panel
->slidersFrm
);
1380 WMSetButtonSelected(panel
->slidersBtn
, True
);
1381 WMMapWidget(panel
->hsbFrm
);
1382 WMSetButtonSelected(panel
->hsbBtn
, True
);
1383 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1384 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1386 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1387 WMMapWidget(panel
->customPaletteFrm
);
1388 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1389 customSetPalette(panel
);
1390 } else if (mode
== WMColorListModeColorPanel
) {
1391 WMMapWidget(panel
->colorListFrm
);
1392 WMSetButtonSelected(panel
->colorListBtn
, True
);
1400 WMGetColorPanelColor(WMColorPanel
*panel
)
1402 return WMGetColorWellColor(panel
->colorWell
);
1407 WMSetColorPanelColor(WMColorPanel
*panel
, WMColor
*color
)
1409 WMSetColorWellColor(panel
->colorWell
, color
);
1411 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1412 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1413 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1414 panel
->color
.set
= cpRGB
;
1416 if (panel
->mode
== panel
->lastChanged
)
1417 panel
->lastChanged
= 0;
1419 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1424 updateSwatch(WMColorPanel
*panel
, CPColor color
)
1426 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1429 if (color
.set
!= cpRGB
)
1430 convertCPColor(&color
);
1432 panel
->color
= color
;
1434 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8,
1435 color
.rgb
.green
<< 8,
1436 color
.rgb
.blue
<< 8, True
);
1438 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1439 WMReleaseColor(wellcolor
);
1441 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1443 (*panel
->action
)(panel
, panel
->clientData
);
1445 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
,
1451 modeButtonCallback(WMWidget
*w
, void *data
)
1453 W_ColorPanel
*panel
= (W_ColorPanel
*)(data
);
1455 if (w
== panel
->wheelBtn
)
1456 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1457 else if (w
== panel
->slidersBtn
)
1458 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1459 else if (w
== panel
->customPaletteBtn
)
1460 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1461 else if (w
== panel
->colorListBtn
)
1462 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1463 else if (w
== panel
->grayBtn
)
1464 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1465 else if (w
== panel
->rgbBtn
)
1466 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1467 else if (w
== panel
->cmykBtn
)
1468 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1469 else if (w
== panel
->hsbBtn
)
1470 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1474 /****************** Magnifying Cursor Functions *******************/
1477 magnifyGetImage(WMScreen
*scr
, XImage
*image
, int x
, int y
, int w
, int h
)
1479 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1480 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1481 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1483 if (!(image
&& image
->data
)) {
1484 /* The image in panel->magnifyGlass->image does not exist yet.
1485 * Grab one from the screen (not beyond) and use it from now on.
1487 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1490 w
, h
, AllPlanes
, ZPixmap
)))
1491 wwarning(_("Color Panel: X failed request"));
1496 /* Coordinate correction for back pixmap
1497 * if magnifying glass is at screen-borders
1500 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1501 * Hatched area is beyond screen border.
1503 * |<-Cursor_x_hot->|
1504 * ________________|_____
1505 * |/ / / / / / /| | |
1506 * | / / / / / / |(x,y) |
1507 * |/_/_/_/_/_/_/|________|
1508 * |<----x0----->|<--w0-->|
1512 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1514 * Hatched area is beyond screen border
1516 * |<-Cursor_x_hot->|
1517 * ________________|_______________
1518 * | | | / / / / / /|
1519 * | (x,y)|/ / / / / / |
1520 * |___________________|_/_/_/_/_/_/|
1521 * |<-------w0-------->| |
1522 * |<---------------w--|----------->|
1527 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1528 x0
= Cursor_x_hot
- x
;
1532 if (displayWidth
-1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1533 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1536 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1537 y0
= Cursor_y_hot
- y
;
1541 if (displayHeight
-1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1542 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1544 /* end of coordinate correction */
1547 /* Grab an image from the screen, clipped if necessary,
1548 * and put it in the existing panel->magnifyGlass->image
1549 * with the corresponding clipping offset.
1551 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1552 x
- Cursor_x_hot
+ x0
,
1553 y
- Cursor_y_hot
+ y0
,
1554 w0
, h0
, AllPlanes
, ZPixmap
,
1556 wwarning(_("Color Panel: X failed request"));
1563 magnifyGetImageStored(WMColorPanel
*panel
, int x1
, int y1
, int x2
, int y2
)
1565 /* (x1, y1) = topleft corner of existing rectangle
1566 * (x2, y2) = topleft corner of new position
1569 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1570 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1572 const int dx
= abs(x2
- x1
),
1575 const int x_min
= Cursor_x_hot
,
1576 y_min
= Cursor_y_hot
,
1577 x_max
= DisplayWidth(scr
->display
, scr
->screen
) -1 -
1578 (Cursor_mask_width
- Cursor_x_hot
),
1579 y_max
= DisplayHeight(scr
->display
, scr
->screen
) -1 -
1580 (Cursor_mask_height
- Cursor_y_hot
);
1582 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1583 return; /* No movement */
1595 width
= Cursor_mask_width
- dx
;
1596 height
= Cursor_mask_height
- dy
;
1598 /* If the traversed distance is larger than the size of the magnifying
1599 * glass contents, there is no need to do dirty rectangles. A whole new
1600 * rectangle can be grabbed (unless that rectangle falls partially
1602 * Destroying the image and setting it to NULL will achieve that later on.
1604 * Of course, grabbing an XImage beyond the borders of the screen will
1605 * cause trouble, this is considdered a special case. Part of the screen
1606 * is grabbed, but there is no need for dirty rectangles.
1608 if ((width
<= 0) || (height
<= 0)) {
1609 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1610 if (panel
->magnifyGlass
->image
)
1611 XDestroyImage(panel
->magnifyGlass
->image
);
1612 panel
->magnifyGlass
->image
= NULL
;
1615 if (panel
->magnifyGlass
->image
) {
1616 /* Get dirty rectangle from panel->magnifyGlass->image */
1617 panel
->magnifyGlass
->dirtyRect
=
1618 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1619 if (!panel
->magnifyGlass
->dirtyRect
) {
1620 wwarning(_("Color Panel: X failed request"));
1621 return; /* X returned a NULL from XSubImage */
1626 /* Get image from screen */
1627 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
,
1628 Cursor_mask_width
, Cursor_mask_height
);
1629 if (image
) { /* Only reassign if a *new* image was grabbed */
1630 panel
->magnifyGlass
->image
= image
;
1634 /* Copy previously stored rectangle on covered part of image */
1635 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1638 /* "width" and "height" are used as coordinates here,
1639 * and run from [0...width-1] and [0...height-1] respectively.
1643 old_height
= height
;
1645 for (; width
>= 0; width
--)
1646 for (height
= old_height
; height
>= 0; height
--)
1647 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1648 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1649 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1650 panel
->magnifyGlass
->dirtyRect
= NULL
;
1658 magnifyCreatePixmap(WMColorPanel
*panel
)
1660 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1665 unsigned long color
;
1667 if (!panel
->magnifyGlass
->image
)
1670 if (!panel
->magnifyGlass
->magPix
)
1674 * Copy an area of only 5x5 pixels from the center of the image.
1676 for (u
= 0; u
< 5; u
++) {
1677 for (v
= 0; v
< 5; v
++) {
1678 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1680 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1682 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1683 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1685 /* The center square must eventually be centered around the
1686 * hotspot. The image needs shifting to achieve this. The amount of
1687 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1690 * ^------- center of center square == Cursor_x_hot
1692 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1694 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1695 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1700 return panel
->magnifyGlass
->magPix
;
1702 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
,
1703 Cursor_mask_height
, scr
->depth
);
1707 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1708 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1710 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1711 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1712 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1713 /* (2,2) puts center pixel on center of glass */
1722 magnifyCreateView(W_ColorPanel
*panel
)
1724 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1727 magView
= W_CreateTopView(scr
);
1731 magView
->self
= panel
->win
;
1732 magView
->flags
.topLevel
= 1;
1733 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1734 magView
->attribs
.override_redirect
= True
;
1735 magView
->attribs
.save_under
= True
;
1737 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1739 W_RealizeView(magView
);
1746 magnifyGrabPointer(W_ColorPanel
*panel
)
1748 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1749 Pixmap magPixmap
, magPixmap2
;
1751 XColor fgColor
= {0, 0,0,0, DoRed
|DoGreen
|DoBlue
};
1752 XColor bgColor
= {0, 0xbf00, 0xa000, 0x5000, DoRed
|DoGreen
|DoBlue
};
1754 /* Cursor creation stuff */
1755 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1756 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1757 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1758 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1760 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1761 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1763 XFreePixmap(scr
->display
, magPixmap
);
1764 XFreePixmap(scr
->display
, magPixmap2
);
1766 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1768 /* Set up Pointer */
1769 XGrabPointer (scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1770 PointerMotionMask
| ButtonPressMask
,
1771 GrabModeAsync
, GrabModeAsync
,
1772 scr
->rootWin
, magCursor
, CurrentTime
);
1779 magnifyInitialize(W_ColorPanel
*panel
)
1781 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1784 Pixmap pixmap
, clip_mask
;
1786 Window root_return
, child_return
;
1788 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1789 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1791 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1792 5*5 -1, 5*5 -1, scr
->depth
);
1794 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
,
1795 &x
, &y
, &u
, &v
, &mask
);
1797 panel
->magnifyGlass
->image
= NULL
;
1799 /* Clipmask to make magnified view-contents circular */
1801 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1802 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1804 /* Clip circle in glass cursor */
1805 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1806 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1809 XFreePixmap(scr
->display
, clip_mask
);
1811 /* Draw initial magnifying glass contents */
1812 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1814 pixmap
= magnifyCreatePixmap(panel
);
1815 XSetWindowBackgroundPixmap(scr
->display
,
1816 WMViewXID(panel
->magnifyGlass
->view
),
1818 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1819 XFlush(scr
->display
);
1822 XFreePixmap(scr
->display
, pixmap
);
1833 magnifyPutCursor(WMWidget
*w
, void *data
)
1835 W_ColorPanel
*panel
= (W_ColorPanel
*)(data
);
1836 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1840 WMPoint initialPosition
;
1842 /* Destroy wheelBackImg, so it'll update properly */
1843 if (panel
->selectionBackImg
) {
1844 XFreePixmap(WMWidgetScreen(panel
->win
)->display
,
1845 panel
->selectionBackImg
);
1846 panel
->selectionBackImg
= None
;
1849 /* Create magnifying glass */
1850 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1851 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1852 if (!panel
->magnifyGlass
->view
)
1855 initialPosition
= magnifyInitialize(panel
);
1856 panel
->magnifyGlass
->x
= initialPosition
.x
;
1857 panel
->magnifyGlass
->y
= initialPosition
.y
;
1859 W_MoveView(panel
->magnifyGlass
->view
,
1860 panel
->magnifyGlass
->x
- Cursor_x_hot
,
1861 panel
->magnifyGlass
->y
- Cursor_y_hot
);
1862 W_MapView(panel
->magnifyGlass
->view
);
1864 magCursor
= magnifyGrabPointer(panel
);
1866 while (panel
->magnifyGlass
->image
)
1868 WMNextEvent(scr
->display
, &event
);
1870 /* Pack motion events */
1871 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1877 XDestroyImage(panel
->magnifyGlass
->image
);
1878 panel
->magnifyGlass
->image
= NULL
;
1880 if (event
.xbutton
.button
== Button1
) {
1881 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1882 panel
->color
.set
= cpRGB
;
1883 updateSwatch(panel
, panel
->color
);
1885 switch (panel
->mode
) {
1886 case WMWheelModeColorPanel
:
1891 case WMGrayModeColorPanel
:
1894 case WMRGBModeColorPanel
:
1897 case WMCMYKModeColorPanel
:
1900 case WMHSBModeColorPanel
:
1906 panel
->lastChanged
= panel
->mode
;
1908 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1912 while (XPending(event
.xmotion
.display
)) {
1914 XPeekEvent(event
.xmotion
.display
, &ev
);
1915 if (ev
.type
== MotionNotify
)
1916 XNextEvent(event
.xmotion
.display
, &event
);
1921 /* Get a "dirty rectangle" */
1922 magnifyGetImageStored( panel
,
1923 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1924 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1926 /* Update coordinates */
1927 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1928 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1931 W_MoveView(panel
->magnifyGlass
->view
,
1932 panel
->magnifyGlass
->x
- Cursor_x_hot
,
1933 panel
->magnifyGlass
->y
- Cursor_y_hot
);
1935 /* Put new image (with magn.) in view */
1936 pixmap
= magnifyCreatePixmap(panel
);
1937 if (pixmap
!= None
) {
1938 /* Change the window background */
1939 XSetWindowBackgroundPixmap(scr
->display
,
1940 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1941 /* Force an Expose (handled by X) */
1942 XClearWindow(scr
->display
,
1943 WMViewXID(panel
->magnifyGlass
->view
));
1944 /* Synchronize the event queue, so the Expose is handled NOW */
1945 XFlush(scr
->display
);
1947 XFreePixmap(scr
->display
, pixmap
);
1952 /* Try XQueryPointer for this !!! It returns windows that the pointer
1953 * is over. Note: We found this solving the invisible donkey cap bug
1955 #if 0 /* As it is impossible to make this work in all cases,
1956 * we consider it confusing. Therefore we disabled it.
1958 case FocusOut
: /* fall through */
1961 * Color Panel window (panel->win) lost or received focus.
1962 * We need to update the pixmap in the magnifying glass.
1964 * BUG Doesn't work with focus switches between two windows
1965 * if none of them is the color panel.
1967 XUngrabPointer(scr
->display
, CurrentTime
);
1968 W_UnmapView(panel
->magnifyGlass
->view
);
1970 magnifyInitialize(panel
);
1972 W_MapView(panel
->magnifyGlass
->view
);
1973 XGrabPointer (scr
->display
, panel
->magnifyGlass
->view
->window
,
1974 True
, PointerMotionMask
| ButtonPressMask
,
1975 GrabModeAsync
, GrabModeAsync
,
1976 scr
->rootWin
, magCursor
, CurrentTime
);
1980 WMHandleEvent(&event
);
1985 XUngrabPointer(scr
->display
, CurrentTime
);
1986 XFreeCursor(scr
->display
, magCursor
);
1988 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1989 panel
->magnifyGlass
->magPix
= None
;
1991 W_UnmapView(panel
->magnifyGlass
->view
);
1992 W_DestroyView(panel
->magnifyGlass
->view
);
1993 panel
->magnifyGlass
->view
= NULL
;
1995 wfree(panel
->magnifyGlass
);
2000 /****************** ColorWheel Functions ************************/
2003 wheelCreateMatrix(unsigned int width
, unsigned int height
)
2005 wheelMatrix
*matrix
= NULL
;
2008 assert((width
> 0) && (height
> 0));
2010 matrix
= wmalloc(sizeof(wheelMatrix
));
2011 memset(matrix
, 0, sizeof(wheelMatrix
));
2012 matrix
->width
= width
;
2013 matrix
->height
= height
;
2015 for (i
= 0; i
< 3; i
++) {
2016 matrix
->data
[i
] = wmalloc(width
*height
*sizeof(unsigned char));
2024 wheelDestroyMatrix(wheelMatrix
*matrix
)
2031 for (i
= 0; i
< 3; i
++) {
2032 if (matrix
->data
[i
])
2033 wfree(matrix
->data
[i
]);
2040 wheelInitMatrix(W_ColorPanel
*panel
)
2044 unsigned char *rp
, *gp
, *bp
;
2050 const int cw_halfsize
= (colorWheelSize
+ 4)/2,
2051 cw_sqsize
= (colorWheelSize
+4) * (colorWheelSize
+4),
2052 uchar_shift
= getShift(sizeof(unsigned char));
2054 if (!panel
->wheelMtrx
)
2057 cpColor
.hsv
.value
= 255;
2058 cpColor
.set
= cpHSV
;
2061 ofs
[1] = -(colorWheelSize
+ 4);
2063 /* offsets are counterclockwise (in triangles).
2066 * _______________________________________
2067 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
2068 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
2069 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
2070 * o | | | | | | | | | | | | | | | | | | | | | [3]
2074 * |\ /| <-- triangles
2080 for (y
= 0; y
< cw_halfsize
; y
++) {
2081 for (x
= y
; x
< (colorWheelSize
+4-y
); x
++) {
2082 /* (xcor, ycor) is (x,y) relative to center of matrix */
2083 xcor
= 2 * x
- 4 - colorWheelSize
;
2084 ycor
= 2 * y
- 4 - colorWheelSize
;
2086 /* RColor.saturation is unsigned char and will wrap after 255 */
2087 sat
= rint(255.0 * sqrt(xcor
*xcor
+ ycor
*ycor
) / colorWheelSize
);
2089 cpColor
.hsv
.saturation
= (unsigned char)sat
;
2091 ofs
[0]++; /* top quarter of matrix*/
2092 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
2093 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
2094 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
2098 dhue
[0] = rint(atan((double)ycor
/ (double)xcor
) *
2099 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
2103 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
2104 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
2105 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
2106 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
2108 for (i
= 0; i
< 4; i
++) {
2109 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
2110 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
2111 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
2113 cpColor
.hsv
.hue
= dhue
[i
];
2114 convertCPColor(&cpColor
);
2116 *rp
= (unsigned char)(cpColor
.rgb
.red
);
2117 *gp
= (unsigned char)(cpColor
.rgb
.green
);
2118 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
2122 for (i
= 0; i
< 4; i
++) {
2123 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
2124 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
2125 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
2127 *rp
= (unsigned char)0;
2128 *gp
= (unsigned char)0;
2129 *bp
= (unsigned char)0;
2135 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2*y
);
2141 wheelCalculateValues(W_ColorPanel
*panel
, int maxvalue
)
2146 for (i
= 0; i
< 256; i
++) {
2147 /* We divide by 128 in advance, and check whether that number divides
2148 * by 2 properly. If not, we add one to round the number correctly
2150 v
= (i
*maxvalue
) >> 7;
2151 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) +(v
& 0x01));
2157 wheelRender(W_ColorPanel
*panel
)
2159 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2164 unsigned long ofs
= 0;
2165 /*unsigned char shift = getShift(sizeof(unsigned char));*/
2167 image
= RCreateImage(colorWheelSize
+4, colorWheelSize
+4, True
);
2169 wwarning(_("Color Panel: Could not allocate memory"));
2175 /* TODO Make this transparent istead of gray */
2176 gray
.red
= gray
.blue
= 0xae; gray
.green
= 0xaa;
2178 for (y
= 0; y
< colorWheelSize
+4; y
++) {
2179 for (x
= 0; x
< colorWheelSize
+4; x
++) {
2180 if (wheelInsideColorWheel(panel
, ofs
)) {
2181 *(ptr
++) = (unsigned char)(panel
->wheelMtrx
->values
[
2182 panel
->wheelMtrx
->data
[0][ofs
] ]);
2183 *(ptr
++) = (unsigned char)(panel
->wheelMtrx
->values
[
2184 panel
->wheelMtrx
->data
[1][ofs
] ]);
2185 *(ptr
++) = (unsigned char)(panel
->wheelMtrx
->values
[
2186 panel
->wheelMtrx
->data
[2][ofs
] ]);
2190 *(ptr
++) = (unsigned char)(gray
.red
);
2191 *(ptr
++) = (unsigned char)(gray
.green
);
2192 *(ptr
++) = (unsigned char)(gray
.blue
);
2199 if (panel
->wheelImg
)
2200 XFreePixmap(scr
->display
, panel
->wheelImg
);
2202 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2203 RReleaseImage(image
);
2205 /* Check if backimage exists. If it doesn't, allocate and fill it */
2206 if (!panel
->selectionBackImg
) {
2207 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2208 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2209 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2210 scr
->copyGC
, panel
->colx
-2, panel
->coly
-2, 4, 4, 0, 0);
2211 /* -2 is hot spot correction */
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(- (double)ycor
/ (double)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 convertCPColor(&topColor
);
2475 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2476 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
),
2478 RReleaseImage(sliderImg
);
2479 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2480 WMReleasePixmap(sliderPxmp
);
2483 /****************** Grayscale Panel Functions ***************/
2486 grayBrightnessSliderCallback(WMWidget
*w
, void *data
)
2491 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2493 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2495 sprintf(tmp
, "%d", value
);
2497 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2498 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55*value
);
2499 cpColor
.set
= cpRGB
;
2501 updateSwatch(panel
, cpColor
);
2502 panel
->lastChanged
= WMGrayModeColorPanel
;
2506 grayPresetButtonCallback(WMWidget
*w
, void *data
)
2512 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2515 if (w
== panel
->grayPresetBtn
[i
])
2520 value
= rint((100.0*i
)/6.0);
2521 sprintf(tmp
, "%d", value
);
2523 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2524 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
=
2525 rint((255.0*i
)/6.0);
2526 cpColor
.set
= cpRGB
;
2528 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0*i
)/6.0));
2530 updateSwatch(panel
, cpColor
);
2531 panel
->lastChanged
= WMGrayModeColorPanel
;
2535 grayBrightnessTextFieldCallback(void *observerData
,
2536 WMNotification
*notification
)
2541 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2543 value
= atoi(WMGetTextFieldText(panel
->grayBrightnessT
));
2549 sprintf(tmp
, "%d", value
);
2550 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2551 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2553 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
=
2554 rint((255.0*value
)/100.0);
2555 cpColor
.set
= cpRGB
;
2557 updateSwatch(panel
, cpColor
);
2558 panel
->lastChanged
= WMGrayModeColorPanel
;
2561 /******************* RGB Panel Functions *****************/
2564 rgbSliderCallback(WMWidget
*w
, void *data
)
2569 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2571 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2572 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2573 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2575 sprintf(tmp
, "%d", value
[0]);
2576 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2577 sprintf(tmp
, "%d", value
[1]);
2578 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2579 sprintf(tmp
, "%d", value
[2]);
2580 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2582 cpColor
.rgb
.red
= value
[0];
2583 cpColor
.rgb
.green
= value
[1];
2584 cpColor
.rgb
.blue
= value
[2];
2585 cpColor
.set
= cpRGB
;
2587 updateSwatch(panel
, cpColor
);
2588 panel
->lastChanged
= WMRGBModeColorPanel
;
2592 rgbTextFieldCallback(void *observerData
, WMNotification
*notification
)
2598 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2600 value
[0] = atoi(WMGetTextFieldText(panel
->rgbRedT
));
2601 value
[1] = atoi(WMGetTextFieldText(panel
->rgbGreenT
));
2602 value
[2] = atoi(WMGetTextFieldText(panel
->rgbBlueT
));
2604 for (n
=0; n
< 3; n
++) {
2611 sprintf(tmp
, "%d", value
[0]);
2612 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2613 sprintf(tmp
, "%d", value
[1]);
2614 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2615 sprintf(tmp
, "%d", value
[2]);
2616 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2618 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2619 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2620 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2622 cpColor
.rgb
.red
= value
[0];
2623 cpColor
.rgb
.green
= value
[1];
2624 cpColor
.rgb
.blue
= value
[2];
2625 cpColor
.set
= cpRGB
;
2627 updateSwatch(panel
, cpColor
);
2628 panel
->lastChanged
= WMRGBModeColorPanel
;
2632 /******************* CMYK Panel Functions *****************/
2635 cmykSliderCallback(WMWidget
*w
, void *data
)
2640 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2643 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2644 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2645 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2646 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2648 sprintf(tmp
, "%d", value
[0]);
2649 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2650 sprintf(tmp
, "%d", value
[1]);
2651 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2652 sprintf(tmp
, "%d", value
[2]);
2653 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2654 sprintf(tmp
, "%d", value
[3]);
2655 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2657 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2658 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2659 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2660 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2661 cpColor
.set
= cpRGB
;
2663 updateSwatch(panel
, cpColor
);
2664 panel
->lastChanged
= WMCMYKModeColorPanel
;
2668 cmykTextFieldCallback(void *observerData
, WMNotification
*notification
)
2675 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2677 value
[0] = atoi(WMGetTextFieldText(panel
->cmykCyanT
));
2678 value
[1] = atoi(WMGetTextFieldText(panel
->cmykMagentaT
));
2679 value
[2] = atoi(WMGetTextFieldText(panel
->cmykYellowT
));
2680 value
[3] = atoi(WMGetTextFieldText(panel
->cmykBlackT
));
2682 for (n
=0; n
< 4; n
++) {
2689 sprintf(tmp
, "%d", value
[0]);
2690 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2692 sprintf(tmp
, "%d", value
[1]);
2693 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2695 sprintf(tmp
, "%d", value
[2]);
2696 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2698 sprintf(tmp
, "%d", value
[3]);
2699 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2701 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2702 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2703 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2704 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2706 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2707 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2708 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2709 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2710 cpColor
.set
= cpRGB
;
2712 updateSwatch(panel
, cpColor
);
2713 panel
->lastChanged
= WMCMYKModeColorPanel
;
2716 /********************** HSB Panel Functions ***********************/
2719 hsbSliderCallback(WMWidget
*w
, void *data
)
2724 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2726 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2727 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2728 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2730 sprintf(tmp
, "%d", value
[0]);
2731 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2732 sprintf(tmp
, "%d", value
[1]);
2733 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2734 sprintf(tmp
, "%d", value
[2]);
2735 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2737 cpColor
.hsv
.hue
= value
[0];
2738 cpColor
.hsv
.saturation
= value
[1]*2.55;
2739 cpColor
.hsv
.value
= value
[2]*2.55;
2740 cpColor
.set
= cpHSV
;
2742 convertCPColor(&cpColor
);
2744 panel
->lastChanged
= WMHSBModeColorPanel
;
2745 updateSwatch(panel
, cpColor
);
2747 if (w
!= panel
->hsbBrightnessS
)
2748 hsbUpdateBrightnessGradient(panel
);
2749 if (w
!= panel
->hsbSaturationS
)
2750 hsbUpdateSaturationGradient(panel
);
2751 if (w
!= panel
->hsbHueS
)
2752 hsbUpdateHueGradient(panel
);
2756 hsbTextFieldCallback(void *observerData
, WMNotification
*notification
)
2762 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2764 value
[0] = atoi(WMGetTextFieldText(panel
->hsbHueT
));
2765 value
[1] = atoi(WMGetTextFieldText(panel
->hsbSaturationT
));
2766 value
[2] = atoi(WMGetTextFieldText(panel
->hsbBrightnessT
));
2773 for (n
=1; n
< 3; n
++) {
2780 sprintf(tmp
, "%d", value
[0]);
2781 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2782 sprintf(tmp
, "%d", value
[1]);
2783 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2784 sprintf(tmp
, "%d", value
[2]);
2785 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2787 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2788 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2789 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2791 cpColor
.hsv
.hue
= value
[0];
2792 cpColor
.hsv
.saturation
= value
[1]*2.55;
2793 cpColor
.hsv
.value
= value
[2]*2.55;
2794 cpColor
.set
= cpHSV
;
2796 convertCPColor(&cpColor
);
2798 panel
->lastChanged
= WMHSBModeColorPanel
;
2799 updateSwatch(panel
, cpColor
);
2801 hsbUpdateBrightnessGradient(panel
);
2802 hsbUpdateSaturationGradient(panel
);
2803 hsbUpdateHueGradient(panel
);
2807 hsbUpdateBrightnessGradient(W_ColorPanel
*panel
)
2809 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2813 WMPixmap
*sliderPxmp
;
2815 from
.red
= from
.green
= from
.blue
= 0;
2816 to
.hsv
= panel
->color
.hsv
;
2820 convertCPColor(&to
);
2822 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2823 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2824 RReleaseImage(sliderImg
);
2827 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2828 panel
->font12
, 2, 0, 100, WALeft
, scr
->white
,
2829 False
, _("Brightness"), strlen(_("Brightness")));
2831 wwarning(_("Color Panel: Could not allocate memory"));
2833 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2834 WMReleasePixmap(sliderPxmp
);
2838 hsbUpdateSaturationGradient(W_ColorPanel
*panel
)
2840 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2844 WMPixmap
*sliderPxmp
;
2846 from
.hsv
= panel
->color
.hsv
;
2847 from
.hsv
.saturation
= 0;
2849 convertCPColor(&from
);
2851 to
.hsv
= panel
->color
.hsv
;
2852 to
.hsv
.saturation
= 255;
2854 convertCPColor(&to
);
2856 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
),
2858 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2859 RReleaseImage(sliderImg
);
2862 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2863 panel
->font12
, 2, 0, 100, WALeft
,
2864 from
.hsv
.value
< 128 ? scr
->white
: scr
->black
, False
,
2865 _("Saturation"), strlen(_("Saturation")));
2867 wwarning(_("Color Panel: Could not allocate memory"));
2869 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2870 WMReleasePixmap(sliderPxmp
);
2874 hsbUpdateHueGradient(W_ColorPanel
*panel
)
2876 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2877 RColor
**colors
= NULL
;
2880 WMPixmap
*sliderPxmp
;
2883 hsvcolor
= panel
->color
.hsv
;
2885 colors
= wmalloc(sizeof(RColor
*)*(8));
2886 for (i
=0; i
<7; i
++) {
2887 hsvcolor
.hue
= (360*i
)/6;
2888 colors
[i
] = wmalloc(sizeof(RColor
));
2889 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2893 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2894 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2895 RReleaseImage(sliderImg
);
2898 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2899 panel
->font12
, 2, 0, 100, WALeft
,
2900 hsvcolor
.value
< 128 ? scr
->white
: scr
->black
, False
,
2901 _("Hue"), strlen(_("Hue")));
2903 wwarning(_("Color Panel: Could not allocate memory"));
2905 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2906 WMReleasePixmap(sliderPxmp
);
2914 /*************** Custom Palette Functions ****************/
2917 customRenderSpectrum(W_ColorPanel
*panel
)
2924 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, False
);
2926 ptr
= spectrum
->data
;
2928 for (y
= 0; y
< SPECTRUM_HEIGHT
; y
++) {
2929 cpColor
.hsv
.hue
= y
;
2930 cpColor
.hsv
.saturation
= 0;
2931 cpColor
.hsv
.value
= 255;
2932 cpColor
.set
= cpHSV
;
2934 for (x
= 0; x
< SPECTRUM_WIDTH
; x
++) {
2935 convertCPColor(&cpColor
);
2937 *(ptr
++) = (unsigned char)cpColor
.rgb
.red
;
2938 *(ptr
++) = (unsigned char)cpColor
.rgb
.green
;
2939 *(ptr
++) = (unsigned char)cpColor
.rgb
.blue
;
2941 if (x
< (SPECTRUM_WIDTH
/2))
2942 cpColor
.hsv
.saturation
++;
2944 if (x
> (SPECTRUM_WIDTH
/2))
2945 cpColor
.hsv
.value
--;
2948 if (panel
->customPaletteImg
) {
2949 RReleaseImage(panel
->customPaletteImg
);
2950 panel
->customPaletteImg
= NULL
;
2952 panel
->customPaletteImg
= spectrum
;
2958 customSetPalette(W_ColorPanel
*panel
)
2960 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2965 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
,
2966 customPaletteHeight
, scr
->depth
);
2967 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
,
2968 customPaletteHeight
);
2969 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2970 RReleaseImage(scaledImg
);
2972 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2973 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2975 /* Check backimage exists. If it doesn't, allocate and fill it */
2976 if (!panel
->selectionBackImg
) {
2977 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2978 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2981 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2982 panel
->palx
-2, panel
->paly
-2, 4, 4, 0, 0);
2983 XCopyArea(scr
->display
, panel
->selectionImg
,
2984 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0 , 0, 4, 4,
2985 panel
->palx
-2, panel
->paly
-2);
2986 XFreePixmap(scr
->display
, image
);
2988 panel
->palXRatio
= (double)(panel
->customPaletteImg
->width
) /
2989 (double)(customPaletteWidth
);
2990 panel
->palYRatio
= (double)(panel
->customPaletteImg
->height
) /
2991 (double)(customPaletteHeight
);
2993 item
= WMGetPopUpButtonSelectedItem (panel
->customPaletteHistoryBtn
);
2998 customPalettePositionSelection(W_ColorPanel
*panel
, int x
, int y
)
3000 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3004 /* undraw selection */
3005 XCopyArea(scr
->display
, panel
->selectionBackImg
,
3006 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
3007 panel
->palx
-2, panel
->paly
-2);
3012 ofs
= (rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) *
3013 panel
->customPaletteImg
->width
) * 3;
3015 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[ofs
];
3016 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[ofs
+1];
3017 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[ofs
+2];
3018 panel
->color
.set
= cpRGB
;
3020 updateSwatch(panel
, panel
->color
);
3021 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
3023 /* Redraw color selector (and make a backup of the part it will cover) */
3024 XCopyArea(scr
->display
, panel
->customPaletteContentView
->window
,
3025 panel
->selectionBackImg
, scr
->copyGC
, panel
->palx
-2, panel
->paly
-2,
3026 4, 4, 0, 0); /* "-2" is correction for hotspot location */
3027 XCopyArea(scr
->display
, panel
->selectionImg
,
3028 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
3029 panel
->palx
-2, panel
->paly
-2); /* see above */
3034 customPalettePositionSelectionOutBounds(W_ColorPanel
*panel
, int x
, int y
)
3040 if (x
>= customPaletteWidth
)
3041 x
= customPaletteWidth
-2;
3042 if (y
>= customPaletteHeight
)
3043 y
= customPaletteHeight
-2;
3045 customPalettePositionSelection(panel
, x
, y
);
3050 customPaletteHandleEvents(XEvent
*event
, void *data
)
3052 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3054 switch (event
->type
) {
3056 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
3058 customSetPalette(panel
);
3064 customPaletteHandleActionEvents(XEvent
*event
, void *data
)
3066 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3069 switch (event
->type
) {
3071 x
= event
->xbutton
.x
;
3072 y
= event
->xbutton
.y
;
3074 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
3075 panel
->flags
.dragging
= 1;
3076 customPalettePositionSelection(panel
, x
, y
);
3081 panel
->flags
.dragging
= 0;
3082 if (!panel
->flags
.continuous
) {
3084 (*panel
->action
)(panel
, panel
->clientData
);
3089 x
= event
->xmotion
.x
;
3090 y
= event
->xmotion
.y
;
3092 if (panel
->flags
.dragging
) {
3093 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
3094 customPalettePositionSelection(panel
, x
, y
);
3097 customPalettePositionSelectionOutBounds(panel
, x
, y
);
3105 customPaletteMenuCallback(WMWidget
*w
, void *data
)
3107 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3108 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
3111 case CPmenuNewFromFile
:
3112 customPaletteMenuNewFromFile(panel
);
3115 customPaletteMenuRename(panel
);
3118 customPaletteMenuRemove(panel
);
3122 case CPmenuNewFromClipboard
:
3129 customPaletteMenuNewFromFile(W_ColorPanel
*panel
)
3131 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3132 WMOpenPanel
*browseP
;
3134 char *filename
= NULL
;
3138 RImage
*tmpImg
= NULL
;
3140 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
,"\0") == 0))
3141 spath
= wexpandpath(wgethomedir());
3143 spath
= wexpandpath(panel
->lastBrowseDir
);
3145 browseP
= WMGetOpenPanel(scr
);
3146 WMSetFilePanelCanChooseDirectories(browseP
, 0);
3147 WMSetFilePanelCanChooseFiles(browseP
, 1);
3149 /* Get a filename */
3150 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
3151 _("Open Palette"), RSupportedFileFormats()) ) {
3152 filepath
= WMGetFilePanelFileName(browseP
);
3154 /* Get seperation position between path and filename */
3155 i
= strrchr(filepath
, '/') - filepath
+ 1;
3156 if (i
> strlen(filepath
))
3157 i
= strlen(filepath
);
3159 /* Store last browsed path */
3160 if (panel
->lastBrowseDir
)
3161 wfree(panel
->lastBrowseDir
);
3162 panel
->lastBrowseDir
= wmalloc((i
+1)*sizeof(char));
3163 strncpy(panel
->lastBrowseDir
, filepath
, i
);
3164 panel
->lastBrowseDir
[i
] = '\0';
3166 /* Get filename from path */
3167 filename
= wstrdup(filepath
+ i
);
3169 /* Check for duplicate files, and rename it if there are any */
3170 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3171 while (access (tmp
, F_OK
) == 0) {
3176 newName
= generateNewFilename(filename
);
3180 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3184 /* Copy image to $(gnustepdir)/Library/Colors/ &
3185 * Add filename to history menu */
3186 if (fetchFile (panel
->configurationPath
, filepath
, filename
) == 0) {
3188 /* filepath is a "local" path now the file has been copied */
3190 filepath
= wstrconcat(panel
->configurationPath
, filename
);
3192 /* load the image & add menu entries */
3193 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
3195 if (panel
->customPaletteImg
)
3196 RReleaseImage(panel
->customPaletteImg
);
3197 panel
->customPaletteImg
= tmpImg
;
3199 customSetPalette(panel
);
3200 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
3202 panel
->currentPalette
= WMGetPopUpButtonNumberOfItems(
3203 panel
->customPaletteHistoryBtn
)-1;
3205 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3206 panel
->currentPalette
);
3209 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3211 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
3212 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
3213 _("Invalid file format !"), _("OK"), NULL
, NULL
);
3215 wsyserror(_("can't remove file %s"), tmp
);
3216 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
3217 _("Couldn't remove file from Configuration Directory !"),
3218 _("OK"), NULL
, NULL
);
3225 WMFreeFilePanel(browseP
);
3232 customPaletteMenuRename(W_ColorPanel
*panel
)
3234 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3235 char *toName
= NULL
;
3237 char *toPath
, *fromPath
;
3241 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3242 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3244 toName
= WMRunInputPanel(scr
, panel
->win
, _("Rename"), _("Rename palette to:"),
3245 fromName
, _("OK"), _("Cancel"));
3249 /* As some people do certain stupid things... */
3250 if (strcmp(toName
, fromName
) == 0) {
3255 /* For normal people */
3256 fromPath
= wstrconcat(panel
->configurationPath
, fromName
);
3257 toPath
= wstrconcat(panel
->configurationPath
, toName
);
3259 if (access (toPath
, F_OK
) == 0) {
3260 /* Careful, this palette exists already */
3261 if (WMRunAlertPanel(scr
, panel
->win
, _("Warning"),
3262 _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"),
3264 /* "No" = 0, "Yes" = 1 */
3265 int items
= WMGetPopUpButtonNumberOfItems(
3266 panel
->customPaletteHistoryBtn
);
3270 /* Remove from History list too */
3272 while ((index
< items
) && (strcmp(WMGetPopUpButtonItem(
3273 panel
->customPaletteHistoryBtn
, index
),
3277 if (index
< items
) {
3278 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
,
3293 if ( rename(fromPath
, toPath
) != 0)
3294 wsyserror(_("Couldn't rename palette %s to %s\n"), fromName
, toName
);
3296 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3297 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
,
3300 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3310 customPaletteMenuRemove(W_ColorPanel
*panel
)
3312 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3318 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3320 tmp
= wstrconcat( _("This will permanently remove the palette "),
3321 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3322 text
= wstrconcat( tmp
,
3323 _(".\n\nAre you sure you want to remove this palette ?"));
3326 choice
= WMRunAlertPanel(scr
, panel
->win
, _("Remove"), text
, _("Yes"), _("No"),
3328 /* returns 0 (= "Yes") or 1 (="No") */
3333 tmp
= wstrconcat(panel
->configurationPath
,
3334 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3336 if ( remove(tmp
) == 0) {
3337 /* item-1 always exists */
3338 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3341 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
,
3343 customSetPalette(panel
);
3345 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3348 wsyserror(_("Couldn't remove palette %s\n"), tmp
);
3357 customPaletteHistoryCallback(WMWidget
*w
, void *data
)
3359 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3360 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3364 unsigned char perm_mask
;
3366 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3367 if (item
== panel
->currentPalette
)
3371 customRenderSpectrum(panel
);
3373 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
,
3375 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
,
3378 /* Load file from configpath */
3379 filename
= wstrconcat( panel
->configurationPath
,
3380 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
) );
3382 /* If the file corresponding to the item does not exist,
3383 * remove it from the history list and select the next one.
3385 perm_mask
= (access(filename
, F_OK
) == 0);
3387 /* File does not exist */
3389 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3391 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3392 customPaletteHistoryCallback(w
, data
);
3397 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3399 if (panel
->customPaletteImg
) {
3400 RReleaseImage(panel
->customPaletteImg
);
3401 panel
->customPaletteImg
= NULL
;
3403 panel
->customPaletteImg
= tmp
;
3406 /* If the image is not writable, don't allow removing/renaming */
3407 perm_mask
= (access(filename
, W_OK
) == 0);
3408 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
,
3410 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
,
3415 customSetPalette(panel
);
3417 panel
->currentPalette
= item
;
3420 /************************* ColorList Panel Functions **********************/
3423 colorListPaintItem(WMList
*lPtr
, int index
, Drawable d
, char *text
,
3424 int state
, WMRect
*rect
)
3426 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3427 Display
*dpy
= WMScreenDisplay(scr
);
3428 WMView
*view
= W_VIEW(lPtr
);
3429 RColor color
= *((RColor
*)WMGetListItem(lPtr
, index
)->clientData
);
3430 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3431 int width
, height
, x
, y
;
3434 width
= rect
->size
.width
;
3435 height
= rect
->size
.height
;
3439 if (state
& WLDSSelected
)
3440 XFillRectangle(dpy
, d
, WMColorGC(scr
->white
), x
, y
, width
, height
);
3442 XFillRectangle(dpy
, d
, WMColorGC(view
->backColor
), x
, y
, width
, height
);
3444 fillColor
= WMCreateRGBColor(scr
, color
.red
<<8, color
.green
<<8,
3445 color
.blue
<<8, True
);
3447 XFillRectangle(dpy
, d
, WMColorGC(fillColor
), x
, y
, 15, height
);
3448 WMReleaseColor(fillColor
);
3450 WMDrawString(scr
, d
, scr
->black
, panel
->font12
, x
+18, y
, text
, strlen(text
));
3455 colorListSelect(WMWidget
*w
, void *data
)
3457 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3460 cpColor
.rgb
= *((RColor
*)WMGetListSelectedItem(w
)->clientData
);
3461 cpColor
.set
= cpRGB
;
3463 panel
->lastChanged
= WMColorListModeColorPanel
;
3464 updateSwatch(panel
, cpColor
);
3469 colorListColorMenuCallback(WMWidget
*w
, void *data
)
3471 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3472 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3486 colorListListMenuCallback(WMWidget
*w
, void *data
)
3488 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3489 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3493 /* New Color List */
3494 colorListListMenuNew(panel
);
3505 colorListListMenuNew(W_ColorPanel
*panel
)
3511 /*************** Panel Initialisation Functions *****************/
3514 wheelInit(W_ColorPanel
*panel
)
3518 if (panel
->color
.set
!= cpHSV
)
3519 convertCPColor(&panel
->color
);
3521 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3523 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3524 (1 + ( panel
->color
.hsv
.saturation
/255.0) *
3525 cos( panel
->color
.hsv
.hue
* M_PI
/180.0)));
3526 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3527 (1 + ( panel
->color
.hsv
.saturation
/255.0) *
3528 sin(- panel
->color
.hsv
.hue
*M_PI
/180.0)));
3530 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3532 cpColor
= panel
->color
;
3533 cpColor
.hsv
.value
= 255;
3534 cpColor
.set
= cpHSV
;
3535 wheelUpdateBrightnessGradient(panel
, cpColor
);
3540 grayInit(W_ColorPanel
*panel
)
3545 if (panel
->color
.set
!= cpHSV
)
3546 convertCPColor(&panel
->color
);
3548 value
= rint(panel
->color
.hsv
.value
/2.55);
3549 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3551 sprintf(tmp
, "%d", value
);
3552 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3557 rgbInit(W_ColorPanel
*panel
)
3561 if (panel
->color
.set
!= cpRGB
)
3562 convertCPColor(&panel
->color
);
3564 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3565 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3566 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3568 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3569 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3570 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3571 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3572 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3573 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3578 cmykInit(W_ColorPanel
*panel
)
3583 if (panel
->color
.set
!= cpRGB
)
3584 convertCPColor(&panel
->color
);
3586 value
[0] = rint((255-panel
->color
.rgb
.red
)/2.55);
3587 value
[1] = rint((255-panel
->color
.rgb
.green
)/2.55);
3588 value
[2] = rint((255-panel
->color
.rgb
.blue
)/2.55);
3590 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3591 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3592 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3593 WMSetSliderValue(panel
->cmykBlackS
, 0);
3595 sprintf(tmp
, "%d", value
[0]);
3596 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3597 sprintf(tmp
, "%d", value
[1]);
3598 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3599 sprintf(tmp
, "%d", value
[2]);
3600 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3601 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3606 hsbInit(W_ColorPanel
*panel
)
3611 if (panel
->color
.set
!= cpHSV
)
3612 convertCPColor(&panel
->color
);
3614 value
[0] = panel
->color
.hsv
.hue
;
3615 value
[1] = rint(panel
->color
.hsv
.saturation
/2.55);
3616 value
[2] = rint(panel
->color
.hsv
.value
/2.55);
3618 WMSetSliderValue(panel
->hsbHueS
,value
[0]);
3619 WMSetSliderValue(panel
->hsbSaturationS
,value
[1]);
3620 WMSetSliderValue(panel
->hsbBrightnessS
,value
[2]);
3622 sprintf(tmp
, "%d", value
[0]);
3623 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3624 sprintf(tmp
, "%d", value
[1]);
3625 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3626 sprintf(tmp
, "%d", value
[2]);
3627 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3629 hsbUpdateBrightnessGradient(panel
);
3630 hsbUpdateSaturationGradient(panel
);
3631 hsbUpdateHueGradient(panel
);
3636 /************************** Common utility functions ************************/
3639 fetchFile(char *toPath
, char *srcFile
, char *destFile
)
3646 if ((src
= open(srcFile
, O_RDONLY
|O_BINARY
)) == 0) {
3647 wsyserror(_("Could not open %s"), srcFile
);
3651 tmp
= wstrconcat(toPath
, destFile
);
3652 if ((dest
= open( tmp
, O_RDWR
|O_CREAT
|O_BINARY
, S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
))
3654 wsyserror(_("Could not create %s"), tmp
);
3662 while ((n
= read(src
, buf
, BUFSIZE
)) > 0)
3664 if (write (dest
, buf
, n
) != n
) {
3665 wsyserror(_("Write error on file %s"), destFile
);
3675 generateNewFilename(char *curName
)
3688 if (((ptr
= strrchr(ptr
, '{'))==0) || sscanf(ptr
, "{%i}%c", &n
, &c
)!=1)
3689 return wstrconcat(curName
, " {1}");
3691 baseLen
= ptr
- curName
-1;
3693 newName
= wmalloc(baseLen
+ 16);
3694 strncpy(newName
, curName
, baseLen
);
3695 newName
[baseLen
] = 0;
3697 sprintf(&newName
[baseLen
], " {%i}", n
+1);
3704 convertCPColor(CPColor
*color
)
3706 unsigned short old_hue
= 0;
3708 switch (color
->set
) {
3710 wwarning(_("Color Panel: Color unspecified"));
3713 old_hue
= color
->hsv
.hue
;
3714 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3716 /* In black the hue is undefined, and may change by conversion
3717 * Same for white. */
3719 ((color
->rgb
.red
== 0) &&
3720 (color
->rgb
.green
== 0) &&
3721 (color
->rgb
.blue
== 0)) ||
3722 ((color
->rgb
.red
== 0) &&
3723 (color
->rgb
.green
== 0) &&
3724 (color
->rgb
.blue
== 255))
3726 color
->hsv
.hue
= old_hue
;
3729 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3735 #define ABS_SHIFT(val, shift) \
3736 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3739 ulongToRColor(WMScreen
*scr
, unsigned long value
)
3742 XColor
*xcolor
= NULL
;
3744 if (!(xcolor
= wmalloc(sizeof(XColor
)) )) {
3745 wwarning(_("Color Panel: Could not allocate memory"));
3752 xcolor
->pixel
= value
;
3753 XQueryColor(scr
->display
, scr
->rcontext
->cmap
, xcolor
);
3755 color
.red
= xcolor
->red
>> 8;
3756 color
.green
= xcolor
->green
>> 8;
3757 color
.blue
= xcolor
->blue
>> 8;
3766 getShift(unsigned char value
)
3768 unsigned char i
= -1;
3783 #ifdef SHAPE_WAS_DEFINED
3784 #undef SHAPE_WAS_DEFINED