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 ;-)
18 * - Look at further optimization of colorWheel matrix calculation.
19 * It appears to be rather symmetric in angles of 60 degrees,
20 * while it is optimized in angles of 90 degrees.
21 * - 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
48 # include <X11/extensions/shape.h>
51 char *WMColorPanelColorChangedNotification
= "WMColorPanelColorChangedNotification";
54 * Bitmaps for magnifying glass cursor
58 #define Cursor_x_hot 11
59 #define Cursor_y_hot 11
60 #define Cursor_width 32
61 #define Cursor_height 32
62 static unsigned char Cursor_bits
[] = {
63 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
64 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
65 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
66 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
67 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
68 0x00, 0x08, 0x00, 0x50, 0x00, 0x10, 0x00, 0x88, 0x00, 0x20, 0x00, 0x5c, 0x01, 0xc0, 0x81,
69 0x3b, 0x02, 0x00, 0x7e, 0x70, 0x05, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0xc0, 0x15, 0x00,
70 0x00, 0x80, 0x23, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x5c,
71 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x70
74 /* Cursor shape-mask */
75 #define Cursor_shape_width 32
76 #define Cursor_shape_height 32
77 static unsigned char Cursor_shape_bits
[] = {
78 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
79 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
80 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
81 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
82 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
83 0x00, 0x08, 0x00, 0x70, 0x00, 0x10, 0x00, 0xf8, 0x00, 0x20, 0x00, 0xfc, 0x01, 0xc0, 0x81,
84 0xfb, 0x03, 0x00, 0x7e, 0xf0, 0x07, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xc0, 0x1f, 0x00,
85 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfc,
86 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x70
89 /* Clip-mask for magnified pixels */
90 #define Cursor_mask_width 24
91 #define Cursor_mask_height 24
92 static unsigned char Cursor_mask_bits
[] = {
93 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07,
94 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
95 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
96 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f,
97 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f,
98 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00
101 typedef struct MovingView
{
102 WMView
*view
; /* The view this is all about */
103 XImage
*image
; /* What's under the view */
104 XImage
*dirtyRect
; /* Storage of overlapped image area */
105 Pixmap magPix
; /* Magnified part of pixmap */
106 RColor color
; /* Color of a pixel in the image */
107 int x
, y
; /* Position of view */
110 typedef struct CPColor
{
111 RColor rgb
; /* The RGB values of the color */
112 RHSVColor hsv
; /* The HSV values of the color */
113 enum { /* Which one was last set ? */
120 typedef struct WheelMatrix
{
121 unsigned int width
, height
; /* Size of the colorwheel */
122 unsigned char *data
[3]; /* Wheel data (R,G,B) */
123 unsigned char values
[256]; /* Precalculated values R,G & B = 0-255 */
126 typedef struct W_ColorPanel
{
134 WMColorWell
*colorWell
;
135 WMButton
*magnifyBtn
;
137 WMButton
*slidersBtn
;
138 WMButton
*customPaletteBtn
;
139 WMButton
*colorListBtn
;
141 /* Magnifying Glass */
142 MovingView
*magnifyGlass
;
144 /* ColorWheel Panel */
146 WMSlider
*wheelBrightnessS
;
151 WMFrame
*seperatorFrm
;
156 /* Gray Scale Panel */
160 WMSlider
*grayBrightnessS
;
161 WMTextField
*grayBrightnessT
;
162 WMButton
*grayPresetBtn
[7];
171 WMTextField
*rgbRedT
;
172 WMTextField
*rgbGreenT
;
173 WMTextField
*rgbBlueT
;
180 WMSlider
*cmykMagentaS
;
181 WMSlider
*cmykYellowS
;
182 WMSlider
*cmykBlackS
;
183 WMTextField
*cmykCyanT
;
184 WMTextField
*cmykMagentaT
;
185 WMTextField
*cmykYellowT
;
186 WMTextField
*cmykBlackT
;
191 WMSlider
*hsbSaturationS
;
192 WMSlider
*hsbBrightnessS
;
193 WMTextField
*hsbHueT
;
194 WMTextField
*hsbSaturationT
;
195 WMTextField
*hsbBrightnessT
;
197 /* Custom Palette Panel */
198 WMFrame
*customPaletteFrm
;
199 WMPopUpButton
*customPaletteHistoryBtn
;
200 WMFrame
*customPaletteContentFrm
;
201 WMPopUpButton
*customPaletteMenuBtn
;
202 WMView
*customPaletteContentView
;
204 /* Color List Panel */
205 WMFrame
*colorListFrm
;
206 WMPopUpButton
*colorListHistoryBtn
;
207 WMList
*colorListContentLst
;
208 WMPopUpButton
*colorListColorMenuBtn
;
209 WMPopUpButton
*colorListListMenuBtn
;
211 /* Look-Up Tables and Images */
212 wheelMatrix
*wheelMtrx
;
215 Pixmap selectionBackImg
;
216 RImage
*customPaletteImg
;
219 /* Common Data Fields */
220 CPColor color
; /* Current color */
221 WMColorPanelMode mode
; /* Current color selection mode */
222 WMColorPanelMode slidersmode
; /* Current color sel. mode sliders panel */
223 WMColorPanelMode lastChanged
; /* Panel that last changed the color */
224 int colx
, coly
; /* (x,y) of sel.-marker in WheelMode */
225 int palx
, paly
; /* (x,y) of sel.-marker in
227 double palXRatio
, palYRatio
; /* Ratios in x & y between
231 char *configurationPath
;
234 unsigned int continuous
:1;
235 unsigned int dragging
:1;
244 CPmenuNewFromClipboard
245 } customPaletteMenuItem
;
255 #define colorWheelSize 150
256 #define customPaletteWidth 182
257 #define customPaletteHeight 106
258 #define knobThickness 8
260 #define SPECTRUM_WIDTH 511
261 #define SPECTRUM_HEIGHT 360
263 #define COLORWHEEL_PART 1
264 #define CUSTOMPALETTE_PART 2
267 #define MAX_LENGTH 1024
270 #define M_PI 3.14159265358979323846
273 /* Silly hack for Windows systems with cygwin */
278 static int fetchFile(char *toPath
, char *imageSrcFile
, char *imageDestFileName
);
279 char *generateNewFilename(char *curName
);
280 void convertCPColor(CPColor
* color
);
281 RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
);
282 unsigned char getShift(unsigned char value
);
284 static void modeButtonCallback(WMWidget
* w
, void *data
);
285 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
);
286 static void readConfiguration(W_ColorPanel
* panel
);
287 static void readXColors(W_ColorPanel
* panel
);
289 static void closeWindowCallback(WMWidget
* w
, void *data
);
291 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
);
292 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
);
293 static void magnifyPutCursor(WMWidget
* w
, void *data
);
294 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
);
295 static void magnifyGetImageStored(W_ColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
);
296 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
);
298 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
);
299 static void wheelDestroyMatrix(wheelMatrix
* matrix
);
300 static void wheelInitMatrix(W_ColorPanel
* panel
);
301 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
);
302 static void wheelRender(W_ColorPanel
* panel
);
303 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
);
304 static void wheelPaint(W_ColorPanel
* panel
);
306 static void wheelHandleEvents(XEvent
* event
, void *data
);
307 static void wheelHandleActionEvents(XEvent
* event
, void *data
);
308 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
);
309 static void wheelUpdateSelection(W_ColorPanel
* panel
);
310 static void wheelUndrawSelection(W_ColorPanel
* panel
);
312 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
);
313 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
314 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
);
315 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
);
317 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
);
318 static void grayPresetButtonCallback(WMWidget
* w
, void *data
);
319 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
);
321 static void rgbSliderCallback(WMWidget
* w
, void *data
);
322 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
);
324 static void cmykSliderCallback(WMWidget
* w
, void *data
);
325 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
);
327 static void hsbSliderCallback(WMWidget
* w
, void *data
);
328 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
);
329 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
);
330 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
);
331 static void hsbUpdateHueGradient(W_ColorPanel
* panel
);
333 static void customRenderSpectrum(W_ColorPanel
* panel
);
334 static void customSetPalette(W_ColorPanel
* panel
);
335 static void customPaletteHandleEvents(XEvent
* event
, void *data
);
336 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
);
337 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
);
338 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
339 static void customPaletteMenuCallback(WMWidget
* w
, void *data
);
340 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
);
342 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
);
343 static void customPaletteMenuRename(W_ColorPanel
* panel
);
344 static void customPaletteMenuRemove(W_ColorPanel
* panel
);
346 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
);
347 static void colorListSelect(WMWidget
* w
, void *data
);
348 static void colorListColorMenuCallback(WMWidget
* w
, void *data
);
349 static void colorListListMenuCallback(WMWidget
* w
, void *data
);
350 static void colorListListMenuNew(W_ColorPanel
* panel
);
352 static void wheelInit(W_ColorPanel
* panel
);
353 static void grayInit(W_ColorPanel
* panel
);
354 static void rgbInit(W_ColorPanel
* panel
);
355 static void cmykInit(W_ColorPanel
* panel
);
356 static void hsbInit(W_ColorPanel
* panel
);
358 void WMSetColorPanelAction(WMColorPanel
* panel
, WMAction2
* action
, void *data
)
360 panel
->action
= action
;
361 panel
->clientData
= data
;
364 static WMColorPanel
*makeColorPanel(WMScreen
* scrPtr
, char *name
)
371 WMColor
*textcolor
, *graybuttoncolor
;
373 GC bgc
= WMColorGC(scrPtr
->black
);
374 GC wgc
= WMColorGC(scrPtr
->white
);
376 panel
= wmalloc(sizeof(WMColorPanel
));
377 memset(panel
, 0, sizeof(WMColorPanel
));
379 panel
->color
.rgb
.red
= 0;
380 panel
->color
.rgb
.green
= 0;
381 panel
->color
.rgb
.blue
= 0;
382 panel
->color
.hsv
.hue
= 0;
383 panel
->color
.hsv
.saturation
= 0;
384 panel
->color
.hsv
.value
= 0;
385 panel
->color
.set
= cpNone
; /* Color has not been set yet */
387 panel
->font8
= WMSystemFontOfSize(scrPtr
, 8);
388 panel
->font12
= WMSystemFontOfSize(scrPtr
, 12);
390 panel
->win
= WMCreateWindowWithStyle(scrPtr
, name
,
391 WMTitledWindowMask
| WMClosableWindowMask
| WMResizableWindowMask
);
392 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
393 WMSetWindowTitle(panel
->win
, _("Colors"));
394 WMSetWindowCloseAction(panel
->win
, closeWindowCallback
, panel
);
396 /* Set Default ColorPanel Mode(s) */
397 panel
->mode
= WMWheelModeColorPanel
;
398 panel
->lastChanged
= 0;
399 panel
->slidersmode
= WMRGBModeColorPanel
;
400 panel
->configurationPath
= wstrconcat(wusergnusteppath(), "/Library/Colors/");
402 /* Some General Purpose Widgets */
403 panel
->colorWell
= WMCreateColorWell(panel
->win
);
404 WMResizeWidget(panel
->colorWell
, 134, 36);
405 WSetColorWellBordered(panel
->colorWell
, False
);
406 WMMoveWidget(panel
->colorWell
, 56, 4);
408 panel
->magnifyBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
409 WMResizeWidget(panel
->magnifyBtn
, 46, 36);
410 WMMoveWidget(panel
->magnifyBtn
, 6, 4);
411 WMSetButtonAction(panel
->magnifyBtn
, magnifyPutCursor
, panel
);
412 WMSetButtonImagePosition(panel
->magnifyBtn
, WIPImageOnly
);
413 WMSetButtonImage(panel
->magnifyBtn
, scrPtr
->magnifyIcon
);
415 panel
->wheelBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
416 WMResizeWidget(panel
->wheelBtn
, 46, 32);
417 WMMoveWidget(panel
->wheelBtn
, 6, 44);
418 WMSetButtonAction(panel
->wheelBtn
, modeButtonCallback
, panel
);
419 WMSetButtonImagePosition(panel
->wheelBtn
, WIPImageOnly
);
420 WMSetButtonImage(panel
->wheelBtn
, scrPtr
->wheelIcon
);
422 panel
->slidersBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
423 WMResizeWidget(panel
->slidersBtn
, 46, 32);
424 WMMoveWidget(panel
->slidersBtn
, 52, 44);
425 WMSetButtonAction(panel
->slidersBtn
, modeButtonCallback
, panel
);
426 WMSetButtonImagePosition(panel
->slidersBtn
, WIPImageOnly
);
427 WMSetButtonImage(panel
->slidersBtn
, scrPtr
->rgbIcon
);
429 panel
->customPaletteBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
430 WMResizeWidget(panel
->customPaletteBtn
, 46, 32);
431 WMMoveWidget(panel
->customPaletteBtn
, 98, 44);
432 WMSetButtonAction(panel
->customPaletteBtn
, modeButtonCallback
, panel
);
433 WMSetButtonImagePosition(panel
->customPaletteBtn
, WIPImageOnly
);
434 WMSetButtonImage(panel
->customPaletteBtn
, scrPtr
->customPaletteIcon
);
436 panel
->colorListBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
437 WMResizeWidget(panel
->colorListBtn
, 46, 32);
438 WMMoveWidget(panel
->colorListBtn
, 144, 44);
439 WMSetButtonAction(panel
->colorListBtn
, modeButtonCallback
, panel
);
440 WMSetButtonImagePosition(panel
->colorListBtn
, WIPImageOnly
);
441 WMSetButtonImage(panel
->colorListBtn
, scrPtr
->colorListIcon
);
443 /* Let's Group some of them together */
444 WMGroupButtons(panel
->wheelBtn
, panel
->slidersBtn
);
445 WMGroupButtons(panel
->wheelBtn
, panel
->customPaletteBtn
);
446 WMGroupButtons(panel
->wheelBtn
, panel
->colorListBtn
);
448 /* Widgets for the ColorWheel Panel */
449 panel
->wheelFrm
= WMCreateFrame(panel
->win
);
450 WMSetFrameRelief(panel
->wheelFrm
, WRFlat
);
451 WMResizeWidget(panel
->wheelFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
452 WMMoveWidget(panel
->wheelFrm
, 5, 80);
454 panel
->wheelView
= W_CreateView(W_VIEW(panel
->wheelFrm
));
455 /* XXX Can we create a view ? */
456 W_ResizeView(panel
->wheelView
, colorWheelSize
+ 4, colorWheelSize
+ 4);
457 W_MoveView(panel
->wheelView
, 0, 0);
459 /* Create an event handler to handle expose/click events in ColorWheel */
460 WMCreateEventHandler(panel
->wheelView
,
461 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
|
462 LeaveWindowMask
| ButtonMotionMask
, wheelHandleActionEvents
, panel
);
464 WMCreateEventHandler(panel
->wheelView
, ExposureMask
, wheelHandleEvents
, panel
);
466 panel
->wheelBrightnessS
= WMCreateSlider(panel
->wheelFrm
);
467 WMResizeWidget(panel
->wheelBrightnessS
, 16, 153);
468 WMMoveWidget(panel
->wheelBrightnessS
, 5 + colorWheelSize
+ 14, 1);
469 WMSetSliderMinValue(panel
->wheelBrightnessS
, 0);
470 WMSetSliderMaxValue(panel
->wheelBrightnessS
, 255);
471 WMSetSliderAction(panel
->wheelBrightnessS
, wheelBrightnessSliderCallback
, panel
);
472 WMSetSliderKnobThickness(panel
->wheelBrightnessS
, knobThickness
);
474 panel
->wheelMtrx
= wheelCreateMatrix(colorWheelSize
+ 4, colorWheelSize
+ 4);
475 wheelInitMatrix(panel
);
477 /* Widgets for the Slider Panels */
478 panel
->slidersFrm
= WMCreateFrame(panel
->win
);
479 WMSetFrameRelief(panel
->slidersFrm
, WRFlat
);
480 WMResizeWidget(panel
->slidersFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
481 WMMoveWidget(panel
->slidersFrm
, 4, 80);
483 panel
->seperatorFrm
= WMCreateFrame(panel
->slidersFrm
);
484 WMSetFrameRelief(panel
->seperatorFrm
, WRPushed
);
485 WMResizeWidget(panel
->seperatorFrm
, PWIDTH
- 8, 2);
486 WMMoveWidget(panel
->seperatorFrm
, 0, 1);
488 panel
->grayBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
489 WMResizeWidget(panel
->grayBtn
, 46, 24);
490 WMMoveWidget(panel
->grayBtn
, 1, 8);
491 WMSetButtonAction(panel
->grayBtn
, modeButtonCallback
, panel
);
492 WMSetButtonImagePosition(panel
->grayBtn
, WIPImageOnly
);
493 WMSetButtonImage(panel
->grayBtn
, scrPtr
->grayIcon
);
495 panel
->rgbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
496 WMResizeWidget(panel
->rgbBtn
, 46, 24);
497 WMMoveWidget(panel
->rgbBtn
, 47, 8);
498 WMSetButtonAction(panel
->rgbBtn
, modeButtonCallback
, panel
);
499 WMSetButtonImagePosition(panel
->rgbBtn
, WIPImageOnly
);
500 WMSetButtonImage(panel
->rgbBtn
, scrPtr
->rgbIcon
);
502 panel
->cmykBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
503 WMResizeWidget(panel
->cmykBtn
, 46, 24);
504 WMMoveWidget(panel
->cmykBtn
, 93, 8);
505 WMSetButtonAction(panel
->cmykBtn
, modeButtonCallback
, panel
);
506 WMSetButtonImagePosition(panel
->cmykBtn
, WIPImageOnly
);
507 WMSetButtonImage(panel
->cmykBtn
, scrPtr
->cmykIcon
);
509 panel
->hsbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
510 WMResizeWidget(panel
->hsbBtn
, 46, 24);
511 WMMoveWidget(panel
->hsbBtn
, 139, 8);
512 WMSetButtonAction(panel
->hsbBtn
, modeButtonCallback
, panel
);
513 WMSetButtonImagePosition(panel
->hsbBtn
, WIPImageOnly
);
514 WMSetButtonImage(panel
->hsbBtn
, scrPtr
->hsbIcon
);
516 /* Let's Group the Slider Panel Buttons Together */
517 WMGroupButtons(panel
->grayBtn
, panel
->rgbBtn
);
518 WMGroupButtons(panel
->grayBtn
, panel
->cmykBtn
);
519 WMGroupButtons(panel
->grayBtn
, panel
->hsbBtn
);
521 textcolor
= WMDarkGrayColor(scrPtr
);
523 /* Widgets for GrayScale Panel */
524 panel
->grayFrm
= WMCreateFrame(panel
->slidersFrm
);
525 WMSetFrameRelief(panel
->grayFrm
, WRFlat
);
526 WMResizeWidget(panel
->grayFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
527 WMMoveWidget(panel
->grayFrm
, 0, 34);
529 panel
->grayMinL
= WMCreateLabel(panel
->grayFrm
);
530 WMResizeWidget(panel
->grayMinL
, 20, 10);
531 WMMoveWidget(panel
->grayMinL
, 2, 2);
532 WMSetLabelText(panel
->grayMinL
, "0");
533 WMSetLabelTextAlignment(panel
->grayMinL
, WALeft
);
534 WMSetLabelTextColor(panel
->grayMinL
, textcolor
);
535 WMSetLabelFont(panel
->grayMinL
, panel
->font8
);
537 panel
->grayMaxL
= WMCreateLabel(panel
->grayFrm
);
538 WMResizeWidget(panel
->grayMaxL
, 40, 10);
539 WMMoveWidget(panel
->grayMaxL
, 104, 2);
540 WMSetLabelText(panel
->grayMaxL
, "100");
541 WMSetLabelTextAlignment(panel
->grayMaxL
, WARight
);
542 WMSetLabelTextColor(panel
->grayMaxL
, textcolor
);
543 WMSetLabelFont(panel
->grayMaxL
, panel
->font8
);
545 panel
->grayBrightnessS
= WMCreateSlider(panel
->grayFrm
);
546 WMResizeWidget(panel
->grayBrightnessS
, 141, 16);
547 WMMoveWidget(panel
->grayBrightnessS
, 2, 14);
548 WMSetSliderMinValue(panel
->grayBrightnessS
, 0);
549 WMSetSliderMaxValue(panel
->grayBrightnessS
, 100);
550 WMSetSliderKnobThickness(panel
->grayBrightnessS
, knobThickness
);
551 WMSetSliderAction(panel
->grayBrightnessS
, grayBrightnessSliderCallback
, panel
);
561 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
562 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
563 RReleaseImage(image
);
566 W_PaintText(W_VIEW(panel
->grayBrightnessS
), pixmap
->pixmap
,
567 panel
->font12
, 2, 0, 100, WALeft
, scrPtr
->white
,
568 False
, _("Brightness"), strlen(_("Brightness")));
570 wwarning(_("Color Panel: Could not allocate memory"));
572 WMSetSliderImage(panel
->grayBrightnessS
, pixmap
);
573 WMReleasePixmap(pixmap
);
575 panel
->grayBrightnessT
= WMCreateTextField(panel
->grayFrm
);
576 WMResizeWidget(panel
->grayBrightnessT
, 40, 18);
577 WMMoveWidget(panel
->grayBrightnessT
, 146, 13);
578 WMSetTextFieldAlignment(panel
->grayBrightnessT
, WALeft
);
579 WMAddNotificationObserver(grayBrightnessTextFieldCallback
, panel
,
580 WMTextDidEndEditingNotification
, panel
->grayBrightnessT
);
582 for (i
= 0; i
< 7; i
++) {
583 pixmap
= WMCreatePixmap(scrPtr
, 13, 13, scrPtr
->depth
, False
);
585 graybuttoncolor
= WMCreateRGBColor(scrPtr
, (255 / 6) * i
<< 8,
586 (255 / 6) * i
<< 8, (255 / 6) * i
<< 8, True
);
587 WMPaintColorSwatch(graybuttoncolor
, pixmap
->pixmap
, 0, 0, 15, 15);
588 WMReleaseColor(graybuttoncolor
);
590 panel
->grayPresetBtn
[i
] = WMCreateCommandButton(panel
->grayFrm
);
591 WMResizeWidget(panel
->grayPresetBtn
[i
], 20, 24);
592 WMMoveWidget(panel
->grayPresetBtn
[i
], 2 + (i
* 20), 34);
593 WMSetButtonAction(panel
->grayPresetBtn
[i
], grayPresetButtonCallback
, panel
);
594 WMSetButtonImage(panel
->grayPresetBtn
[i
], pixmap
);
595 WMSetButtonImagePosition(panel
->grayPresetBtn
[i
], WIPImageOnly
);
596 WMReleasePixmap(pixmap
);
600 /* End of GrayScale Panel */
602 /* Widgets for RGB Panel */
603 panel
->rgbFrm
= WMCreateFrame(panel
->slidersFrm
);
604 WMSetFrameRelief(panel
->rgbFrm
, WRFlat
);
605 WMResizeWidget(panel
->rgbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
606 WMMoveWidget(panel
->rgbFrm
, 0, 34);
608 panel
->rgbMinL
= WMCreateLabel(panel
->rgbFrm
);
609 WMResizeWidget(panel
->rgbMinL
, 20, 10);
610 WMMoveWidget(panel
->rgbMinL
, 2, 2);
611 WMSetLabelText(panel
->rgbMinL
, "0");
612 WMSetLabelTextAlignment(panel
->rgbMinL
, WALeft
);
613 WMSetLabelTextColor(panel
->rgbMinL
, textcolor
);
614 WMSetLabelFont(panel
->rgbMinL
, panel
->font8
);
616 panel
->rgbMaxL
= WMCreateLabel(panel
->rgbFrm
);
617 WMResizeWidget(panel
->rgbMaxL
, 40, 10);
618 WMMoveWidget(panel
->rgbMaxL
, 104, 2);
619 WMSetLabelText(panel
->rgbMaxL
, "255");
620 WMSetLabelTextAlignment(panel
->rgbMaxL
, WARight
);
621 WMSetLabelTextColor(panel
->rgbMaxL
, textcolor
);
622 WMSetLabelFont(panel
->rgbMaxL
, panel
->font8
);
624 panel
->rgbRedS
= WMCreateSlider(panel
->rgbFrm
);
625 WMResizeWidget(panel
->rgbRedS
, 141, 16);
626 WMMoveWidget(panel
->rgbRedS
, 2, 14);
627 WMSetSliderMinValue(panel
->rgbRedS
, 0);
628 WMSetSliderMaxValue(panel
->rgbRedS
, 255);
629 WMSetSliderKnobThickness(panel
->rgbRedS
, knobThickness
);
630 WMSetSliderAction(panel
->rgbRedS
, rgbSliderCallback
, panel
);
636 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
637 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
638 RReleaseImage(image
);
641 W_PaintText(W_VIEW(panel
->rgbRedS
), pixmap
->pixmap
, panel
->font12
,
642 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Red"), strlen(_("Red")));
644 wwarning(_("Color Panel: Could not allocate memory"));
646 WMSetSliderImage(panel
->rgbRedS
, pixmap
);
647 WMReleasePixmap(pixmap
);
649 panel
->rgbRedT
= WMCreateTextField(panel
->rgbFrm
);
650 WMResizeWidget(panel
->rgbRedT
, 40, 18);
651 WMMoveWidget(panel
->rgbRedT
, 146, 13);
652 WMSetTextFieldAlignment(panel
->rgbRedT
, WALeft
);
653 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbRedT
);
655 panel
->rgbGreenS
= WMCreateSlider(panel
->rgbFrm
);
656 WMResizeWidget(panel
->rgbGreenS
, 141, 16);
657 WMMoveWidget(panel
->rgbGreenS
, 2, 36);
658 WMSetSliderMinValue(panel
->rgbGreenS
, 0);
659 WMSetSliderMaxValue(panel
->rgbGreenS
, 255);
660 WMSetSliderKnobThickness(panel
->rgbGreenS
, knobThickness
);
661 WMSetSliderAction(panel
->rgbGreenS
, rgbSliderCallback
, panel
);
667 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
668 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
669 RReleaseImage(image
);
672 W_PaintText(W_VIEW(panel
->rgbGreenS
), pixmap
->pixmap
, panel
->font12
,
673 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Green"), strlen(_("Green")));
675 wwarning(_("Color Panel: Could not allocate memory"));
677 WMSetSliderImage(panel
->rgbGreenS
, pixmap
);
678 WMReleasePixmap(pixmap
);
680 panel
->rgbGreenT
= WMCreateTextField(panel
->rgbFrm
);
681 WMResizeWidget(panel
->rgbGreenT
, 40, 18);
682 WMMoveWidget(panel
->rgbGreenT
, 146, 35);
683 WMSetTextFieldAlignment(panel
->rgbGreenT
, WALeft
);
684 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbGreenT
);
686 panel
->rgbBlueS
= WMCreateSlider(panel
->rgbFrm
);
687 WMResizeWidget(panel
->rgbBlueS
, 141, 16);
688 WMMoveWidget(panel
->rgbBlueS
, 2, 58);
689 WMSetSliderMinValue(panel
->rgbBlueS
, 0);
690 WMSetSliderMaxValue(panel
->rgbBlueS
, 255);
691 WMSetSliderKnobThickness(panel
->rgbBlueS
, knobThickness
);
692 WMSetSliderAction(panel
->rgbBlueS
, rgbSliderCallback
, panel
);
698 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
699 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
700 RReleaseImage(image
);
703 W_PaintText(W_VIEW(panel
->rgbBlueS
), pixmap
->pixmap
, panel
->font12
,
704 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Blue"), strlen(_("Blue")));
706 wwarning(_("Color Panel: Could not allocate memory"));
708 WMSetSliderImage(panel
->rgbBlueS
, pixmap
);
709 WMReleasePixmap(pixmap
);
711 panel
->rgbBlueT
= WMCreateTextField(panel
->rgbFrm
);
712 WMResizeWidget(panel
->rgbBlueT
, 40, 18);
713 WMMoveWidget(panel
->rgbBlueT
, 146, 57);
714 WMSetTextFieldAlignment(panel
->rgbBlueT
, WALeft
);
715 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbBlueT
);
716 /* End of RGB Panel */
718 /* Widgets for CMYK Panel */
719 panel
->cmykFrm
= WMCreateFrame(panel
->slidersFrm
);
720 WMSetFrameRelief(panel
->cmykFrm
, WRFlat
);
721 WMResizeWidget(panel
->cmykFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
722 WMMoveWidget(panel
->cmykFrm
, 0, 34);
724 panel
->cmykMinL
= WMCreateLabel(panel
->cmykFrm
);
725 WMResizeWidget(panel
->cmykMinL
, 20, 10);
726 WMMoveWidget(panel
->cmykMinL
, 2, 2);
727 WMSetLabelText(panel
->cmykMinL
, "0");
728 WMSetLabelTextAlignment(panel
->cmykMinL
, WALeft
);
729 WMSetLabelTextColor(panel
->cmykMinL
, textcolor
);
730 WMSetLabelFont(panel
->cmykMinL
, panel
->font8
);
732 panel
->cmykMaxL
= WMCreateLabel(panel
->cmykFrm
);
733 WMResizeWidget(panel
->cmykMaxL
, 40, 10);
734 WMMoveWidget(panel
->cmykMaxL
, 104, 2);
735 WMSetLabelText(panel
->cmykMaxL
, "100");
736 WMSetLabelTextAlignment(panel
->cmykMaxL
, WARight
);
737 WMSetLabelTextColor(panel
->cmykMaxL
, textcolor
);
738 WMSetLabelFont(panel
->cmykMaxL
, panel
->font8
);
740 panel
->cmykCyanS
= WMCreateSlider(panel
->cmykFrm
);
741 WMResizeWidget(panel
->cmykCyanS
, 141, 16);
742 WMMoveWidget(panel
->cmykCyanS
, 2, 14);
743 WMSetSliderMinValue(panel
->cmykCyanS
, 0);
744 WMSetSliderMaxValue(panel
->cmykCyanS
, 100);
745 WMSetSliderKnobThickness(panel
->cmykCyanS
, knobThickness
);
746 WMSetSliderAction(panel
->cmykCyanS
, cmykSliderCallback
, panel
);
756 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
757 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
758 RReleaseImage(image
);
761 W_PaintText(W_VIEW(panel
->cmykCyanS
), pixmap
->pixmap
, panel
->font12
,
762 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Cyan"), strlen(_("Cyan")));
764 wwarning(_("Color Panel: Could not allocate memory"));
766 WMSetSliderImage(panel
->cmykCyanS
, pixmap
);
767 WMReleasePixmap(pixmap
);
769 panel
->cmykCyanT
= WMCreateTextField(panel
->cmykFrm
);
770 WMResizeWidget(panel
->cmykCyanT
, 40, 18);
771 WMMoveWidget(panel
->cmykCyanT
, 146, 13);
772 WMSetTextFieldAlignment(panel
->cmykCyanT
, WALeft
);
773 WMAddNotificationObserver(cmykTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->cmykCyanT
);
775 panel
->cmykMagentaS
= WMCreateSlider(panel
->cmykFrm
);
776 WMResizeWidget(panel
->cmykMagentaS
, 141, 16);
777 WMMoveWidget(panel
->cmykMagentaS
, 2, 36);
778 WMSetSliderMinValue(panel
->cmykMagentaS
, 0);
779 WMSetSliderMaxValue(panel
->cmykMagentaS
, 100);
780 WMSetSliderKnobThickness(panel
->cmykMagentaS
, knobThickness
);
781 WMSetSliderAction(panel
->cmykMagentaS
, cmykSliderCallback
, panel
);
787 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
788 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
789 RReleaseImage(image
);
792 W_PaintText(W_VIEW(panel
->cmykMagentaS
), pixmap
->pixmap
, panel
->font12
,
793 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Magenta"), strlen(_("Magenta")));
795 wwarning(_("Color Panel: Could not allocate memory"));
797 WMSetSliderImage(panel
->cmykMagentaS
, pixmap
);
798 WMReleasePixmap(pixmap
);
800 panel
->cmykMagentaT
= WMCreateTextField(panel
->cmykFrm
);
801 WMResizeWidget(panel
->cmykMagentaT
, 40, 18);
802 WMMoveWidget(panel
->cmykMagentaT
, 146, 35);
803 WMSetTextFieldAlignment(panel
->cmykMagentaT
, WALeft
);
804 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
805 WMTextDidEndEditingNotification
, panel
->cmykMagentaT
);
807 panel
->cmykYellowS
= WMCreateSlider(panel
->cmykFrm
);
808 WMResizeWidget(panel
->cmykYellowS
, 141, 16);
809 WMMoveWidget(panel
->cmykYellowS
, 2, 58);
810 WMSetSliderMinValue(panel
->cmykYellowS
, 0);
811 WMSetSliderMaxValue(panel
->cmykYellowS
, 100);
812 WMSetSliderKnobThickness(panel
->cmykYellowS
, knobThickness
);
813 WMSetSliderAction(panel
->cmykYellowS
, cmykSliderCallback
, panel
);
819 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
820 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
821 RReleaseImage(image
);
824 W_PaintText(W_VIEW(panel
->cmykYellowS
), pixmap
->pixmap
, panel
->font12
,
825 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Yellow"), strlen(_("Yellow")));
827 wwarning(_("Color Panel: Could not allocate memory"));
829 WMSetSliderImage(panel
->cmykYellowS
, pixmap
);
830 WMReleasePixmap(pixmap
);
832 panel
->cmykYellowT
= WMCreateTextField(panel
->cmykFrm
);
833 WMResizeWidget(panel
->cmykYellowT
, 40, 18);
834 WMMoveWidget(panel
->cmykYellowT
, 146, 57);
835 WMSetTextFieldAlignment(panel
->cmykYellowT
, WALeft
);
836 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
837 WMTextDidEndEditingNotification
, panel
->cmykYellowT
);
839 panel
->cmykBlackS
= WMCreateSlider(panel
->cmykFrm
);
840 WMResizeWidget(panel
->cmykBlackS
, 141, 16);
841 WMMoveWidget(panel
->cmykBlackS
, 2, 80);
842 WMSetSliderMinValue(panel
->cmykBlackS
, 0);
843 WMSetSliderMaxValue(panel
->cmykBlackS
, 100);
844 WMSetSliderValue(panel
->cmykBlackS
, 0);
845 WMSetSliderKnobThickness(panel
->cmykBlackS
, knobThickness
);
846 WMSetSliderAction(panel
->cmykBlackS
, cmykSliderCallback
, panel
);
852 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
853 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
854 RReleaseImage(image
);
857 W_PaintText(W_VIEW(panel
->cmykBlackS
), pixmap
->pixmap
, panel
->font12
,
858 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Black"), strlen(_("Black")));
860 wwarning(_("Color Panel: Could not allocate memory"));
862 WMSetSliderImage(panel
->cmykBlackS
, pixmap
);
863 WMReleasePixmap(pixmap
);
865 panel
->cmykBlackT
= WMCreateTextField(panel
->cmykFrm
);
866 WMResizeWidget(panel
->cmykBlackT
, 40, 18);
867 WMMoveWidget(panel
->cmykBlackT
, 146, 79);
868 WMSetTextFieldAlignment(panel
->cmykBlackT
, WALeft
);
869 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
870 WMTextDidEndEditingNotification
, panel
->cmykBlackT
);
871 /* End of CMYK Panel */
873 /* Widgets for HSB Panel */
874 panel
->hsbFrm
= WMCreateFrame(panel
->slidersFrm
);
875 WMSetFrameRelief(panel
->hsbFrm
, WRFlat
);
876 WMResizeWidget(panel
->hsbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
877 WMMoveWidget(panel
->hsbFrm
, 0, 34);
879 panel
->hsbHueS
= WMCreateSlider(panel
->hsbFrm
);
880 WMResizeWidget(panel
->hsbHueS
, 141, 16);
881 WMMoveWidget(panel
->hsbHueS
, 2, 14);
882 WMSetSliderMinValue(panel
->hsbHueS
, 0);
883 WMSetSliderMaxValue(panel
->hsbHueS
, 359);
884 WMSetSliderKnobThickness(panel
->hsbHueS
, knobThickness
);
885 WMSetSliderAction(panel
->hsbHueS
, hsbSliderCallback
, panel
);
887 panel
->hsbHueT
= WMCreateTextField(panel
->hsbFrm
);
888 WMResizeWidget(panel
->hsbHueT
, 40, 18);
889 WMMoveWidget(panel
->hsbHueT
, 146, 13);
890 WMSetTextFieldAlignment(panel
->hsbHueT
, WALeft
);
891 WMAddNotificationObserver(hsbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->hsbHueT
);
893 panel
->hsbSaturationS
= WMCreateSlider(panel
->hsbFrm
);
894 WMResizeWidget(panel
->hsbSaturationS
, 141, 16);
895 WMMoveWidget(panel
->hsbSaturationS
, 2, 36);
896 WMSetSliderMinValue(panel
->hsbSaturationS
, 0);
897 WMSetSliderMaxValue(panel
->hsbSaturationS
, 100);
898 WMSetSliderKnobThickness(panel
->hsbSaturationS
, knobThickness
);
899 WMSetSliderAction(panel
->hsbSaturationS
, hsbSliderCallback
, panel
);
901 panel
->hsbSaturationT
= WMCreateTextField(panel
->hsbFrm
);
902 WMResizeWidget(panel
->hsbSaturationT
, 40, 18);
903 WMMoveWidget(panel
->hsbSaturationT
, 146, 35);
904 WMSetTextFieldAlignment(panel
->hsbSaturationT
, WALeft
);
905 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
906 WMTextDidEndEditingNotification
, panel
->hsbSaturationT
);
908 panel
->hsbBrightnessS
= WMCreateSlider(panel
->hsbFrm
);
909 WMResizeWidget(panel
->hsbBrightnessS
, 141, 16);
910 WMMoveWidget(panel
->hsbBrightnessS
, 2, 58);
911 WMSetSliderMinValue(panel
->hsbBrightnessS
, 0);
912 WMSetSliderMaxValue(panel
->hsbBrightnessS
, 100);
913 WMSetSliderKnobThickness(panel
->hsbBrightnessS
, knobThickness
);
914 WMSetSliderAction(panel
->hsbBrightnessS
, hsbSliderCallback
, panel
);
916 panel
->hsbBrightnessT
= WMCreateTextField(panel
->hsbFrm
);
917 WMResizeWidget(panel
->hsbBrightnessT
, 40, 18);
918 WMMoveWidget(panel
->hsbBrightnessT
, 146, 57);
919 WMSetTextFieldAlignment(panel
->hsbBrightnessT
, WALeft
);
920 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
921 WMTextDidEndEditingNotification
, panel
->hsbBrightnessT
);
922 /* End of HSB Panel */
924 WMReleaseColor(textcolor
);
926 /* Widgets for the CustomPalette Panel */
927 panel
->customPaletteFrm
= WMCreateFrame(panel
->win
);
928 WMSetFrameRelief(panel
->customPaletteFrm
, WRFlat
);
929 WMResizeWidget(panel
->customPaletteFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
930 WMMoveWidget(panel
->customPaletteFrm
, 5, 80);
932 panel
->customPaletteHistoryBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
933 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, _("Spectrum"));
934 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
935 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1);
936 WMSetPopUpButtonAction(panel
->customPaletteHistoryBtn
, customPaletteHistoryCallback
, panel
);
937 WMResizeWidget(panel
->customPaletteHistoryBtn
, PWIDTH
- 8, 20);
938 WMMoveWidget(panel
->customPaletteHistoryBtn
, 0, 0);
940 panel
->customPaletteContentFrm
= WMCreateFrame(panel
->customPaletteFrm
);
941 WMSetFrameRelief(panel
->customPaletteContentFrm
, WRSunken
);
942 WMResizeWidget(panel
->customPaletteContentFrm
, PWIDTH
- 8, PHEIGHT
- 156);
943 WMMoveWidget(panel
->customPaletteContentFrm
, 0, 23);
945 panel
->customPaletteContentView
= W_CreateView(W_VIEW(panel
->customPaletteContentFrm
));
946 /* XXX Test if we can create a view */
947 W_ResizeView(panel
->customPaletteContentView
, customPaletteWidth
, customPaletteHeight
);
948 W_MoveView(panel
->customPaletteContentView
, 2, 2);
950 /* Create event handler to handle expose/click events in CustomPalette */
951 WMCreateEventHandler(panel
->customPaletteContentView
,
952 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
| LeaveWindowMask
|
953 ButtonMotionMask
, customPaletteHandleActionEvents
, panel
);
955 WMCreateEventHandler(panel
->customPaletteContentView
, ExposureMask
, customPaletteHandleEvents
, panel
);
957 panel
->customPaletteMenuBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
958 WMSetPopUpButtonPullsDown(panel
->customPaletteMenuBtn
, 1);
959 WMSetPopUpButtonText(panel
->customPaletteMenuBtn
, _("Palette"));
960 WMSetPopUpButtonAction(panel
->customPaletteMenuBtn
, customPaletteMenuCallback
, panel
);
961 WMResizeWidget(panel
->customPaletteMenuBtn
, PWIDTH
- 8, 20);
962 WMMoveWidget(panel
->customPaletteMenuBtn
, 0, PHEIGHT
- 130);
964 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from File..."));
965 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Rename..."));
966 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Remove"));
967 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Copy"));
968 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from Clipboard"));
970 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, 0);
971 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, 0);
972 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuCopy
, 0);
973 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuNewFromClipboard
, 0);
975 customRenderSpectrum(panel
);
976 panel
->currentPalette
= 0;
977 panel
->palx
= customPaletteWidth
/ 2;
978 panel
->paly
= customPaletteHeight
/ 2;
980 /* Widgets for the ColorList Panel */
981 panel
->colorListFrm
= WMCreateFrame(panel
->win
);
982 WMSetFrameRelief(panel
->colorListFrm
, WRFlat
);
983 WMResizeWidget(panel
->colorListFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
984 WMMoveWidget(panel
->colorListFrm
, 5, 80);
986 panel
->colorListHistoryBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
987 WMAddPopUpButtonItem(panel
->colorListHistoryBtn
, _("X11-Colors"));
988 WMSetPopUpButtonSelectedItem(panel
->colorListHistoryBtn
,
989 WMGetPopUpButtonNumberOfItems(panel
->colorListHistoryBtn
) - 1);
990 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
991 * colorListHistoryCallback, panel); */
992 WMResizeWidget(panel
->colorListHistoryBtn
, PWIDTH
- 8, 20);
993 WMMoveWidget(panel
->colorListHistoryBtn
, 0, 0);
995 panel
->colorListContentLst
= WMCreateList(panel
->colorListFrm
);
996 WMSetListAction(panel
->colorListContentLst
, colorListSelect
, panel
);
997 WMSetListUserDrawProc(panel
->colorListContentLst
, colorListPaintItem
);
998 WMResizeWidget(panel
->colorListContentLst
, PWIDTH
- 8, PHEIGHT
- 156);
999 WMMoveWidget(panel
->colorListContentLst
, 0, 23);
1000 WMHangData(panel
->colorListContentLst
, panel
);
1002 panel
->colorListColorMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1003 WMSetPopUpButtonPullsDown(panel
->colorListColorMenuBtn
, 1);
1004 WMSetPopUpButtonText(panel
->colorListColorMenuBtn
, _("Color"));
1005 WMSetPopUpButtonAction(panel
->colorListColorMenuBtn
, colorListColorMenuCallback
, panel
);
1006 WMResizeWidget(panel
->colorListColorMenuBtn
, (PWIDTH
- 16) / 2, 20);
1007 WMMoveWidget(panel
->colorListColorMenuBtn
, 0, PHEIGHT
- 130);
1009 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Add..."));
1010 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Rename..."));
1011 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Remove"));
1013 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuAdd
, 0);
1014 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRename
, 0);
1015 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRemove
, 0);
1017 panel
->colorListListMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1018 WMSetPopUpButtonPullsDown(panel
->colorListListMenuBtn
, 1);
1019 WMSetPopUpButtonText(panel
->colorListListMenuBtn
, _("List"));
1020 WMSetPopUpButtonAction(panel
->colorListListMenuBtn
, colorListListMenuCallback
, panel
);
1021 WMResizeWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2, 20);
1022 WMMoveWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2 + 8, PHEIGHT
- 130);
1024 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("New..."));
1025 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Rename..."));
1026 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Remove"));
1028 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuAdd
, 0);
1029 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRename
, 0);
1030 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRemove
, 0);
1032 WMRealizeWidget(panel
->win
);
1033 WMMapSubwidgets(panel
->win
);
1035 WMMapSubwidgets(panel
->wheelFrm
);
1036 WMMapSubwidgets(panel
->slidersFrm
);
1037 WMMapSubwidgets(panel
->grayFrm
);
1038 WMMapSubwidgets(panel
->rgbFrm
);
1039 WMMapSubwidgets(panel
->cmykFrm
);
1040 WMMapSubwidgets(panel
->hsbFrm
);
1041 WMMapSubwidgets(panel
->customPaletteFrm
);
1042 WMMapSubwidgets(panel
->customPaletteContentFrm
);
1043 WMMapSubwidgets(panel
->colorListFrm
);
1045 /* Pixmap to indicate selection positions
1046 * wheelframe MUST be mapped.
1048 panel
->selectionImg
= XCreatePixmap(scrPtr
->display
, WMWidgetXID(panel
->win
), 4, 4, scrPtr
->depth
);
1049 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, bgc
, 0, 0, 4, 4);
1050 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, wgc
, 1, 1, 2, 2);
1052 readConfiguration(panel
);
1058 WMColorPanel
*WMGetColorPanel(WMScreen
* scrPtr
)
1060 WMColorPanel
*panel
;
1062 if (scrPtr
->sharedColorPanel
)
1063 return scrPtr
->sharedColorPanel
;
1065 panel
= makeColorPanel(scrPtr
, "colorPanel");
1067 scrPtr
->sharedColorPanel
= panel
;
1072 void WMFreeColorPanel(WMColorPanel
* panel
)
1074 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1076 if (panel
== scr
->sharedColorPanel
) {
1077 scr
->sharedColorPanel
= NULL
;
1083 WMRemoveNotificationObserver(panel
);
1084 WMUnmapWidget(panel
->win
);
1087 WMReleaseFont(panel
->font8
);
1088 WMReleaseFont(panel
->font12
);
1091 wheelDestroyMatrix(panel
->wheelMtrx
);
1092 if (panel
->wheelImg
)
1093 XFreePixmap(scr
->display
, panel
->wheelImg
);
1094 if (panel
->selectionImg
)
1095 XFreePixmap(scr
->display
, panel
->selectionImg
);
1096 if (panel
->selectionBackImg
)
1097 XFreePixmap(scr
->display
, panel
->selectionBackImg
);
1098 RReleaseImage(panel
->customPaletteImg
);
1101 if (panel
->lastBrowseDir
)
1102 wfree(panel
->lastBrowseDir
);
1103 if (panel
->configurationPath
)
1104 wfree(panel
->configurationPath
);
1106 WMDestroyWidget(panel
->win
);
1111 void WMCloseColorPanel(WMColorPanel
* panel
)
1113 WMFreeColorPanel(panel
);
1116 void WMShowColorPanel(WMColorPanel
* panel
)
1118 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1119 WMColor
*white
= WMWhiteColor(scr
);
1121 if (panel
->color
.set
== cpNone
)
1122 WMSetColorPanelColor(panel
, white
);
1123 WMReleaseColor(white
);
1125 if (panel
->mode
!= WMWheelModeColorPanel
)
1126 WMPerformButtonClick(panel
->wheelBtn
);
1128 WMMapWidget(panel
->win
);
1131 static void closeWindowCallback(WMWidget
* w
, void *data
)
1133 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
1135 WMCloseColorPanel(panel
);
1138 static void readConfiguration(W_ColorPanel
* panel
)
1140 /* XXX Doesn't take care of "invalid" files */
1144 struct stat stat_buf
;
1147 if (stat(panel
->configurationPath
, &stat_buf
) != 0) {
1148 if (mkdir(panel
->configurationPath
, S_IRWXU
| S_IRGRP
| S_IROTH
| S_IXGRP
| S_IXOTH
) != 0) {
1149 wsyserror(_("Color Panel: Could not create directory %s needed"
1150 " to store configurations"), panel
->configurationPath
);
1151 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1152 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1153 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1154 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1156 _("Could not create ColorPanel configuration directory"),
1157 _("OK"), NULL
, NULL
);
1162 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1163 wwarning(_("Color Panel: Could not find file"), "%s", panel
->configurationPath
);
1167 while ((dp
= readdir(dPtr
)) != NULL
) {
1168 unsigned int perm_mask
;
1169 char *path
= wstrconcat(panel
->configurationPath
,
1172 if (dp
->d_name
[0] != '.') {
1173 item
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
1174 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1176 perm_mask
= (access(path
, R_OK
) == 0);
1177 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
, item
, perm_mask
);
1184 static void readXColors(W_ColorPanel
* panel
)
1189 for (entry
= rgbColors
; entry
->name
!= NULL
; entry
++) {
1190 item
= WMAddListItem(panel
->colorListContentLst
, entry
->name
);
1191 item
->clientData
= (void *)&(entry
->color
);
1195 void WMSetColorPanelPickerMode(WMColorPanel
* panel
, WMColorPanelMode mode
)
1197 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1199 if (mode
!= WMWheelModeColorPanel
) {
1200 WMUnmapWidget(panel
->wheelFrm
);
1201 if (panel
->selectionBackImg
) {
1202 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1203 panel
->selectionBackImg
= None
;
1206 if (mode
!= WMGrayModeColorPanel
)
1207 WMUnmapWidget(panel
->grayFrm
);
1208 if (mode
!= WMRGBModeColorPanel
)
1209 WMUnmapWidget(panel
->rgbFrm
);
1210 if (mode
!= WMCMYKModeColorPanel
)
1211 WMUnmapWidget(panel
->cmykFrm
);
1212 if (mode
!= WMHSBModeColorPanel
)
1213 WMUnmapWidget(panel
->hsbFrm
);
1214 if (mode
!= WMCustomPaletteModeColorPanel
) {
1215 WMUnmapWidget(panel
->customPaletteFrm
);
1216 if (panel
->selectionBackImg
) {
1217 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1218 panel
->selectionBackImg
= None
;
1221 if (mode
!= WMColorListModeColorPanel
)
1222 WMUnmapWidget(panel
->colorListFrm
);
1223 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1224 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1225 WMUnmapWidget(panel
->slidersFrm
);
1227 panel
->slidersmode
= mode
;
1229 if (mode
== WMWheelModeColorPanel
) {
1230 WMMapWidget(panel
->wheelFrm
);
1231 WMSetButtonSelected(panel
->wheelBtn
, True
);
1232 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1236 } else if (mode
== WMGrayModeColorPanel
) {
1237 WMMapWidget(panel
->slidersFrm
);
1238 WMSetButtonSelected(panel
->slidersBtn
, True
);
1239 WMMapWidget(panel
->grayFrm
);
1240 WMSetButtonSelected(panel
->grayBtn
, True
);
1241 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1242 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1244 } else if (mode
== WMRGBModeColorPanel
) {
1245 WMMapWidget(panel
->slidersFrm
);
1246 WMSetButtonSelected(panel
->slidersBtn
, True
);
1247 WMMapWidget(panel
->rgbFrm
);
1248 WMSetButtonSelected(panel
->rgbBtn
, True
);
1249 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1250 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1252 } else if (mode
== WMCMYKModeColorPanel
) {
1253 WMMapWidget(panel
->slidersFrm
);
1254 WMSetButtonSelected(panel
->slidersBtn
, True
);
1255 WMMapWidget(panel
->cmykFrm
);
1256 WMSetButtonSelected(panel
->cmykBtn
, True
);
1257 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1258 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1260 } else if (mode
== WMHSBModeColorPanel
) {
1261 WMMapWidget(panel
->slidersFrm
);
1262 WMSetButtonSelected(panel
->slidersBtn
, True
);
1263 WMMapWidget(panel
->hsbFrm
);
1264 WMSetButtonSelected(panel
->hsbBtn
, True
);
1265 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1266 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1268 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1269 WMMapWidget(panel
->customPaletteFrm
);
1270 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1271 customSetPalette(panel
);
1272 } else if (mode
== WMColorListModeColorPanel
) {
1273 WMMapWidget(panel
->colorListFrm
);
1274 WMSetButtonSelected(panel
->colorListBtn
, True
);
1280 WMColor
*WMGetColorPanelColor(WMColorPanel
* panel
)
1282 return WMGetColorWellColor(panel
->colorWell
);
1285 void WMSetColorPanelColor(WMColorPanel
* panel
, WMColor
* color
)
1287 WMSetColorWellColor(panel
->colorWell
, color
);
1289 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1290 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1291 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1292 panel
->color
.set
= cpRGB
;
1294 if (panel
->mode
== panel
->lastChanged
)
1295 panel
->lastChanged
= 0;
1297 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1300 static void updateSwatch(WMColorPanel
* panel
, CPColor color
)
1302 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1305 if (color
.set
!= cpRGB
)
1306 convertCPColor(&color
);
1308 panel
->color
= color
;
1310 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8, color
.rgb
.green
<< 8, color
.rgb
.blue
<< 8, True
);
1312 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1313 WMReleaseColor(wellcolor
);
1315 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1317 (*panel
->action
) (panel
, panel
->clientData
);
1319 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
, NULL
);
1323 static void modeButtonCallback(WMWidget
* w
, void *data
)
1325 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1327 if (w
== panel
->wheelBtn
)
1328 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1329 else if (w
== panel
->slidersBtn
)
1330 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1331 else if (w
== panel
->customPaletteBtn
)
1332 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1333 else if (w
== panel
->colorListBtn
)
1334 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1335 else if (w
== panel
->grayBtn
)
1336 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1337 else if (w
== panel
->rgbBtn
)
1338 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1339 else if (w
== panel
->cmykBtn
)
1340 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1341 else if (w
== panel
->hsbBtn
)
1342 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1345 /****************** Magnifying Cursor Functions *******************/
1347 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
)
1349 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1350 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1351 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1353 if (!(image
&& image
->data
)) {
1354 /* The image in panel->magnifyGlass->image does not exist yet.
1355 * Grab one from the screen (not beyond) and use it from now on.
1357 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1358 x
- Cursor_x_hot
, y
- Cursor_y_hot
, w
, h
, AllPlanes
, ZPixmap
)))
1359 wwarning(_("Color Panel: X failed request"));
1364 /* Coordinate correction for back pixmap
1365 * if magnifying glass is at screen-borders
1368 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1369 * Hatched area is beyond screen border.
1371 * |<-Cursor_x_hot->|
1372 * ________________|_____
1373 * |/ / / / / / /| | |
1374 * | / / / / / / |(x,y) |
1375 * |/_/_/_/_/_/_/|________|
1376 * |<----x0----->|<--w0-->|
1380 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1382 * Hatched area is beyond screen border
1384 * |<-Cursor_x_hot->|
1385 * ________________|_______________
1386 * | | | / / / / / /|
1387 * | (x,y)|/ / / / / / |
1388 * |___________________|_/_/_/_/_/_/|
1389 * |<-------w0-------->| |
1390 * |<---------------w--|----------->|
1395 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1396 x0
= Cursor_x_hot
- x
;
1400 if (displayWidth
- 1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1401 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1404 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1405 y0
= Cursor_y_hot
- y
;
1409 if (displayHeight
- 1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1410 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1412 /* end of coordinate correction */
1414 /* Grab an image from the screen, clipped if necessary,
1415 * and put it in the existing panel->magnifyGlass->image
1416 * with the corresponding clipping offset.
1418 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1419 x
- Cursor_x_hot
+ x0
, y
- Cursor_y_hot
+ y0
, w0
, h0
, AllPlanes
, ZPixmap
, image
, x0
, y0
))
1420 wwarning(_("Color Panel: X failed request"));
1425 static void magnifyGetImageStored(WMColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
)
1427 /* (x1, y1) = topleft corner of existing rectangle
1428 * (x2, y2) = topleft corner of new position
1431 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1432 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1434 const int dx
= abs(x2
- x1
), dy
= abs(y2
- y1
);
1436 const int x_min
= Cursor_x_hot
,
1437 y_min
= Cursor_y_hot
,
1438 x_max
= DisplayWidth(scr
->display
, scr
->screen
) - 1 -
1439 (Cursor_mask_width
- Cursor_x_hot
),
1440 y_max
= DisplayHeight(scr
->display
, scr
->screen
) - 1 - (Cursor_mask_height
- Cursor_y_hot
);
1442 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1443 return; /* No movement */
1455 width
= Cursor_mask_width
- dx
;
1456 height
= Cursor_mask_height
- dy
;
1458 /* If the traversed distance is larger than the size of the magnifying
1459 * glass contents, there is no need to do dirty rectangles. A whole new
1460 * rectangle can be grabbed (unless that rectangle falls partially
1462 * Destroying the image and setting it to NULL will achieve that later on.
1464 * Of course, grabbing an XImage beyond the borders of the screen will
1465 * cause trouble, this is considdered a special case. Part of the screen
1466 * is grabbed, but there is no need for dirty rectangles.
1468 if ((width
<= 0) || (height
<= 0)) {
1469 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1470 if (panel
->magnifyGlass
->image
)
1471 XDestroyImage(panel
->magnifyGlass
->image
);
1472 panel
->magnifyGlass
->image
= NULL
;
1475 if (panel
->magnifyGlass
->image
) {
1476 /* Get dirty rectangle from panel->magnifyGlass->image */
1477 panel
->magnifyGlass
->dirtyRect
=
1478 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1479 if (!panel
->magnifyGlass
->dirtyRect
) {
1480 wwarning(_("Color Panel: X failed request"));
1481 return; /* X returned a NULL from XSubImage */
1486 /* Get image from screen */
1487 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
, Cursor_mask_width
, Cursor_mask_height
);
1488 if (image
) { /* Only reassign if a *new* image was grabbed */
1489 panel
->magnifyGlass
->image
= image
;
1493 /* Copy previously stored rectangle on covered part of image */
1494 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1497 /* "width" and "height" are used as coordinates here,
1498 * and run from [0...width-1] and [0...height-1] respectively.
1502 old_height
= height
;
1504 for (; width
>= 0; width
--)
1505 for (height
= old_height
; height
>= 0; height
--)
1506 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1507 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1508 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1509 panel
->magnifyGlass
->dirtyRect
= NULL
;
1515 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
)
1517 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1522 unsigned long color
;
1524 if (!panel
->magnifyGlass
->image
)
1527 if (!panel
->magnifyGlass
->magPix
)
1531 * Copy an area of only 5x5 pixels from the center of the image.
1533 for (u
= 0; u
< 5; u
++) {
1534 for (v
= 0; v
< 5; v
++) {
1535 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1537 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1539 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1540 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1542 /* The center square must eventually be centered around the
1543 * hotspot. The image needs shifting to achieve this. The amount of
1544 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1547 * ^------- center of center square == Cursor_x_hot
1549 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1551 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1552 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1557 return panel
->magnifyGlass
->magPix
;
1559 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
, Cursor_mask_height
, scr
->depth
);
1563 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1564 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1566 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1567 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1568 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1569 /* (2,2) puts center pixel on center of glass */
1576 static WMView
*magnifyCreateView(W_ColorPanel
* panel
)
1578 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1581 magView
= W_CreateTopView(scr
);
1585 magView
->self
= panel
->win
;
1586 magView
->flags
.topLevel
= 1;
1587 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1588 magView
->attribs
.override_redirect
= True
;
1589 magView
->attribs
.save_under
= True
;
1591 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1593 W_RealizeView(magView
);
1598 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
)
1600 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1601 Pixmap magPixmap
, magPixmap2
;
1603 XColor fgColor
= { 0, 0, 0, 0, DoRed
| DoGreen
| DoBlue
};
1604 XColor bgColor
= { 0, 0xbf00, 0xa000, 0x5000, DoRed
| DoGreen
| DoBlue
};
1606 /* Cursor creation stuff */
1607 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1608 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1609 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1610 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1612 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1613 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1615 XFreePixmap(scr
->display
, magPixmap
);
1616 XFreePixmap(scr
->display
, magPixmap2
);
1618 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1620 /* Set up Pointer */
1621 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1622 PointerMotionMask
| ButtonPressMask
,
1623 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1628 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
)
1630 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1633 Pixmap pixmap
, clip_mask
;
1635 Window root_return
, child_return
;
1637 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1638 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1640 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1641 5 * 5 - 1, 5 * 5 - 1, scr
->depth
);
1643 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
, &x
, &y
, &u
, &v
, &mask
);
1645 panel
->magnifyGlass
->image
= NULL
;
1647 /* Clipmask to make magnified view-contents circular */
1649 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1650 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1652 /* Clip circle in glass cursor */
1653 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1654 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1657 XFreePixmap(scr
->display
, clip_mask
);
1659 /* Draw initial magnifying glass contents */
1660 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1662 pixmap
= magnifyCreatePixmap(panel
);
1663 XSetWindowBackgroundPixmap(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1664 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1665 XFlush(scr
->display
);
1668 XFreePixmap(scr
->display
, pixmap
);
1677 static void magnifyPutCursor(WMWidget
* w
, void *data
)
1679 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1680 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1684 WMPoint initialPosition
;
1686 /* Destroy wheelBackImg, so it'll update properly */
1687 if (panel
->selectionBackImg
) {
1688 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1689 panel
->selectionBackImg
= None
;
1692 /* Create magnifying glass */
1693 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1694 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1695 if (!panel
->magnifyGlass
->view
)
1698 initialPosition
= magnifyInitialize(panel
);
1699 panel
->magnifyGlass
->x
= initialPosition
.x
;
1700 panel
->magnifyGlass
->y
= initialPosition
.y
;
1702 W_MoveView(panel
->magnifyGlass
->view
,
1703 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1704 W_MapView(panel
->magnifyGlass
->view
);
1706 magCursor
= magnifyGrabPointer(panel
);
1708 while (panel
->magnifyGlass
->image
) {
1709 WMNextEvent(scr
->display
, &event
);
1711 /* Pack motion events */
1712 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1715 switch (event
.type
) {
1717 XDestroyImage(panel
->magnifyGlass
->image
);
1718 panel
->magnifyGlass
->image
= NULL
;
1720 if (event
.xbutton
.button
== Button1
) {
1721 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1722 panel
->color
.set
= cpRGB
;
1723 updateSwatch(panel
, panel
->color
);
1725 switch (panel
->mode
) {
1726 case WMWheelModeColorPanel
:
1731 case WMGrayModeColorPanel
:
1734 case WMRGBModeColorPanel
:
1737 case WMCMYKModeColorPanel
:
1740 case WMHSBModeColorPanel
:
1746 panel
->lastChanged
= panel
->mode
;
1748 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1752 while (XPending(event
.xmotion
.display
)) {
1754 XPeekEvent(event
.xmotion
.display
, &ev
);
1755 if (ev
.type
== MotionNotify
)
1756 XNextEvent(event
.xmotion
.display
, &event
);
1761 /* Get a "dirty rectangle" */
1762 magnifyGetImageStored(panel
,
1763 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1764 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1766 /* Update coordinates */
1767 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1768 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1771 W_MoveView(panel
->magnifyGlass
->view
,
1772 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1774 /* Put new image (with magn.) in view */
1775 pixmap
= magnifyCreatePixmap(panel
);
1776 if (pixmap
!= None
) {
1777 /* Change the window background */
1778 XSetWindowBackgroundPixmap(scr
->display
,
1779 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1780 /* Force an Expose (handled by X) */
1781 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1782 /* Synchronize the event queue, so the Expose is handled NOW */
1783 XFlush(scr
->display
);
1785 XFreePixmap(scr
->display
, pixmap
);
1790 /* Try XQueryPointer for this !!! It returns windows that the pointer
1791 * is over. Note: We found this solving the invisible donkey cap bug
1793 #if 0 /* As it is impossible to make this work in all cases,
1794 * we consider it confusing. Therefore we disabled it.
1796 case FocusOut
: /* fall through */
1799 * Color Panel window (panel->win) lost or received focus.
1800 * We need to update the pixmap in the magnifying glass.
1802 * BUG Doesn't work with focus switches between two windows
1803 * if none of them is the color panel.
1805 XUngrabPointer(scr
->display
, CurrentTime
);
1806 W_UnmapView(panel
->magnifyGlass
->view
);
1808 magnifyInitialize(panel
);
1810 W_MapView(panel
->magnifyGlass
->view
);
1811 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
,
1812 True
, PointerMotionMask
| ButtonPressMask
,
1813 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1817 WMHandleEvent(&event
);
1822 XUngrabPointer(scr
->display
, CurrentTime
);
1823 XFreeCursor(scr
->display
, magCursor
);
1825 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1826 panel
->magnifyGlass
->magPix
= None
;
1828 W_UnmapView(panel
->magnifyGlass
->view
);
1829 W_DestroyView(panel
->magnifyGlass
->view
);
1830 panel
->magnifyGlass
->view
= NULL
;
1832 wfree(panel
->magnifyGlass
);
1835 /****************** ColorWheel Functions ************************/
1837 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
)
1839 wheelMatrix
*matrix
= NULL
;
1842 assert((width
> 0) && (height
> 0));
1844 matrix
= wmalloc(sizeof(wheelMatrix
));
1845 memset(matrix
, 0, sizeof(wheelMatrix
));
1846 matrix
->width
= width
;
1847 matrix
->height
= height
;
1849 for (i
= 0; i
< 3; i
++) {
1850 matrix
->data
[i
] = wmalloc(width
* height
* sizeof(unsigned char));
1856 static void wheelDestroyMatrix(wheelMatrix
* matrix
)
1863 for (i
= 0; i
< 3; i
++) {
1864 if (matrix
->data
[i
])
1865 wfree(matrix
->data
[i
]);
1870 static void wheelInitMatrix(W_ColorPanel
* panel
)
1874 unsigned char *rp
, *gp
, *bp
;
1880 const int cw_halfsize
= (colorWheelSize
+ 4) / 2,
1881 cw_sqsize
= (colorWheelSize
+ 4) * (colorWheelSize
+ 4), uchar_shift
= getShift(sizeof(unsigned char));
1883 if (!panel
->wheelMtrx
)
1886 cpColor
.hsv
.value
= 255;
1887 cpColor
.set
= cpHSV
;
1890 ofs
[1] = -(colorWheelSize
+ 4);
1892 /* offsets are counterclockwise (in triangles).
1895 * _______________________________________
1896 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
1897 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
1898 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
1899 * o | | | | | | | | | | | | | | | | | | | | | [3]
1903 * |\ /| <-- triangles
1909 for (y
= 0; y
< cw_halfsize
; y
++) {
1910 for (x
= y
; x
< (colorWheelSize
+ 4 - y
); x
++) {
1911 /* (xcor, ycor) is (x,y) relative to center of matrix */
1912 xcor
= 2 * x
- 4 - colorWheelSize
;
1913 ycor
= 2 * y
- 4 - colorWheelSize
;
1915 /* RColor.saturation is unsigned char and will wrap after 255 */
1916 sat
= rint(255.0 * sqrt(xcor
* xcor
+ ycor
* ycor
) / colorWheelSize
);
1918 cpColor
.hsv
.saturation
= (unsigned char)sat
;
1920 ofs
[0]++; /* top quarter of matrix */
1921 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
1922 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
1923 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
1927 dhue
[0] = rint(atan((double)ycor
/ (double)xcor
) *
1928 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
1932 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
1933 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
1934 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
1935 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
1937 for (i
= 0; i
< 4; i
++) {
1938 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1939 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1940 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1942 cpColor
.hsv
.hue
= dhue
[i
];
1943 convertCPColor(&cpColor
);
1945 *rp
= (unsigned char)(cpColor
.rgb
.red
);
1946 *gp
= (unsigned char)(cpColor
.rgb
.green
);
1947 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
1950 for (i
= 0; i
< 4; i
++) {
1951 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1952 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1953 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1955 *rp
= (unsigned char)0;
1956 *gp
= (unsigned char)0;
1957 *bp
= (unsigned char)0;
1962 ofs
[0] += 2 * y
+ 1;
1963 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2 * y
);
1967 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
)
1972 for (i
= 0; i
< 256; i
++) {
1973 /* We divide by 128 in advance, and check whether that number divides
1974 * by 2 properly. If not, we add one to round the number correctly
1976 v
= (i
* maxvalue
) >> 7;
1977 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) + (v
& 0x01));
1981 static void wheelRender(W_ColorPanel
* panel
)
1983 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1988 unsigned long ofs
= 0;
1989 /*unsigned char shift = getShift(sizeof(unsigned char)); */
1991 image
= RCreateImage(colorWheelSize
+ 4, colorWheelSize
+ 4, True
);
1993 wwarning(_("Color Panel: Could not allocate memory"));
1999 /* TODO Make this transparent istead of gray */
2000 gray
.red
= gray
.blue
= 0xae;
2003 for (y
= 0; y
< colorWheelSize
+ 4; y
++) {
2004 for (x
= 0; x
< colorWheelSize
+ 4; x
++) {
2005 if (wheelInsideColorWheel(panel
, ofs
)) {
2007 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]]);
2009 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]]);
2011 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]]);
2014 *(ptr
++) = (unsigned char)(gray
.red
);
2015 *(ptr
++) = (unsigned char)(gray
.green
);
2016 *(ptr
++) = (unsigned char)(gray
.blue
);
2023 if (panel
->wheelImg
)
2024 XFreePixmap(scr
->display
, panel
->wheelImg
);
2026 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2027 RReleaseImage(image
);
2029 /* Check if backimage exists. If it doesn't, allocate and fill it */
2030 if (!panel
->selectionBackImg
) {
2031 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2032 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2033 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2034 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2035 /* -2 is hot spot correction */
2039 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
)
2041 return ((panel
->wheelMtrx
->data
[0][ofs
] != 0) &&
2042 (panel
->wheelMtrx
->data
[1][ofs
] != 0) && (panel
->wheelMtrx
->data
[2][ofs
] != 0));
2045 static void wheelPaint(W_ColorPanel
* panel
)
2047 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2049 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->wheelView
->window
,
2050 scr
->copyGC
, 0, 0, colorWheelSize
+ 4, colorWheelSize
+ 4, 0, 0);
2052 /* Draw selection image */
2053 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2054 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2057 static void wheelHandleEvents(XEvent
* event
, void *data
)
2059 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2061 switch (event
->type
) {
2063 if (event
->xexpose
.count
!= 0) /* TODO Improve */
2070 static void wheelHandleActionEvents(XEvent
* event
, void *data
)
2072 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2074 switch (event
->type
) {
2076 if (getPickerPart(panel
, event
->xbutton
.x
, event
->xbutton
.y
) == COLORWHEEL_PART
) {
2078 panel
->lastChanged
= WMWheelModeColorPanel
;
2079 panel
->flags
.dragging
= 1;
2081 wheelPositionSelection(panel
, event
->xbutton
.x
, event
->xbutton
.y
);
2086 panel
->flags
.dragging
= 0;
2087 if (!panel
->flags
.continuous
) {
2089 (*panel
->action
) (panel
, panel
->clientData
);
2094 if (panel
->flags
.dragging
) {
2095 if (getPickerPart(panel
, event
->xmotion
.x
, event
->xmotion
.y
) == COLORWHEEL_PART
) {
2096 wheelPositionSelection(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2098 wheelPositionSelectionOutBounds(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2104 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
)
2112 if (panel
->mode
== WMWheelModeColorPanel
) {
2113 if ((lx
>= 2) && (lx
<= 2 + colorWheelSize
) && (ly
>= 2) && (ly
<= 2 + colorWheelSize
)) {
2115 ofs
= ly
* panel
->wheelMtrx
->width
+ lx
;
2117 if (wheelInsideColorWheel(panel
, ofs
))
2118 return COLORWHEEL_PART
;
2122 if (panel
->mode
== WMCustomPaletteModeColorPanel
) {
2123 if ((lx
>= 2) && (lx
< customPaletteWidth
- 2) && (ly
>= 2) && (ly
< customPaletteHeight
- 2)) {
2124 return CUSTOMPALETTE_PART
;
2131 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
)
2135 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2137 value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2139 wheelCalculateValues(panel
, value
);
2141 if (panel
->color
.set
== cpRGB
) {
2142 convertCPColor(&panel
->color
);
2143 panel
->color
.set
= cpHSV
;
2146 panel
->color
.hsv
.value
= value
;
2150 wheelUpdateSelection(panel
);
2153 static void wheelUpdateSelection(W_ColorPanel
* panel
)
2155 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2157 updateSwatch(panel
, panel
->color
);
2158 panel
->lastChanged
= WMWheelModeColorPanel
;
2160 /* Redraw color selector (and make a backup of the part it will cover) */
2161 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2162 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2163 /* "-2" is correction for hotspot location */
2164 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2165 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2169 static void wheelUndrawSelection(W_ColorPanel
* panel
)
2171 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2173 XCopyArea(scr
->display
, panel
->selectionBackImg
, panel
->wheelView
->window
,
2174 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2178 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2180 unsigned long ofs
= (y
* panel
->wheelMtrx
->width
) + x
;
2182 panel
->color
.rgb
.red
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]];
2184 panel
->color
.rgb
.green
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]];
2186 panel
->color
.rgb
.blue
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]];
2187 panel
->color
.set
= cpRGB
;
2189 wheelUndrawSelection(panel
);
2194 wheelUpdateSelection(panel
);
2195 wheelUpdateBrightnessGradientFromLocation(panel
);
2198 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2204 xcor
= x
* 2 - colorWheelSize
- 4;
2205 ycor
= y
* 2 - colorWheelSize
- 4;
2207 panel
->color
.hsv
.saturation
= 255;
2208 panel
->color
.hsv
.value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2211 hue
= rint(atan(-(double)ycor
/ (double)xcor
) * (180.0 / M_PI
));
2222 if ((xcor
> 0) && (ycor
> 0))
2225 panel
->color
.hsv
.hue
= hue
;
2226 panel
->color
.set
= cpHSV
;
2227 convertCPColor(&panel
->color
);
2229 wheelUndrawSelection(panel
);
2231 panel
->colx
= 2 + rint((colorWheelSize
* (1.0 + cos(panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2232 /* "+2" because of "colorWheelSize + 4" */
2233 panel
->coly
= 2 + rint((colorWheelSize
* (1.0 + sin(-panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2235 wheelUpdateSelection(panel
);
2236 cpColor
= panel
->color
;
2237 wheelUpdateBrightnessGradient(panel
, cpColor
);
2240 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
)
2245 ofs
= panel
->coly
* panel
->wheelMtrx
->width
+ panel
->colx
;
2247 from
.rgb
.red
= panel
->wheelMtrx
->data
[0][ofs
];
2248 from
.rgb
.green
= panel
->wheelMtrx
->data
[1][ofs
];
2249 from
.rgb
.blue
= panel
->wheelMtrx
->data
[2][ofs
];
2252 wheelUpdateBrightnessGradient(panel
, from
);
2255 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
)
2259 WMPixmap
*sliderPxmp
;
2261 to
.red
= to
.green
= to
.blue
= 0;
2263 if (topColor
.set
== cpHSV
)
2264 convertCPColor(&topColor
);
2266 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2267 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
), sliderImg
, 0);
2268 RReleaseImage(sliderImg
);
2269 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2270 WMReleasePixmap(sliderPxmp
);
2273 /****************** Grayscale Panel Functions ***************/
2275 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
)
2280 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2282 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2284 sprintf(tmp
, "%d", value
);
2286 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2287 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55 * value
);
2288 cpColor
.set
= cpRGB
;
2290 updateSwatch(panel
, cpColor
);
2291 panel
->lastChanged
= WMGrayModeColorPanel
;
2294 static void grayPresetButtonCallback(WMWidget
* w
, void *data
)
2300 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2303 if (w
== panel
->grayPresetBtn
[i
])
2308 value
= rint((100.0 * i
) / 6.0);
2309 sprintf(tmp
, "%d", value
);
2311 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2312 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * i
) / 6.0);
2313 cpColor
.set
= cpRGB
;
2315 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0 * i
) / 6.0));
2317 updateSwatch(panel
, cpColor
);
2318 panel
->lastChanged
= WMGrayModeColorPanel
;
2321 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
)
2326 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2328 value
= atoi(WMGetTextFieldText(panel
->grayBrightnessT
));
2334 sprintf(tmp
, "%d", value
);
2335 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2336 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2338 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * value
) / 100.0);
2339 cpColor
.set
= cpRGB
;
2341 updateSwatch(panel
, cpColor
);
2342 panel
->lastChanged
= WMGrayModeColorPanel
;
2345 /******************* RGB Panel Functions *****************/
2347 static void rgbSliderCallback(WMWidget
* w
, void *data
)
2352 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2354 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2355 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2356 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2358 sprintf(tmp
, "%d", value
[0]);
2359 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2360 sprintf(tmp
, "%d", value
[1]);
2361 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2362 sprintf(tmp
, "%d", value
[2]);
2363 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2365 cpColor
.rgb
.red
= value
[0];
2366 cpColor
.rgb
.green
= value
[1];
2367 cpColor
.rgb
.blue
= value
[2];
2368 cpColor
.set
= cpRGB
;
2370 updateSwatch(panel
, cpColor
);
2371 panel
->lastChanged
= WMRGBModeColorPanel
;
2374 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2380 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2382 value
[0] = atoi(WMGetTextFieldText(panel
->rgbRedT
));
2383 value
[1] = atoi(WMGetTextFieldText(panel
->rgbGreenT
));
2384 value
[2] = atoi(WMGetTextFieldText(panel
->rgbBlueT
));
2386 for (n
= 0; n
< 3; n
++) {
2393 sprintf(tmp
, "%d", value
[0]);
2394 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2395 sprintf(tmp
, "%d", value
[1]);
2396 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2397 sprintf(tmp
, "%d", value
[2]);
2398 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2400 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2401 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2402 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2404 cpColor
.rgb
.red
= value
[0];
2405 cpColor
.rgb
.green
= value
[1];
2406 cpColor
.rgb
.blue
= value
[2];
2407 cpColor
.set
= cpRGB
;
2409 updateSwatch(panel
, cpColor
);
2410 panel
->lastChanged
= WMRGBModeColorPanel
;
2413 /******************* CMYK Panel Functions *****************/
2415 static void cmykSliderCallback(WMWidget
* w
, void *data
)
2420 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2423 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2424 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2425 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2426 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2428 sprintf(tmp
, "%d", value
[0]);
2429 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2430 sprintf(tmp
, "%d", value
[1]);
2431 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2432 sprintf(tmp
, "%d", value
[2]);
2433 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2434 sprintf(tmp
, "%d", value
[3]);
2435 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2437 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2438 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2439 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2440 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2441 cpColor
.set
= cpRGB
;
2443 updateSwatch(panel
, cpColor
);
2444 panel
->lastChanged
= WMCMYKModeColorPanel
;
2447 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
)
2454 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2456 value
[0] = atoi(WMGetTextFieldText(panel
->cmykCyanT
));
2457 value
[1] = atoi(WMGetTextFieldText(panel
->cmykMagentaT
));
2458 value
[2] = atoi(WMGetTextFieldText(panel
->cmykYellowT
));
2459 value
[3] = atoi(WMGetTextFieldText(panel
->cmykBlackT
));
2461 for (n
= 0; n
< 4; n
++) {
2468 sprintf(tmp
, "%d", value
[0]);
2469 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2471 sprintf(tmp
, "%d", value
[1]);
2472 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2474 sprintf(tmp
, "%d", value
[2]);
2475 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2477 sprintf(tmp
, "%d", value
[3]);
2478 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2480 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2481 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2482 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2483 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2485 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2486 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2487 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2488 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2489 cpColor
.set
= cpRGB
;
2491 updateSwatch(panel
, cpColor
);
2492 panel
->lastChanged
= WMCMYKModeColorPanel
;
2495 /********************** HSB Panel Functions ***********************/
2497 static void hsbSliderCallback(WMWidget
* w
, void *data
)
2502 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2504 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2505 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2506 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2508 sprintf(tmp
, "%d", value
[0]);
2509 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2510 sprintf(tmp
, "%d", value
[1]);
2511 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2512 sprintf(tmp
, "%d", value
[2]);
2513 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2515 cpColor
.hsv
.hue
= value
[0];
2516 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2517 cpColor
.hsv
.value
= value
[2] * 2.55;
2518 cpColor
.set
= cpHSV
;
2520 convertCPColor(&cpColor
);
2522 panel
->lastChanged
= WMHSBModeColorPanel
;
2523 updateSwatch(panel
, cpColor
);
2525 if (w
!= panel
->hsbBrightnessS
)
2526 hsbUpdateBrightnessGradient(panel
);
2527 if (w
!= panel
->hsbSaturationS
)
2528 hsbUpdateSaturationGradient(panel
);
2529 if (w
!= panel
->hsbHueS
)
2530 hsbUpdateHueGradient(panel
);
2533 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2539 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2541 value
[0] = atoi(WMGetTextFieldText(panel
->hsbHueT
));
2542 value
[1] = atoi(WMGetTextFieldText(panel
->hsbSaturationT
));
2543 value
[2] = atoi(WMGetTextFieldText(panel
->hsbBrightnessT
));
2550 for (n
= 1; n
< 3; n
++) {
2557 sprintf(tmp
, "%d", value
[0]);
2558 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2559 sprintf(tmp
, "%d", value
[1]);
2560 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2561 sprintf(tmp
, "%d", value
[2]);
2562 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2564 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2565 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2566 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2568 cpColor
.hsv
.hue
= value
[0];
2569 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2570 cpColor
.hsv
.value
= value
[2] * 2.55;
2571 cpColor
.set
= cpHSV
;
2573 convertCPColor(&cpColor
);
2575 panel
->lastChanged
= WMHSBModeColorPanel
;
2576 updateSwatch(panel
, cpColor
);
2578 hsbUpdateBrightnessGradient(panel
);
2579 hsbUpdateSaturationGradient(panel
);
2580 hsbUpdateHueGradient(panel
);
2583 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
)
2585 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2589 WMPixmap
*sliderPxmp
;
2591 from
.red
= from
.green
= from
.blue
= 0;
2592 to
.hsv
= panel
->color
.hsv
;
2596 convertCPColor(&to
);
2598 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2599 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2600 RReleaseImage(sliderImg
);
2603 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2604 panel
->font12
, 2, 0, 100, WALeft
, scr
->white
,
2605 False
, _("Brightness"), strlen(_("Brightness")));
2607 wwarning(_("Color Panel: Could not allocate memory"));
2609 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2610 WMReleasePixmap(sliderPxmp
);
2613 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
)
2615 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2619 WMPixmap
*sliderPxmp
;
2621 from
.hsv
= panel
->color
.hsv
;
2622 from
.hsv
.saturation
= 0;
2624 convertCPColor(&from
);
2626 to
.hsv
= panel
->color
.hsv
;
2627 to
.hsv
.saturation
= 255;
2629 convertCPColor(&to
);
2631 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
), RGRD_HORIZONTAL
);
2632 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2633 RReleaseImage(sliderImg
);
2636 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2637 panel
->font12
, 2, 0, 100, WALeft
,
2638 from
.hsv
.value
< 128 ? scr
->white
: scr
->black
, False
,
2639 _("Saturation"), strlen(_("Saturation")));
2641 wwarning(_("Color Panel: Could not allocate memory"));
2643 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2644 WMReleasePixmap(sliderPxmp
);
2647 static void hsbUpdateHueGradient(W_ColorPanel
* panel
)
2649 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2650 RColor
**colors
= NULL
;
2653 WMPixmap
*sliderPxmp
;
2656 hsvcolor
= panel
->color
.hsv
;
2658 colors
= wmalloc(sizeof(RColor
*) * (8));
2659 for (i
= 0; i
< 7; i
++) {
2660 hsvcolor
.hue
= (360 * i
) / 6;
2661 colors
[i
] = wmalloc(sizeof(RColor
));
2662 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2666 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2667 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2668 RReleaseImage(sliderImg
);
2671 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2672 panel
->font12
, 2, 0, 100, WALeft
,
2673 hsvcolor
.value
< 128 ? scr
->white
: scr
->black
, False
, _("Hue"), strlen(_("Hue")));
2675 wwarning(_("Color Panel: Could not allocate memory"));
2677 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2678 WMReleasePixmap(sliderPxmp
);
2680 for (i
= 0; i
< 7; i
++)
2686 /*************** Custom Palette Functions ****************/
2688 static void customRenderSpectrum(W_ColorPanel
* panel
)
2695 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, False
);
2697 ptr
= spectrum
->data
;
2699 for (y
= 0; y
< SPECTRUM_HEIGHT
; y
++) {
2700 cpColor
.hsv
.hue
= y
;
2701 cpColor
.hsv
.saturation
= 0;
2702 cpColor
.hsv
.value
= 255;
2703 cpColor
.set
= cpHSV
;
2705 for (x
= 0; x
< SPECTRUM_WIDTH
; x
++) {
2706 convertCPColor(&cpColor
);
2708 *(ptr
++) = (unsigned char)cpColor
.rgb
.red
;
2709 *(ptr
++) = (unsigned char)cpColor
.rgb
.green
;
2710 *(ptr
++) = (unsigned char)cpColor
.rgb
.blue
;
2712 if (x
< (SPECTRUM_WIDTH
/ 2))
2713 cpColor
.hsv
.saturation
++;
2715 if (x
> (SPECTRUM_WIDTH
/ 2))
2716 cpColor
.hsv
.value
--;
2719 if (panel
->customPaletteImg
) {
2720 RReleaseImage(panel
->customPaletteImg
);
2721 panel
->customPaletteImg
= NULL
;
2723 panel
->customPaletteImg
= spectrum
;
2726 static void customSetPalette(W_ColorPanel
* panel
)
2728 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2733 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
, customPaletteHeight
, scr
->depth
);
2734 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
, customPaletteHeight
);
2735 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2736 RReleaseImage(scaledImg
);
2738 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2739 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2741 /* Check backimage exists. If it doesn't, allocate and fill it */
2742 if (!panel
->selectionBackImg
) {
2743 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2744 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2747 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2748 panel
->palx
- 2, panel
->paly
- 2, 4, 4, 0, 0);
2749 XCopyArea(scr
->display
, panel
->selectionImg
,
2750 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2751 panel
->palx
- 2, panel
->paly
- 2);
2752 XFreePixmap(scr
->display
, image
);
2754 panel
->palXRatio
= (double)(panel
->customPaletteImg
->width
) / (double)(customPaletteWidth
);
2755 panel
->palYRatio
= (double)(panel
->customPaletteImg
->height
) / (double)(customPaletteHeight
);
2757 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2760 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2762 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2765 /* undraw selection */
2766 XCopyArea(scr
->display
, panel
->selectionBackImg
,
2767 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2768 panel
->palx
- 2, panel
->paly
- 2);
2773 ofs
= (rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) * panel
->customPaletteImg
->width
) * 3;
2775 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[ofs
];
2776 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[ofs
+ 1];
2777 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[ofs
+ 2];
2778 panel
->color
.set
= cpRGB
;
2780 updateSwatch(panel
, panel
->color
);
2781 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
2783 /* Redraw color selector (and make a backup of the part it will cover) */
2784 XCopyArea(scr
->display
, panel
->customPaletteContentView
->window
, panel
->selectionBackImg
, scr
->copyGC
, panel
->palx
- 2, panel
->paly
- 2, 4, 4, 0, 0); /* "-2" is correction for hotspot location */
2785 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4, panel
->palx
- 2, panel
->paly
- 2); /* see above */
2788 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2794 if (x
>= customPaletteWidth
)
2795 x
= customPaletteWidth
- 2;
2796 if (y
>= customPaletteHeight
)
2797 y
= customPaletteHeight
- 2;
2799 customPalettePositionSelection(panel
, x
, y
);
2802 static void customPaletteHandleEvents(XEvent
* event
, void *data
)
2804 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2806 switch (event
->type
) {
2808 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
2810 customSetPalette(panel
);
2815 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
)
2817 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2820 switch (event
->type
) {
2822 x
= event
->xbutton
.x
;
2823 y
= event
->xbutton
.y
;
2825 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2826 panel
->flags
.dragging
= 1;
2827 customPalettePositionSelection(panel
, x
, y
);
2832 panel
->flags
.dragging
= 0;
2833 if (!panel
->flags
.continuous
) {
2835 (*panel
->action
) (panel
, panel
->clientData
);
2840 x
= event
->xmotion
.x
;
2841 y
= event
->xmotion
.y
;
2843 if (panel
->flags
.dragging
) {
2844 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2845 customPalettePositionSelection(panel
, x
, y
);
2847 customPalettePositionSelectionOutBounds(panel
, x
, y
);
2853 static void customPaletteMenuCallback(WMWidget
* w
, void *data
)
2855 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2856 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
2859 case CPmenuNewFromFile
:
2860 customPaletteMenuNewFromFile(panel
);
2863 customPaletteMenuRename(panel
);
2866 customPaletteMenuRemove(panel
);
2870 case CPmenuNewFromClipboard
:
2875 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
)
2877 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2878 WMOpenPanel
*browseP
;
2880 char *filename
= NULL
;
2884 RImage
*tmpImg
= NULL
;
2886 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
, "\0") == 0))
2887 spath
= wexpandpath(wgethomedir());
2889 spath
= wexpandpath(panel
->lastBrowseDir
);
2891 browseP
= WMGetOpenPanel(scr
);
2892 WMSetFilePanelCanChooseDirectories(browseP
, 0);
2893 WMSetFilePanelCanChooseFiles(browseP
, 1);
2895 /* Get a filename */
2896 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
2897 _("Open Palette"), RSupportedFileFormats())) {
2898 filepath
= WMGetFilePanelFileName(browseP
);
2900 /* Get seperation position between path and filename */
2901 i
= strrchr(filepath
, '/') - filepath
+ 1;
2902 if (i
> strlen(filepath
))
2903 i
= strlen(filepath
);
2905 /* Store last browsed path */
2906 if (panel
->lastBrowseDir
)
2907 wfree(panel
->lastBrowseDir
);
2908 panel
->lastBrowseDir
= wmalloc((i
+ 1) * sizeof(char));
2909 strncpy(panel
->lastBrowseDir
, filepath
, i
);
2910 panel
->lastBrowseDir
[i
] = '\0';
2912 /* Get filename from path */
2913 filename
= wstrdup(filepath
+ i
);
2915 /* Check for duplicate files, and rename it if there are any */
2916 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2917 while (access(tmp
, F_OK
) == 0) {
2922 newName
= generateNewFilename(filename
);
2926 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2930 /* Copy image to $(gnustepdir)/Library/Colors/ &
2931 * Add filename to history menu */
2932 if (fetchFile(panel
->configurationPath
, filepath
, filename
) == 0) {
2934 /* filepath is a "local" path now the file has been copied */
2936 filepath
= wstrconcat(panel
->configurationPath
, filename
);
2938 /* load the image & add menu entries */
2939 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
2941 if (panel
->customPaletteImg
)
2942 RReleaseImage(panel
->customPaletteImg
);
2943 panel
->customPaletteImg
= tmpImg
;
2945 customSetPalette(panel
);
2946 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
2948 panel
->currentPalette
=
2949 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1;
2951 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
2952 panel
->currentPalette
);
2955 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2957 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
2958 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2959 _("Invalid file format !"), _("OK"), NULL
, NULL
);
2961 wsyserror(_("can't remove file %s"), tmp
);
2962 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2963 _("Couldn't remove file from Configuration Directory !"),
2964 _("OK"), NULL
, NULL
);
2971 WMFreeFilePanel(browseP
);
2976 static void customPaletteMenuRename(W_ColorPanel
* panel
)
2978 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2979 char *toName
= NULL
;
2981 char *toPath
, *fromPath
;
2985 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2986 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
2988 toName
= WMRunInputPanel(scr
, panel
->win
, _("Rename"), _("Rename palette to:"),
2989 fromName
, _("OK"), _("Cancel"));
2993 /* As some people do certain stupid things... */
2994 if (strcmp(toName
, fromName
) == 0) {
2999 /* For normal people */
3000 fromPath
= wstrconcat(panel
->configurationPath
, fromName
);
3001 toPath
= wstrconcat(panel
->configurationPath
, toName
);
3003 if (access(toPath
, F_OK
) == 0) {
3004 /* Careful, this palette exists already */
3005 if (WMRunAlertPanel(scr
, panel
->win
, _("Warning"),
3006 _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"),
3008 /* "No" = 0, "Yes" = 1 */
3009 int items
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
3013 /* Remove from History list too */
3015 while ((index
< items
)
3017 (strcmp(WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, index
), toName
)
3021 if (index
< items
) {
3022 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, index
);
3036 if (rename(fromPath
, toPath
) != 0)
3037 wsyserror(_("Couldn't rename palette %s to %s\n"), fromName
, toName
);
3039 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3040 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
, toName
);
3042 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3050 static void customPaletteMenuRemove(W_ColorPanel
* panel
)
3052 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3058 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3060 tmp
= wstrconcat(_("This will permanently remove the palette "),
3061 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3062 text
= wstrconcat(tmp
, _(".\n\nAre you sure you want to remove this palette ?"));
3065 choice
= WMRunAlertPanel(scr
, panel
->win
, _("Remove"), text
, _("Yes"), _("No"), NULL
);
3066 /* returns 0 (= "Yes") or 1 (="No") */
3071 tmp
= wstrconcat(panel
->configurationPath
,
3072 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3074 if (remove(tmp
) == 0) {
3075 /* item-1 always exists */
3076 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3078 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
, panel
);
3079 customSetPalette(panel
);
3081 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3084 wsyserror(_("Couldn't remove palette %s\n"), tmp
);
3091 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
)
3093 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3094 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3098 unsigned char perm_mask
;
3100 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3101 if (item
== panel
->currentPalette
)
3105 customRenderSpectrum(panel
);
3107 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, False
);
3108 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, False
);
3110 /* Load file from configpath */
3111 filename
= wstrconcat(panel
->configurationPath
,
3112 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3114 /* If the file corresponding to the item does not exist,
3115 * remove it from the history list and select the next one.
3117 perm_mask
= (access(filename
, F_OK
) == 0);
3119 /* File does not exist */
3121 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3122 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3123 customPaletteHistoryCallback(w
, data
);
3128 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3130 if (panel
->customPaletteImg
) {
3131 RReleaseImage(panel
->customPaletteImg
);
3132 panel
->customPaletteImg
= NULL
;
3134 panel
->customPaletteImg
= tmp
;
3137 /* If the image is not writable, don't allow removing/renaming */
3138 perm_mask
= (access(filename
, W_OK
) == 0);
3139 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, perm_mask
);
3140 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, perm_mask
);
3144 customSetPalette(panel
);
3146 panel
->currentPalette
= item
;
3149 /************************* ColorList Panel Functions **********************/
3151 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
)
3153 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3154 Display
*dpy
= WMScreenDisplay(scr
);
3155 WMView
*view
= W_VIEW(lPtr
);
3156 RColor
*color
= (RColor
*) WMGetListItem(lPtr
, index
)->clientData
;
3157 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3158 int width
, height
, x
, y
;
3161 width
= rect
->size
.width
;
3162 height
= rect
->size
.height
;
3166 if (state
& WLDSSelected
)
3167 XFillRectangle(dpy
, d
, WMColorGC(scr
->white
), x
, y
, width
, height
);
3169 XFillRectangle(dpy
, d
, WMColorGC(view
->backColor
), x
, y
, width
, height
);
3171 fillColor
= WMCreateRGBColor(scr
, color
->red
<< 8, color
->green
<< 8, color
->blue
<< 8, True
);
3173 XFillRectangle(dpy
, d
, WMColorGC(fillColor
), x
, y
, 15, height
);
3174 WMReleaseColor(fillColor
);
3176 WMDrawString(scr
, d
, scr
->black
, panel
->font12
, x
+ 18, y
, text
, strlen(text
));
3179 static void colorListSelect(WMWidget
* w
, void *data
)
3181 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3184 cpColor
.rgb
= *((RColor
*) WMGetListSelectedItem(w
)->clientData
);
3185 cpColor
.set
= cpRGB
;
3187 panel
->lastChanged
= WMColorListModeColorPanel
;
3188 updateSwatch(panel
, cpColor
);
3191 static void colorListColorMenuCallback(WMWidget
* w
, void *data
)
3193 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3194 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3206 static void colorListListMenuCallback(WMWidget
* w
, void *data
)
3208 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3209 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3213 /* New Color List */
3214 colorListListMenuNew(panel
);
3223 static void colorListListMenuNew(W_ColorPanel
* panel
)
3228 /*************** Panel Initialisation Functions *****************/
3230 static void wheelInit(W_ColorPanel
* panel
)
3234 if (panel
->color
.set
!= cpHSV
)
3235 convertCPColor(&panel
->color
);
3237 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3239 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3240 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3241 cos(panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3242 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3243 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3244 sin(-panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3246 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3248 cpColor
= panel
->color
;
3249 cpColor
.hsv
.value
= 255;
3250 cpColor
.set
= cpHSV
;
3251 wheelUpdateBrightnessGradient(panel
, cpColor
);
3254 static void grayInit(W_ColorPanel
* panel
)
3259 if (panel
->color
.set
!= cpHSV
)
3260 convertCPColor(&panel
->color
);
3262 value
= rint(panel
->color
.hsv
.value
/ 2.55);
3263 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3265 sprintf(tmp
, "%d", value
);
3266 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3269 static void rgbInit(W_ColorPanel
* panel
)
3273 if (panel
->color
.set
!= cpRGB
)
3274 convertCPColor(&panel
->color
);
3276 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3277 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3278 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3280 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3281 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3282 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3283 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3284 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3285 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3288 static void cmykInit(W_ColorPanel
* panel
)
3293 if (panel
->color
.set
!= cpRGB
)
3294 convertCPColor(&panel
->color
);
3296 value
[0] = rint((255 - panel
->color
.rgb
.red
) / 2.55);
3297 value
[1] = rint((255 - panel
->color
.rgb
.green
) / 2.55);
3298 value
[2] = rint((255 - panel
->color
.rgb
.blue
) / 2.55);
3300 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3301 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3302 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3303 WMSetSliderValue(panel
->cmykBlackS
, 0);
3305 sprintf(tmp
, "%d", value
[0]);
3306 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3307 sprintf(tmp
, "%d", value
[1]);
3308 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3309 sprintf(tmp
, "%d", value
[2]);
3310 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3311 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3314 static void hsbInit(W_ColorPanel
* panel
)
3319 if (panel
->color
.set
!= cpHSV
)
3320 convertCPColor(&panel
->color
);
3322 value
[0] = panel
->color
.hsv
.hue
;
3323 value
[1] = rint(panel
->color
.hsv
.saturation
/ 2.55);
3324 value
[2] = rint(panel
->color
.hsv
.value
/ 2.55);
3326 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
3327 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
3328 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
3330 sprintf(tmp
, "%d", value
[0]);
3331 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3332 sprintf(tmp
, "%d", value
[1]);
3333 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3334 sprintf(tmp
, "%d", value
[2]);
3335 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3337 hsbUpdateBrightnessGradient(panel
);
3338 hsbUpdateSaturationGradient(panel
);
3339 hsbUpdateHueGradient(panel
);
3342 /************************** Common utility functions ************************/
3344 static int fetchFile(char *toPath
, char *srcFile
, char *destFile
)
3351 if ((src
= open(srcFile
, O_RDONLY
| O_BINARY
)) == 0) {
3352 wsyserror(_("Could not open %s"), srcFile
);
3356 tmp
= wstrconcat(toPath
, destFile
);
3357 if ((dest
= open(tmp
, O_RDWR
| O_CREAT
| O_BINARY
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
))
3359 wsyserror(_("Could not create %s"), tmp
);
3366 while ((n
= read(src
, buf
, BUFSIZE
)) > 0) {
3367 if (write(dest
, buf
, n
) != n
) {
3368 wsyserror(_("Write error on file %s"), destFile
);
3376 char *generateNewFilename(char *curName
)
3388 if (((ptr
= strrchr(ptr
, '{')) == 0) || sscanf(ptr
, "{%i}%c", &n
, &c
) != 1)
3389 return wstrconcat(curName
, " {1}");
3391 baseLen
= ptr
- curName
- 1;
3393 newName
= wmalloc(baseLen
+ 16);
3394 strncpy(newName
, curName
, baseLen
);
3395 newName
[baseLen
] = 0;
3397 sprintf(&newName
[baseLen
], " {%i}", n
+ 1);
3402 void convertCPColor(CPColor
* color
)
3404 unsigned short old_hue
= 0;
3406 switch (color
->set
) {
3408 wwarning(_("Color Panel: Color unspecified"));
3411 old_hue
= color
->hsv
.hue
;
3412 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3414 /* In black the hue is undefined, and may change by conversion
3415 * Same for white. */
3416 if (((color
->rgb
.red
== 0) &&
3417 (color
->rgb
.green
== 0) &&
3418 (color
->rgb
.blue
== 0)) ||
3419 ((color
->rgb
.red
== 0) && (color
->rgb
.green
== 0) && (color
->rgb
.blue
== 255))
3421 color
->hsv
.hue
= old_hue
;
3424 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3429 #define ABS_SHIFT(val, shift) \
3430 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3432 RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
)
3435 XColor
*xcolor
= NULL
;
3437 if (!(xcolor
= wmalloc(sizeof(XColor
)))) {
3438 wwarning(_("Color Panel: Could not allocate memory"));
3445 xcolor
->pixel
= value
;
3446 XQueryColor(scr
->display
, scr
->rcontext
->cmap
, xcolor
);
3448 color
.red
= xcolor
->red
>> 8;
3449 color
.green
= xcolor
->green
>> 8;
3450 color
.blue
= xcolor
->blue
>> 8;
3457 unsigned char getShift(unsigned char value
)
3459 unsigned char i
= -1;
3472 #ifdef SHAPE_WAS_DEFINED
3473 #undef SHAPE_WAS_DEFINED