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.
35 #include <sys/types.h>
39 #define RETRY( x ) do { \
41 } while (errno == EINTR);
43 /* BUG There's something fishy with shaped windows */
44 /* Whithout shape extension the magnified image is completely broken -Dan */
47 # define SHAPE_WAS_DEFINED
53 # include <X11/extensions/shape.h>
56 char *WMColorPanelColorChangedNotification
= "WMColorPanelColorChangedNotification";
59 * Bitmaps for magnifying glass cursor
63 #define Cursor_x_hot 11
64 #define Cursor_y_hot 11
65 #define Cursor_width 32
66 #define Cursor_height 32
67 static unsigned char Cursor_bits
[] = {
68 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
69 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
70 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
71 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
72 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
73 0x00, 0x08, 0x00, 0x50, 0x00, 0x10, 0x00, 0x88, 0x00, 0x20, 0x00, 0x5c, 0x01, 0xc0, 0x81,
74 0x3b, 0x02, 0x00, 0x7e, 0x70, 0x05, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0xc0, 0x15, 0x00,
75 0x00, 0x80, 0x23, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x5c,
76 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x70
79 /* Cursor shape-mask */
80 #define Cursor_shape_width 32
81 #define Cursor_shape_height 32
82 static unsigned char Cursor_shape_bits
[] = {
83 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
84 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
85 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
86 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
87 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
88 0x00, 0x08, 0x00, 0x70, 0x00, 0x10, 0x00, 0xf8, 0x00, 0x20, 0x00, 0xfc, 0x01, 0xc0, 0x81,
89 0xfb, 0x03, 0x00, 0x7e, 0xf0, 0x07, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xc0, 0x1f, 0x00,
90 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfc,
91 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x70
94 /* Clip-mask for magnified pixels */
95 #define Cursor_mask_width 24
96 #define Cursor_mask_height 24
97 static unsigned char Cursor_mask_bits
[] = {
98 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07,
99 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
100 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
101 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f,
102 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f,
103 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00
106 typedef struct MovingView
{
107 WMView
*view
; /* The view this is all about */
108 XImage
*image
; /* What's under the view */
109 XImage
*dirtyRect
; /* Storage of overlapped image area */
110 Pixmap magPix
; /* Magnified part of pixmap */
111 RColor color
; /* Color of a pixel in the image */
112 int x
, y
; /* Position of view */
115 typedef struct CPColor
{
116 RColor rgb
; /* The RGB values of the color */
117 RHSVColor hsv
; /* The HSV values of the color */
118 enum { /* Which one was last set ? */
125 typedef struct WheelMatrix
{
126 unsigned int width
, height
; /* Size of the colorwheel */
127 unsigned char *data
[3]; /* Wheel data (R,G,B) */
128 unsigned char values
[256]; /* Precalculated values R,G & B = 0-255 */
131 typedef struct W_ColorPanel
{
139 WMColorWell
*colorWell
;
140 WMButton
*magnifyBtn
;
142 WMButton
*slidersBtn
;
143 WMButton
*customPaletteBtn
;
144 WMButton
*colorListBtn
;
146 /* Magnifying Glass */
147 MovingView
*magnifyGlass
;
149 /* ColorWheel Panel */
151 WMSlider
*wheelBrightnessS
;
156 WMFrame
*seperatorFrm
;
161 /* Gray Scale Panel */
165 WMSlider
*grayBrightnessS
;
166 WMTextField
*grayBrightnessT
;
167 WMButton
*grayPresetBtn
[7];
176 WMTextField
*rgbRedT
;
177 WMTextField
*rgbGreenT
;
178 WMTextField
*rgbBlueT
;
185 WMSlider
*cmykMagentaS
;
186 WMSlider
*cmykYellowS
;
187 WMSlider
*cmykBlackS
;
188 WMTextField
*cmykCyanT
;
189 WMTextField
*cmykMagentaT
;
190 WMTextField
*cmykYellowT
;
191 WMTextField
*cmykBlackT
;
196 WMSlider
*hsbSaturationS
;
197 WMSlider
*hsbBrightnessS
;
198 WMTextField
*hsbHueT
;
199 WMTextField
*hsbSaturationT
;
200 WMTextField
*hsbBrightnessT
;
202 /* Custom Palette Panel */
203 WMFrame
*customPaletteFrm
;
204 WMPopUpButton
*customPaletteHistoryBtn
;
205 WMFrame
*customPaletteContentFrm
;
206 WMPopUpButton
*customPaletteMenuBtn
;
207 WMView
*customPaletteContentView
;
209 /* Color List Panel */
210 WMFrame
*colorListFrm
;
211 WMPopUpButton
*colorListHistoryBtn
;
212 WMList
*colorListContentLst
;
213 WMPopUpButton
*colorListColorMenuBtn
;
214 WMPopUpButton
*colorListListMenuBtn
;
216 /* Look-Up Tables and Images */
217 wheelMatrix
*wheelMtrx
;
220 Pixmap selectionBackImg
;
221 RImage
*customPaletteImg
;
224 /* Common Data Fields */
225 CPColor color
; /* Current color */
226 WMColorPanelMode mode
; /* Current color selection mode */
227 WMColorPanelMode slidersmode
; /* Current color sel. mode sliders panel */
228 WMColorPanelMode lastChanged
; /* Panel that last changed the color */
229 int colx
, coly
; /* (x,y) of sel.-marker in WheelMode */
230 int palx
, paly
; /* (x,y) of sel.-marker in
232 double palXRatio
, palYRatio
; /* Ratios in x & y between
236 char *configurationPath
;
239 unsigned int continuous
:1;
240 unsigned int dragging
:1;
249 CPmenuNewFromClipboard
250 } customPaletteMenuItem
;
260 #define colorWheelSize 150
261 #define customPaletteWidth 182
262 #define customPaletteHeight 106
263 #define knobThickness 8
265 #define SPECTRUM_WIDTH 511
266 #define SPECTRUM_HEIGHT 360
268 #define COLORWHEEL_PART 1
269 #define CUSTOMPALETTE_PART 2
272 #define MAX_LENGTH 1024
275 #define M_PI 3.14159265358979323846
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 panel
->color
.rgb
.red
= 0;
378 panel
->color
.rgb
.green
= 0;
379 panel
->color
.rgb
.blue
= 0;
380 panel
->color
.hsv
.hue
= 0;
381 panel
->color
.hsv
.saturation
= 0;
382 panel
->color
.hsv
.value
= 0;
383 panel
->color
.set
= cpNone
; /* Color has not been set yet */
385 panel
->font8
= WMSystemFontOfSize(scrPtr
, 8);
386 panel
->font12
= WMSystemFontOfSize(scrPtr
, 12);
388 panel
->win
= WMCreateWindowWithStyle(scrPtr
, name
,
389 WMTitledWindowMask
| WMClosableWindowMask
| WMResizableWindowMask
);
390 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
391 WMSetWindowTitle(panel
->win
, _("Colors"));
392 WMSetWindowCloseAction(panel
->win
, closeWindowCallback
, panel
);
394 /* Set Default ColorPanel Mode(s) */
395 panel
->mode
= WMWheelModeColorPanel
;
396 panel
->lastChanged
= 0;
397 panel
->slidersmode
= WMRGBModeColorPanel
;
398 panel
->configurationPath
= wstrconcat(wusergnusteppath(), "/Library/Colors/");
400 /* Some General Purpose Widgets */
401 panel
->colorWell
= WMCreateColorWell(panel
->win
);
402 WMResizeWidget(panel
->colorWell
, 134, 36);
403 WSetColorWellBordered(panel
->colorWell
, False
);
404 WMMoveWidget(panel
->colorWell
, 56, 4);
406 panel
->magnifyBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
407 WMResizeWidget(panel
->magnifyBtn
, 46, 36);
408 WMMoveWidget(panel
->magnifyBtn
, 6, 4);
409 WMSetButtonAction(panel
->magnifyBtn
, magnifyPutCursor
, panel
);
410 WMSetButtonImagePosition(panel
->magnifyBtn
, WIPImageOnly
);
411 WMSetButtonImage(panel
->magnifyBtn
, scrPtr
->magnifyIcon
);
413 panel
->wheelBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
414 WMResizeWidget(panel
->wheelBtn
, 46, 32);
415 WMMoveWidget(panel
->wheelBtn
, 6, 44);
416 WMSetButtonAction(panel
->wheelBtn
, modeButtonCallback
, panel
);
417 WMSetButtonImagePosition(panel
->wheelBtn
, WIPImageOnly
);
418 WMSetButtonImage(panel
->wheelBtn
, scrPtr
->wheelIcon
);
420 panel
->slidersBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
421 WMResizeWidget(panel
->slidersBtn
, 46, 32);
422 WMMoveWidget(panel
->slidersBtn
, 52, 44);
423 WMSetButtonAction(panel
->slidersBtn
, modeButtonCallback
, panel
);
424 WMSetButtonImagePosition(panel
->slidersBtn
, WIPImageOnly
);
425 WMSetButtonImage(panel
->slidersBtn
, scrPtr
->rgbIcon
);
427 panel
->customPaletteBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
428 WMResizeWidget(panel
->customPaletteBtn
, 46, 32);
429 WMMoveWidget(panel
->customPaletteBtn
, 98, 44);
430 WMSetButtonAction(panel
->customPaletteBtn
, modeButtonCallback
, panel
);
431 WMSetButtonImagePosition(panel
->customPaletteBtn
, WIPImageOnly
);
432 WMSetButtonImage(panel
->customPaletteBtn
, scrPtr
->customPaletteIcon
);
434 panel
->colorListBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
435 WMResizeWidget(panel
->colorListBtn
, 46, 32);
436 WMMoveWidget(panel
->colorListBtn
, 144, 44);
437 WMSetButtonAction(panel
->colorListBtn
, modeButtonCallback
, panel
);
438 WMSetButtonImagePosition(panel
->colorListBtn
, WIPImageOnly
);
439 WMSetButtonImage(panel
->colorListBtn
, scrPtr
->colorListIcon
);
441 /* Let's Group some of them together */
442 WMGroupButtons(panel
->wheelBtn
, panel
->slidersBtn
);
443 WMGroupButtons(panel
->wheelBtn
, panel
->customPaletteBtn
);
444 WMGroupButtons(panel
->wheelBtn
, panel
->colorListBtn
);
446 /* Widgets for the ColorWheel Panel */
447 panel
->wheelFrm
= WMCreateFrame(panel
->win
);
448 WMSetFrameRelief(panel
->wheelFrm
, WRFlat
);
449 WMResizeWidget(panel
->wheelFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
450 WMMoveWidget(panel
->wheelFrm
, 5, 80);
452 panel
->wheelView
= W_CreateView(W_VIEW(panel
->wheelFrm
));
453 /* XXX Can we create a view ? */
454 W_ResizeView(panel
->wheelView
, colorWheelSize
+ 4, colorWheelSize
+ 4);
455 W_MoveView(panel
->wheelView
, 0, 0);
457 /* Create an event handler to handle expose/click events in ColorWheel */
458 WMCreateEventHandler(panel
->wheelView
,
459 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
|
460 LeaveWindowMask
| ButtonMotionMask
, wheelHandleActionEvents
, panel
);
462 WMCreateEventHandler(panel
->wheelView
, ExposureMask
, wheelHandleEvents
, panel
);
464 panel
->wheelBrightnessS
= WMCreateSlider(panel
->wheelFrm
);
465 WMResizeWidget(panel
->wheelBrightnessS
, 16, 153);
466 WMMoveWidget(panel
->wheelBrightnessS
, 5 + colorWheelSize
+ 14, 1);
467 WMSetSliderMinValue(panel
->wheelBrightnessS
, 0);
468 WMSetSliderMaxValue(panel
->wheelBrightnessS
, 255);
469 WMSetSliderAction(panel
->wheelBrightnessS
, wheelBrightnessSliderCallback
, panel
);
470 WMSetSliderKnobThickness(panel
->wheelBrightnessS
, knobThickness
);
472 panel
->wheelMtrx
= wheelCreateMatrix(colorWheelSize
+ 4, colorWheelSize
+ 4);
473 wheelInitMatrix(panel
);
475 /* Widgets for the Slider Panels */
476 panel
->slidersFrm
= WMCreateFrame(panel
->win
);
477 WMSetFrameRelief(panel
->slidersFrm
, WRFlat
);
478 WMResizeWidget(panel
->slidersFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
479 WMMoveWidget(panel
->slidersFrm
, 4, 80);
481 panel
->seperatorFrm
= WMCreateFrame(panel
->slidersFrm
);
482 WMSetFrameRelief(panel
->seperatorFrm
, WRPushed
);
483 WMResizeWidget(panel
->seperatorFrm
, PWIDTH
- 8, 2);
484 WMMoveWidget(panel
->seperatorFrm
, 0, 1);
486 panel
->grayBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
487 WMResizeWidget(panel
->grayBtn
, 46, 24);
488 WMMoveWidget(panel
->grayBtn
, 1, 8);
489 WMSetButtonAction(panel
->grayBtn
, modeButtonCallback
, panel
);
490 WMSetButtonImagePosition(panel
->grayBtn
, WIPImageOnly
);
491 WMSetButtonImage(panel
->grayBtn
, scrPtr
->grayIcon
);
493 panel
->rgbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
494 WMResizeWidget(panel
->rgbBtn
, 46, 24);
495 WMMoveWidget(panel
->rgbBtn
, 47, 8);
496 WMSetButtonAction(panel
->rgbBtn
, modeButtonCallback
, panel
);
497 WMSetButtonImagePosition(panel
->rgbBtn
, WIPImageOnly
);
498 WMSetButtonImage(panel
->rgbBtn
, scrPtr
->rgbIcon
);
500 panel
->cmykBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
501 WMResizeWidget(panel
->cmykBtn
, 46, 24);
502 WMMoveWidget(panel
->cmykBtn
, 93, 8);
503 WMSetButtonAction(panel
->cmykBtn
, modeButtonCallback
, panel
);
504 WMSetButtonImagePosition(panel
->cmykBtn
, WIPImageOnly
);
505 WMSetButtonImage(panel
->cmykBtn
, scrPtr
->cmykIcon
);
507 panel
->hsbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
508 WMResizeWidget(panel
->hsbBtn
, 46, 24);
509 WMMoveWidget(panel
->hsbBtn
, 139, 8);
510 WMSetButtonAction(panel
->hsbBtn
, modeButtonCallback
, panel
);
511 WMSetButtonImagePosition(panel
->hsbBtn
, WIPImageOnly
);
512 WMSetButtonImage(panel
->hsbBtn
, scrPtr
->hsbIcon
);
514 /* Let's Group the Slider Panel Buttons Together */
515 WMGroupButtons(panel
->grayBtn
, panel
->rgbBtn
);
516 WMGroupButtons(panel
->grayBtn
, panel
->cmykBtn
);
517 WMGroupButtons(panel
->grayBtn
, panel
->hsbBtn
);
519 textcolor
= WMDarkGrayColor(scrPtr
);
521 /* Widgets for GrayScale Panel */
522 panel
->grayFrm
= WMCreateFrame(panel
->slidersFrm
);
523 WMSetFrameRelief(panel
->grayFrm
, WRFlat
);
524 WMResizeWidget(panel
->grayFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
525 WMMoveWidget(panel
->grayFrm
, 0, 34);
527 panel
->grayMinL
= WMCreateLabel(panel
->grayFrm
);
528 WMResizeWidget(panel
->grayMinL
, 20, 10);
529 WMMoveWidget(panel
->grayMinL
, 2, 2);
530 WMSetLabelText(panel
->grayMinL
, "0");
531 WMSetLabelTextAlignment(panel
->grayMinL
, WALeft
);
532 WMSetLabelTextColor(panel
->grayMinL
, textcolor
);
533 WMSetLabelFont(panel
->grayMinL
, panel
->font8
);
535 panel
->grayMaxL
= WMCreateLabel(panel
->grayFrm
);
536 WMResizeWidget(panel
->grayMaxL
, 40, 10);
537 WMMoveWidget(panel
->grayMaxL
, 104, 2);
538 WMSetLabelText(panel
->grayMaxL
, "100");
539 WMSetLabelTextAlignment(panel
->grayMaxL
, WARight
);
540 WMSetLabelTextColor(panel
->grayMaxL
, textcolor
);
541 WMSetLabelFont(panel
->grayMaxL
, panel
->font8
);
543 panel
->grayBrightnessS
= WMCreateSlider(panel
->grayFrm
);
544 WMResizeWidget(panel
->grayBrightnessS
, 141, 16);
545 WMMoveWidget(panel
->grayBrightnessS
, 2, 14);
546 WMSetSliderMinValue(panel
->grayBrightnessS
, 0);
547 WMSetSliderMaxValue(panel
->grayBrightnessS
, 100);
548 WMSetSliderKnobThickness(panel
->grayBrightnessS
, knobThickness
);
549 WMSetSliderAction(panel
->grayBrightnessS
, grayBrightnessSliderCallback
, panel
);
559 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
560 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
561 RReleaseImage(image
);
564 W_PaintText(W_VIEW(panel
->grayBrightnessS
), pixmap
->pixmap
,
565 panel
->font12
, 2, 0, 100, WALeft
, scrPtr
->white
,
566 False
, _("Brightness"), strlen(_("Brightness")));
568 wwarning(_("Color Panel: Could not allocate memory"));
570 WMSetSliderImage(panel
->grayBrightnessS
, pixmap
);
571 WMReleasePixmap(pixmap
);
573 panel
->grayBrightnessT
= WMCreateTextField(panel
->grayFrm
);
574 WMResizeWidget(panel
->grayBrightnessT
, 40, 18);
575 WMMoveWidget(panel
->grayBrightnessT
, 146, 13);
576 WMSetTextFieldAlignment(panel
->grayBrightnessT
, WALeft
);
577 WMAddNotificationObserver(grayBrightnessTextFieldCallback
, panel
,
578 WMTextDidEndEditingNotification
, panel
->grayBrightnessT
);
580 for (i
= 0; i
< 7; i
++) {
581 pixmap
= WMCreatePixmap(scrPtr
, 13, 13, scrPtr
->depth
, False
);
583 graybuttoncolor
= WMCreateRGBColor(scrPtr
, (255 / 6) * i
<< 8,
584 (255 / 6) * i
<< 8, (255 / 6) * i
<< 8, True
);
585 WMPaintColorSwatch(graybuttoncolor
, pixmap
->pixmap
, 0, 0, 15, 15);
586 WMReleaseColor(graybuttoncolor
);
588 panel
->grayPresetBtn
[i
] = WMCreateCommandButton(panel
->grayFrm
);
589 WMResizeWidget(panel
->grayPresetBtn
[i
], 20, 24);
590 WMMoveWidget(panel
->grayPresetBtn
[i
], 2 + (i
* 20), 34);
591 WMSetButtonAction(panel
->grayPresetBtn
[i
], grayPresetButtonCallback
, panel
);
592 WMSetButtonImage(panel
->grayPresetBtn
[i
], pixmap
);
593 WMSetButtonImagePosition(panel
->grayPresetBtn
[i
], WIPImageOnly
);
594 WMReleasePixmap(pixmap
);
598 /* End of GrayScale Panel */
600 /* Widgets for RGB Panel */
601 panel
->rgbFrm
= WMCreateFrame(panel
->slidersFrm
);
602 WMSetFrameRelief(panel
->rgbFrm
, WRFlat
);
603 WMResizeWidget(panel
->rgbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
604 WMMoveWidget(panel
->rgbFrm
, 0, 34);
606 panel
->rgbMinL
= WMCreateLabel(panel
->rgbFrm
);
607 WMResizeWidget(panel
->rgbMinL
, 20, 10);
608 WMMoveWidget(panel
->rgbMinL
, 2, 2);
609 WMSetLabelText(panel
->rgbMinL
, "0");
610 WMSetLabelTextAlignment(panel
->rgbMinL
, WALeft
);
611 WMSetLabelTextColor(panel
->rgbMinL
, textcolor
);
612 WMSetLabelFont(panel
->rgbMinL
, panel
->font8
);
614 panel
->rgbMaxL
= WMCreateLabel(panel
->rgbFrm
);
615 WMResizeWidget(panel
->rgbMaxL
, 40, 10);
616 WMMoveWidget(panel
->rgbMaxL
, 104, 2);
617 WMSetLabelText(panel
->rgbMaxL
, "255");
618 WMSetLabelTextAlignment(panel
->rgbMaxL
, WARight
);
619 WMSetLabelTextColor(panel
->rgbMaxL
, textcolor
);
620 WMSetLabelFont(panel
->rgbMaxL
, panel
->font8
);
622 panel
->rgbRedS
= WMCreateSlider(panel
->rgbFrm
);
623 WMResizeWidget(panel
->rgbRedS
, 141, 16);
624 WMMoveWidget(panel
->rgbRedS
, 2, 14);
625 WMSetSliderMinValue(panel
->rgbRedS
, 0);
626 WMSetSliderMaxValue(panel
->rgbRedS
, 255);
627 WMSetSliderKnobThickness(panel
->rgbRedS
, knobThickness
);
628 WMSetSliderAction(panel
->rgbRedS
, rgbSliderCallback
, panel
);
634 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
635 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
636 RReleaseImage(image
);
639 W_PaintText(W_VIEW(panel
->rgbRedS
), pixmap
->pixmap
, panel
->font12
,
640 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Red"), strlen(_("Red")));
642 wwarning(_("Color Panel: Could not allocate memory"));
644 WMSetSliderImage(panel
->rgbRedS
, pixmap
);
645 WMReleasePixmap(pixmap
);
647 panel
->rgbRedT
= WMCreateTextField(panel
->rgbFrm
);
648 WMResizeWidget(panel
->rgbRedT
, 40, 18);
649 WMMoveWidget(panel
->rgbRedT
, 146, 13);
650 WMSetTextFieldAlignment(panel
->rgbRedT
, WALeft
);
651 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbRedT
);
653 panel
->rgbGreenS
= WMCreateSlider(panel
->rgbFrm
);
654 WMResizeWidget(panel
->rgbGreenS
, 141, 16);
655 WMMoveWidget(panel
->rgbGreenS
, 2, 36);
656 WMSetSliderMinValue(panel
->rgbGreenS
, 0);
657 WMSetSliderMaxValue(panel
->rgbGreenS
, 255);
658 WMSetSliderKnobThickness(panel
->rgbGreenS
, knobThickness
);
659 WMSetSliderAction(panel
->rgbGreenS
, rgbSliderCallback
, panel
);
665 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
666 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
667 RReleaseImage(image
);
670 W_PaintText(W_VIEW(panel
->rgbGreenS
), pixmap
->pixmap
, panel
->font12
,
671 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Green"), strlen(_("Green")));
673 wwarning(_("Color Panel: Could not allocate memory"));
675 WMSetSliderImage(panel
->rgbGreenS
, pixmap
);
676 WMReleasePixmap(pixmap
);
678 panel
->rgbGreenT
= WMCreateTextField(panel
->rgbFrm
);
679 WMResizeWidget(panel
->rgbGreenT
, 40, 18);
680 WMMoveWidget(panel
->rgbGreenT
, 146, 35);
681 WMSetTextFieldAlignment(panel
->rgbGreenT
, WALeft
);
682 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbGreenT
);
684 panel
->rgbBlueS
= WMCreateSlider(panel
->rgbFrm
);
685 WMResizeWidget(panel
->rgbBlueS
, 141, 16);
686 WMMoveWidget(panel
->rgbBlueS
, 2, 58);
687 WMSetSliderMinValue(panel
->rgbBlueS
, 0);
688 WMSetSliderMaxValue(panel
->rgbBlueS
, 255);
689 WMSetSliderKnobThickness(panel
->rgbBlueS
, knobThickness
);
690 WMSetSliderAction(panel
->rgbBlueS
, rgbSliderCallback
, panel
);
696 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
697 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
698 RReleaseImage(image
);
701 W_PaintText(W_VIEW(panel
->rgbBlueS
), pixmap
->pixmap
, panel
->font12
,
702 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Blue"), strlen(_("Blue")));
704 wwarning(_("Color Panel: Could not allocate memory"));
706 WMSetSliderImage(panel
->rgbBlueS
, pixmap
);
707 WMReleasePixmap(pixmap
);
709 panel
->rgbBlueT
= WMCreateTextField(panel
->rgbFrm
);
710 WMResizeWidget(panel
->rgbBlueT
, 40, 18);
711 WMMoveWidget(panel
->rgbBlueT
, 146, 57);
712 WMSetTextFieldAlignment(panel
->rgbBlueT
, WALeft
);
713 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbBlueT
);
714 /* End of RGB Panel */
716 /* Widgets for CMYK Panel */
717 panel
->cmykFrm
= WMCreateFrame(panel
->slidersFrm
);
718 WMSetFrameRelief(panel
->cmykFrm
, WRFlat
);
719 WMResizeWidget(panel
->cmykFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
720 WMMoveWidget(panel
->cmykFrm
, 0, 34);
722 panel
->cmykMinL
= WMCreateLabel(panel
->cmykFrm
);
723 WMResizeWidget(panel
->cmykMinL
, 20, 10);
724 WMMoveWidget(panel
->cmykMinL
, 2, 2);
725 WMSetLabelText(panel
->cmykMinL
, "0");
726 WMSetLabelTextAlignment(panel
->cmykMinL
, WALeft
);
727 WMSetLabelTextColor(panel
->cmykMinL
, textcolor
);
728 WMSetLabelFont(panel
->cmykMinL
, panel
->font8
);
730 panel
->cmykMaxL
= WMCreateLabel(panel
->cmykFrm
);
731 WMResizeWidget(panel
->cmykMaxL
, 40, 10);
732 WMMoveWidget(panel
->cmykMaxL
, 104, 2);
733 WMSetLabelText(panel
->cmykMaxL
, "100");
734 WMSetLabelTextAlignment(panel
->cmykMaxL
, WARight
);
735 WMSetLabelTextColor(panel
->cmykMaxL
, textcolor
);
736 WMSetLabelFont(panel
->cmykMaxL
, panel
->font8
);
738 panel
->cmykCyanS
= WMCreateSlider(panel
->cmykFrm
);
739 WMResizeWidget(panel
->cmykCyanS
, 141, 16);
740 WMMoveWidget(panel
->cmykCyanS
, 2, 14);
741 WMSetSliderMinValue(panel
->cmykCyanS
, 0);
742 WMSetSliderMaxValue(panel
->cmykCyanS
, 100);
743 WMSetSliderKnobThickness(panel
->cmykCyanS
, knobThickness
);
744 WMSetSliderAction(panel
->cmykCyanS
, cmykSliderCallback
, panel
);
754 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
755 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
756 RReleaseImage(image
);
759 W_PaintText(W_VIEW(panel
->cmykCyanS
), pixmap
->pixmap
, panel
->font12
,
760 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Cyan"), strlen(_("Cyan")));
762 wwarning(_("Color Panel: Could not allocate memory"));
764 WMSetSliderImage(panel
->cmykCyanS
, pixmap
);
765 WMReleasePixmap(pixmap
);
767 panel
->cmykCyanT
= WMCreateTextField(panel
->cmykFrm
);
768 WMResizeWidget(panel
->cmykCyanT
, 40, 18);
769 WMMoveWidget(panel
->cmykCyanT
, 146, 13);
770 WMSetTextFieldAlignment(panel
->cmykCyanT
, WALeft
);
771 WMAddNotificationObserver(cmykTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->cmykCyanT
);
773 panel
->cmykMagentaS
= WMCreateSlider(panel
->cmykFrm
);
774 WMResizeWidget(panel
->cmykMagentaS
, 141, 16);
775 WMMoveWidget(panel
->cmykMagentaS
, 2, 36);
776 WMSetSliderMinValue(panel
->cmykMagentaS
, 0);
777 WMSetSliderMaxValue(panel
->cmykMagentaS
, 100);
778 WMSetSliderKnobThickness(panel
->cmykMagentaS
, knobThickness
);
779 WMSetSliderAction(panel
->cmykMagentaS
, cmykSliderCallback
, panel
);
785 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
786 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
787 RReleaseImage(image
);
790 W_PaintText(W_VIEW(panel
->cmykMagentaS
), pixmap
->pixmap
, panel
->font12
,
791 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Magenta"), strlen(_("Magenta")));
793 wwarning(_("Color Panel: Could not allocate memory"));
795 WMSetSliderImage(panel
->cmykMagentaS
, pixmap
);
796 WMReleasePixmap(pixmap
);
798 panel
->cmykMagentaT
= WMCreateTextField(panel
->cmykFrm
);
799 WMResizeWidget(panel
->cmykMagentaT
, 40, 18);
800 WMMoveWidget(panel
->cmykMagentaT
, 146, 35);
801 WMSetTextFieldAlignment(panel
->cmykMagentaT
, WALeft
);
802 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
803 WMTextDidEndEditingNotification
, panel
->cmykMagentaT
);
805 panel
->cmykYellowS
= WMCreateSlider(panel
->cmykFrm
);
806 WMResizeWidget(panel
->cmykYellowS
, 141, 16);
807 WMMoveWidget(panel
->cmykYellowS
, 2, 58);
808 WMSetSliderMinValue(panel
->cmykYellowS
, 0);
809 WMSetSliderMaxValue(panel
->cmykYellowS
, 100);
810 WMSetSliderKnobThickness(panel
->cmykYellowS
, knobThickness
);
811 WMSetSliderAction(panel
->cmykYellowS
, cmykSliderCallback
, panel
);
817 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
818 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
819 RReleaseImage(image
);
822 W_PaintText(W_VIEW(panel
->cmykYellowS
), pixmap
->pixmap
, panel
->font12
,
823 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Yellow"), strlen(_("Yellow")));
825 wwarning(_("Color Panel: Could not allocate memory"));
827 WMSetSliderImage(panel
->cmykYellowS
, pixmap
);
828 WMReleasePixmap(pixmap
);
830 panel
->cmykYellowT
= WMCreateTextField(panel
->cmykFrm
);
831 WMResizeWidget(panel
->cmykYellowT
, 40, 18);
832 WMMoveWidget(panel
->cmykYellowT
, 146, 57);
833 WMSetTextFieldAlignment(panel
->cmykYellowT
, WALeft
);
834 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
835 WMTextDidEndEditingNotification
, panel
->cmykYellowT
);
837 panel
->cmykBlackS
= WMCreateSlider(panel
->cmykFrm
);
838 WMResizeWidget(panel
->cmykBlackS
, 141, 16);
839 WMMoveWidget(panel
->cmykBlackS
, 2, 80);
840 WMSetSliderMinValue(panel
->cmykBlackS
, 0);
841 WMSetSliderMaxValue(panel
->cmykBlackS
, 100);
842 WMSetSliderValue(panel
->cmykBlackS
, 0);
843 WMSetSliderKnobThickness(panel
->cmykBlackS
, knobThickness
);
844 WMSetSliderAction(panel
->cmykBlackS
, cmykSliderCallback
, panel
);
850 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
851 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
852 RReleaseImage(image
);
855 W_PaintText(W_VIEW(panel
->cmykBlackS
), pixmap
->pixmap
, panel
->font12
,
856 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Black"), strlen(_("Black")));
858 wwarning(_("Color Panel: Could not allocate memory"));
860 WMSetSliderImage(panel
->cmykBlackS
, pixmap
);
861 WMReleasePixmap(pixmap
);
863 panel
->cmykBlackT
= WMCreateTextField(panel
->cmykFrm
);
864 WMResizeWidget(panel
->cmykBlackT
, 40, 18);
865 WMMoveWidget(panel
->cmykBlackT
, 146, 79);
866 WMSetTextFieldAlignment(panel
->cmykBlackT
, WALeft
);
867 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
868 WMTextDidEndEditingNotification
, panel
->cmykBlackT
);
869 /* End of CMYK Panel */
871 /* Widgets for HSB Panel */
872 panel
->hsbFrm
= WMCreateFrame(panel
->slidersFrm
);
873 WMSetFrameRelief(panel
->hsbFrm
, WRFlat
);
874 WMResizeWidget(panel
->hsbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
875 WMMoveWidget(panel
->hsbFrm
, 0, 34);
877 panel
->hsbHueS
= WMCreateSlider(panel
->hsbFrm
);
878 WMResizeWidget(panel
->hsbHueS
, 141, 16);
879 WMMoveWidget(panel
->hsbHueS
, 2, 14);
880 WMSetSliderMinValue(panel
->hsbHueS
, 0);
881 WMSetSliderMaxValue(panel
->hsbHueS
, 359);
882 WMSetSliderKnobThickness(panel
->hsbHueS
, knobThickness
);
883 WMSetSliderAction(panel
->hsbHueS
, hsbSliderCallback
, panel
);
885 panel
->hsbHueT
= WMCreateTextField(panel
->hsbFrm
);
886 WMResizeWidget(panel
->hsbHueT
, 40, 18);
887 WMMoveWidget(panel
->hsbHueT
, 146, 13);
888 WMSetTextFieldAlignment(panel
->hsbHueT
, WALeft
);
889 WMAddNotificationObserver(hsbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->hsbHueT
);
891 panel
->hsbSaturationS
= WMCreateSlider(panel
->hsbFrm
);
892 WMResizeWidget(panel
->hsbSaturationS
, 141, 16);
893 WMMoveWidget(panel
->hsbSaturationS
, 2, 36);
894 WMSetSliderMinValue(panel
->hsbSaturationS
, 0);
895 WMSetSliderMaxValue(panel
->hsbSaturationS
, 100);
896 WMSetSliderKnobThickness(panel
->hsbSaturationS
, knobThickness
);
897 WMSetSliderAction(panel
->hsbSaturationS
, hsbSliderCallback
, panel
);
899 panel
->hsbSaturationT
= WMCreateTextField(panel
->hsbFrm
);
900 WMResizeWidget(panel
->hsbSaturationT
, 40, 18);
901 WMMoveWidget(panel
->hsbSaturationT
, 146, 35);
902 WMSetTextFieldAlignment(panel
->hsbSaturationT
, WALeft
);
903 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
904 WMTextDidEndEditingNotification
, panel
->hsbSaturationT
);
906 panel
->hsbBrightnessS
= WMCreateSlider(panel
->hsbFrm
);
907 WMResizeWidget(panel
->hsbBrightnessS
, 141, 16);
908 WMMoveWidget(panel
->hsbBrightnessS
, 2, 58);
909 WMSetSliderMinValue(panel
->hsbBrightnessS
, 0);
910 WMSetSliderMaxValue(panel
->hsbBrightnessS
, 100);
911 WMSetSliderKnobThickness(panel
->hsbBrightnessS
, knobThickness
);
912 WMSetSliderAction(panel
->hsbBrightnessS
, hsbSliderCallback
, panel
);
914 panel
->hsbBrightnessT
= WMCreateTextField(panel
->hsbFrm
);
915 WMResizeWidget(panel
->hsbBrightnessT
, 40, 18);
916 WMMoveWidget(panel
->hsbBrightnessT
, 146, 57);
917 WMSetTextFieldAlignment(panel
->hsbBrightnessT
, WALeft
);
918 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
919 WMTextDidEndEditingNotification
, panel
->hsbBrightnessT
);
920 /* End of HSB Panel */
922 WMReleaseColor(textcolor
);
924 /* Widgets for the CustomPalette Panel */
925 panel
->customPaletteFrm
= WMCreateFrame(panel
->win
);
926 WMSetFrameRelief(panel
->customPaletteFrm
, WRFlat
);
927 WMResizeWidget(panel
->customPaletteFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
928 WMMoveWidget(panel
->customPaletteFrm
, 5, 80);
930 panel
->customPaletteHistoryBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
931 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, _("Spectrum"));
932 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
933 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1);
934 WMSetPopUpButtonAction(panel
->customPaletteHistoryBtn
, customPaletteHistoryCallback
, panel
);
935 WMResizeWidget(panel
->customPaletteHistoryBtn
, PWIDTH
- 8, 20);
936 WMMoveWidget(panel
->customPaletteHistoryBtn
, 0, 0);
938 panel
->customPaletteContentFrm
= WMCreateFrame(panel
->customPaletteFrm
);
939 WMSetFrameRelief(panel
->customPaletteContentFrm
, WRSunken
);
940 WMResizeWidget(panel
->customPaletteContentFrm
, PWIDTH
- 8, PHEIGHT
- 156);
941 WMMoveWidget(panel
->customPaletteContentFrm
, 0, 23);
943 panel
->customPaletteContentView
= W_CreateView(W_VIEW(panel
->customPaletteContentFrm
));
944 /* XXX Test if we can create a view */
945 W_ResizeView(panel
->customPaletteContentView
, customPaletteWidth
, customPaletteHeight
);
946 W_MoveView(panel
->customPaletteContentView
, 2, 2);
948 /* Create event handler to handle expose/click events in CustomPalette */
949 WMCreateEventHandler(panel
->customPaletteContentView
,
950 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
| LeaveWindowMask
|
951 ButtonMotionMask
, customPaletteHandleActionEvents
, panel
);
953 WMCreateEventHandler(panel
->customPaletteContentView
, ExposureMask
, customPaletteHandleEvents
, panel
);
955 panel
->customPaletteMenuBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
956 WMSetPopUpButtonPullsDown(panel
->customPaletteMenuBtn
, 1);
957 WMSetPopUpButtonText(panel
->customPaletteMenuBtn
, _("Palette"));
958 WMSetPopUpButtonAction(panel
->customPaletteMenuBtn
, customPaletteMenuCallback
, panel
);
959 WMResizeWidget(panel
->customPaletteMenuBtn
, PWIDTH
- 8, 20);
960 WMMoveWidget(panel
->customPaletteMenuBtn
, 0, PHEIGHT
- 130);
962 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from File..."));
963 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Rename..."));
964 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Remove"));
965 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Copy"));
966 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from Clipboard"));
968 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, 0);
969 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, 0);
970 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuCopy
, 0);
971 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuNewFromClipboard
, 0);
973 customRenderSpectrum(panel
);
974 panel
->currentPalette
= 0;
975 panel
->palx
= customPaletteWidth
/ 2;
976 panel
->paly
= customPaletteHeight
/ 2;
978 /* Widgets for the ColorList Panel */
979 panel
->colorListFrm
= WMCreateFrame(panel
->win
);
980 WMSetFrameRelief(panel
->colorListFrm
, WRFlat
);
981 WMResizeWidget(panel
->colorListFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
982 WMMoveWidget(panel
->colorListFrm
, 5, 80);
984 panel
->colorListHistoryBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
985 WMAddPopUpButtonItem(panel
->colorListHistoryBtn
, _("X11-Colors"));
986 WMSetPopUpButtonSelectedItem(panel
->colorListHistoryBtn
,
987 WMGetPopUpButtonNumberOfItems(panel
->colorListHistoryBtn
) - 1);
988 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
989 * colorListHistoryCallback, panel); */
990 WMResizeWidget(panel
->colorListHistoryBtn
, PWIDTH
- 8, 20);
991 WMMoveWidget(panel
->colorListHistoryBtn
, 0, 0);
993 panel
->colorListContentLst
= WMCreateList(panel
->colorListFrm
);
994 WMSetListAction(panel
->colorListContentLst
, colorListSelect
, panel
);
995 WMSetListUserDrawProc(panel
->colorListContentLst
, colorListPaintItem
);
996 WMResizeWidget(panel
->colorListContentLst
, PWIDTH
- 8, PHEIGHT
- 156);
997 WMMoveWidget(panel
->colorListContentLst
, 0, 23);
998 WMHangData(panel
->colorListContentLst
, panel
);
1000 panel
->colorListColorMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1001 WMSetPopUpButtonPullsDown(panel
->colorListColorMenuBtn
, 1);
1002 WMSetPopUpButtonText(panel
->colorListColorMenuBtn
, _("Color"));
1003 WMSetPopUpButtonAction(panel
->colorListColorMenuBtn
, colorListColorMenuCallback
, panel
);
1004 WMResizeWidget(panel
->colorListColorMenuBtn
, (PWIDTH
- 16) / 2, 20);
1005 WMMoveWidget(panel
->colorListColorMenuBtn
, 0, PHEIGHT
- 130);
1007 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Add..."));
1008 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Rename..."));
1009 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Remove"));
1011 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuAdd
, 0);
1012 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRename
, 0);
1013 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRemove
, 0);
1015 panel
->colorListListMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1016 WMSetPopUpButtonPullsDown(panel
->colorListListMenuBtn
, 1);
1017 WMSetPopUpButtonText(panel
->colorListListMenuBtn
, _("List"));
1018 WMSetPopUpButtonAction(panel
->colorListListMenuBtn
, colorListListMenuCallback
, panel
);
1019 WMResizeWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2, 20);
1020 WMMoveWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2 + 8, PHEIGHT
- 130);
1022 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("New..."));
1023 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Rename..."));
1024 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Remove"));
1026 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuAdd
, 0);
1027 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRename
, 0);
1028 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRemove
, 0);
1030 WMRealizeWidget(panel
->win
);
1031 WMMapSubwidgets(panel
->win
);
1033 WMMapSubwidgets(panel
->wheelFrm
);
1034 WMMapSubwidgets(panel
->slidersFrm
);
1035 WMMapSubwidgets(panel
->grayFrm
);
1036 WMMapSubwidgets(panel
->rgbFrm
);
1037 WMMapSubwidgets(panel
->cmykFrm
);
1038 WMMapSubwidgets(panel
->hsbFrm
);
1039 WMMapSubwidgets(panel
->customPaletteFrm
);
1040 WMMapSubwidgets(panel
->customPaletteContentFrm
);
1041 WMMapSubwidgets(panel
->colorListFrm
);
1043 /* Pixmap to indicate selection positions
1044 * wheelframe MUST be mapped.
1046 panel
->selectionImg
= XCreatePixmap(scrPtr
->display
, WMWidgetXID(panel
->win
), 4, 4, scrPtr
->depth
);
1047 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, bgc
, 0, 0, 4, 4);
1048 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, wgc
, 1, 1, 2, 2);
1050 readConfiguration(panel
);
1056 WMColorPanel
*WMGetColorPanel(WMScreen
* scrPtr
)
1058 WMColorPanel
*panel
;
1060 if (scrPtr
->sharedColorPanel
)
1061 return scrPtr
->sharedColorPanel
;
1063 panel
= makeColorPanel(scrPtr
, "colorPanel");
1065 scrPtr
->sharedColorPanel
= panel
;
1070 void WMFreeColorPanel(WMColorPanel
* panel
)
1072 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1074 if (panel
== scr
->sharedColorPanel
) {
1075 scr
->sharedColorPanel
= NULL
;
1081 WMRemoveNotificationObserver(panel
);
1082 WMUnmapWidget(panel
->win
);
1085 WMReleaseFont(panel
->font8
);
1086 WMReleaseFont(panel
->font12
);
1089 wheelDestroyMatrix(panel
->wheelMtrx
);
1090 if (panel
->wheelImg
)
1091 XFreePixmap(scr
->display
, panel
->wheelImg
);
1092 if (panel
->selectionImg
)
1093 XFreePixmap(scr
->display
, panel
->selectionImg
);
1094 if (panel
->selectionBackImg
)
1095 XFreePixmap(scr
->display
, panel
->selectionBackImg
);
1096 RReleaseImage(panel
->customPaletteImg
);
1099 if (panel
->lastBrowseDir
)
1100 wfree(panel
->lastBrowseDir
);
1101 if (panel
->configurationPath
)
1102 wfree(panel
->configurationPath
);
1104 WMDestroyWidget(panel
->win
);
1109 void WMCloseColorPanel(WMColorPanel
* panel
)
1111 WMFreeColorPanel(panel
);
1114 void WMShowColorPanel(WMColorPanel
* panel
)
1116 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1117 WMColor
*white
= WMWhiteColor(scr
);
1119 if (panel
->color
.set
== cpNone
)
1120 WMSetColorPanelColor(panel
, white
);
1121 WMReleaseColor(white
);
1123 if (panel
->mode
!= WMWheelModeColorPanel
)
1124 WMPerformButtonClick(panel
->wheelBtn
);
1126 WMMapWidget(panel
->win
);
1129 static void closeWindowCallback(WMWidget
* w
, void *data
)
1131 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
1133 WMCloseColorPanel(panel
);
1136 static void readConfiguration(W_ColorPanel
* panel
)
1138 /* XXX Doesn't take care of "invalid" files */
1142 struct stat stat_buf
;
1145 if (stat(panel
->configurationPath
, &stat_buf
) != 0) {
1146 if (mkdir(panel
->configurationPath
, S_IRWXU
| S_IRGRP
| S_IROTH
| S_IXGRP
| S_IXOTH
) != 0) {
1147 werror(_("Color Panel: Could not create directory %s needed"
1148 " to store configurations"), panel
->configurationPath
);
1149 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1150 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1151 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1152 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1154 _("Could not create ColorPanel configuration directory"),
1155 _("OK"), NULL
, NULL
);
1160 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1161 wwarning("%s: %s", _("Color Panel: Could not find file"), panel
->configurationPath
);
1165 while ((dp
= readdir(dPtr
)) != NULL
) {
1166 unsigned int perm_mask
;
1167 char *path
= wstrconcat(panel
->configurationPath
,
1170 if (dp
->d_name
[0] != '.') {
1171 item
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
1172 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1174 perm_mask
= (access(path
, R_OK
) == 0);
1175 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
, item
, perm_mask
);
1182 static void readXColors(W_ColorPanel
* panel
)
1187 for (entry
= rgbColors
; entry
->name
!= NULL
; entry
++) {
1188 item
= WMAddListItem(panel
->colorListContentLst
, entry
->name
);
1189 item
->clientData
= (void *)&(entry
->color
);
1193 void WMSetColorPanelPickerMode(WMColorPanel
* panel
, WMColorPanelMode mode
)
1195 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1197 if (mode
!= WMWheelModeColorPanel
) {
1198 WMUnmapWidget(panel
->wheelFrm
);
1199 if (panel
->selectionBackImg
) {
1200 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1201 panel
->selectionBackImg
= None
;
1204 if (mode
!= WMGrayModeColorPanel
)
1205 WMUnmapWidget(panel
->grayFrm
);
1206 if (mode
!= WMRGBModeColorPanel
)
1207 WMUnmapWidget(panel
->rgbFrm
);
1208 if (mode
!= WMCMYKModeColorPanel
)
1209 WMUnmapWidget(panel
->cmykFrm
);
1210 if (mode
!= WMHSBModeColorPanel
)
1211 WMUnmapWidget(panel
->hsbFrm
);
1212 if (mode
!= WMCustomPaletteModeColorPanel
) {
1213 WMUnmapWidget(panel
->customPaletteFrm
);
1214 if (panel
->selectionBackImg
) {
1215 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1216 panel
->selectionBackImg
= None
;
1219 if (mode
!= WMColorListModeColorPanel
)
1220 WMUnmapWidget(panel
->colorListFrm
);
1221 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1222 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1223 WMUnmapWidget(panel
->slidersFrm
);
1225 panel
->slidersmode
= mode
;
1227 if (mode
== WMWheelModeColorPanel
) {
1228 WMMapWidget(panel
->wheelFrm
);
1229 WMSetButtonSelected(panel
->wheelBtn
, True
);
1230 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1234 } else if (mode
== WMGrayModeColorPanel
) {
1235 WMMapWidget(panel
->slidersFrm
);
1236 WMSetButtonSelected(panel
->slidersBtn
, True
);
1237 WMMapWidget(panel
->grayFrm
);
1238 WMSetButtonSelected(panel
->grayBtn
, True
);
1239 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1240 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1242 } else if (mode
== WMRGBModeColorPanel
) {
1243 WMMapWidget(panel
->slidersFrm
);
1244 WMSetButtonSelected(panel
->slidersBtn
, True
);
1245 WMMapWidget(panel
->rgbFrm
);
1246 WMSetButtonSelected(panel
->rgbBtn
, True
);
1247 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1248 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1250 } else if (mode
== WMCMYKModeColorPanel
) {
1251 WMMapWidget(panel
->slidersFrm
);
1252 WMSetButtonSelected(panel
->slidersBtn
, True
);
1253 WMMapWidget(panel
->cmykFrm
);
1254 WMSetButtonSelected(panel
->cmykBtn
, True
);
1255 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1256 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1258 } else if (mode
== WMHSBModeColorPanel
) {
1259 WMMapWidget(panel
->slidersFrm
);
1260 WMSetButtonSelected(panel
->slidersBtn
, True
);
1261 WMMapWidget(panel
->hsbFrm
);
1262 WMSetButtonSelected(panel
->hsbBtn
, True
);
1263 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1264 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1266 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1267 WMMapWidget(panel
->customPaletteFrm
);
1268 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1269 customSetPalette(panel
);
1270 } else if (mode
== WMColorListModeColorPanel
) {
1271 WMMapWidget(panel
->colorListFrm
);
1272 WMSetButtonSelected(panel
->colorListBtn
, True
);
1278 WMColor
*WMGetColorPanelColor(WMColorPanel
* panel
)
1280 return WMGetColorWellColor(panel
->colorWell
);
1283 void WMSetColorPanelColor(WMColorPanel
* panel
, WMColor
* color
)
1285 WMSetColorWellColor(panel
->colorWell
, color
);
1287 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1288 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1289 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1290 panel
->color
.set
= cpRGB
;
1292 if (panel
->mode
== panel
->lastChanged
)
1293 panel
->lastChanged
= 0;
1295 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1298 static void updateSwatch(WMColorPanel
* panel
, CPColor color
)
1300 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1303 if (color
.set
!= cpRGB
)
1304 convertCPColor(&color
);
1306 panel
->color
= color
;
1308 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8, color
.rgb
.green
<< 8, color
.rgb
.blue
<< 8, True
);
1310 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1311 WMReleaseColor(wellcolor
);
1313 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1315 (*panel
->action
) (panel
, panel
->clientData
);
1317 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
, NULL
);
1321 static void modeButtonCallback(WMWidget
* w
, void *data
)
1323 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1325 if (w
== panel
->wheelBtn
)
1326 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1327 else if (w
== panel
->slidersBtn
)
1328 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1329 else if (w
== panel
->customPaletteBtn
)
1330 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1331 else if (w
== panel
->colorListBtn
)
1332 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1333 else if (w
== panel
->grayBtn
)
1334 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1335 else if (w
== panel
->rgbBtn
)
1336 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1337 else if (w
== panel
->cmykBtn
)
1338 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1339 else if (w
== panel
->hsbBtn
)
1340 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1343 /****************** Magnifying Cursor Functions *******************/
1345 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
)
1347 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1348 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1349 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1351 if (!(image
&& image
->data
)) {
1352 /* The image in panel->magnifyGlass->image does not exist yet.
1353 * Grab one from the screen (not beyond) and use it from now on.
1355 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1356 x
- Cursor_x_hot
, y
- Cursor_y_hot
, w
, h
, AllPlanes
, ZPixmap
)))
1357 wwarning(_("Color Panel: X failed request"));
1362 /* Coordinate correction for back pixmap
1363 * if magnifying glass is at screen-borders
1366 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1367 * Hatched area is beyond screen border.
1369 * |<-Cursor_x_hot->|
1370 * ________________|_____
1371 * |/ / / / / / /| | |
1372 * | / / / / / / |(x,y) |
1373 * |/_/_/_/_/_/_/|________|
1374 * |<----x0----->|<--w0-->|
1378 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1380 * Hatched area is beyond screen border
1382 * |<-Cursor_x_hot->|
1383 * ________________|_______________
1384 * | | | / / / / / /|
1385 * | (x,y)|/ / / / / / |
1386 * |___________________|_/_/_/_/_/_/|
1387 * |<-------w0-------->| |
1388 * |<---------------w--|----------->|
1393 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1394 x0
= Cursor_x_hot
- x
;
1398 if (displayWidth
- 1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1399 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1402 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1403 y0
= Cursor_y_hot
- y
;
1407 if (displayHeight
- 1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1408 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1410 /* end of coordinate correction */
1412 /* Grab an image from the screen, clipped if necessary,
1413 * and put it in the existing panel->magnifyGlass->image
1414 * with the corresponding clipping offset.
1416 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1417 x
- Cursor_x_hot
+ x0
, y
- Cursor_y_hot
+ y0
, w0
, h0
, AllPlanes
, ZPixmap
, image
, x0
, y0
))
1418 wwarning(_("Color Panel: X failed request"));
1423 static void magnifyGetImageStored(WMColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
)
1425 /* (x1, y1) = topleft corner of existing rectangle
1426 * (x2, y2) = topleft corner of new position
1429 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1430 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1432 const int dx
= abs(x2
- x1
), dy
= abs(y2
- y1
);
1434 const int x_min
= Cursor_x_hot
,
1435 y_min
= Cursor_y_hot
,
1436 x_max
= DisplayWidth(scr
->display
, scr
->screen
) - 1 -
1437 (Cursor_mask_width
- Cursor_x_hot
),
1438 y_max
= DisplayHeight(scr
->display
, scr
->screen
) - 1 - (Cursor_mask_height
- Cursor_y_hot
);
1440 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1441 return; /* No movement */
1453 width
= Cursor_mask_width
- dx
;
1454 height
= Cursor_mask_height
- dy
;
1456 /* If the traversed distance is larger than the size of the magnifying
1457 * glass contents, there is no need to do dirty rectangles. A whole new
1458 * rectangle can be grabbed (unless that rectangle falls partially
1460 * Destroying the image and setting it to NULL will achieve that later on.
1462 * Of course, grabbing an XImage beyond the borders of the screen will
1463 * cause trouble, this is considdered a special case. Part of the screen
1464 * is grabbed, but there is no need for dirty rectangles.
1466 if ((width
<= 0) || (height
<= 0)) {
1467 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1468 if (panel
->magnifyGlass
->image
)
1469 XDestroyImage(panel
->magnifyGlass
->image
);
1470 panel
->magnifyGlass
->image
= NULL
;
1473 if (panel
->magnifyGlass
->image
) {
1474 /* Get dirty rectangle from panel->magnifyGlass->image */
1475 panel
->magnifyGlass
->dirtyRect
=
1476 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1477 if (!panel
->magnifyGlass
->dirtyRect
) {
1478 wwarning(_("Color Panel: X failed request"));
1479 return; /* X returned a NULL from XSubImage */
1484 /* Get image from screen */
1485 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
, Cursor_mask_width
, Cursor_mask_height
);
1486 if (image
) { /* Only reassign if a *new* image was grabbed */
1487 panel
->magnifyGlass
->image
= image
;
1491 /* Copy previously stored rectangle on covered part of image */
1492 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1495 /* "width" and "height" are used as coordinates here,
1496 * and run from [0...width-1] and [0...height-1] respectively.
1500 old_height
= height
;
1502 for (; width
>= 0; width
--)
1503 for (height
= old_height
; height
>= 0; height
--)
1504 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1505 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1506 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1507 panel
->magnifyGlass
->dirtyRect
= NULL
;
1513 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
)
1515 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1520 unsigned long color
;
1522 if (!panel
->magnifyGlass
->image
)
1525 if (!panel
->magnifyGlass
->magPix
)
1529 * Copy an area of only 5x5 pixels from the center of the image.
1531 for (u
= 0; u
< 5; u
++) {
1532 for (v
= 0; v
< 5; v
++) {
1533 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1535 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1537 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1538 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1540 /* The center square must eventually be centered around the
1541 * hotspot. The image needs shifting to achieve this. The amount of
1542 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1545 * ^------- center of center square == Cursor_x_hot
1547 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1549 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1550 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1555 return panel
->magnifyGlass
->magPix
;
1557 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
, Cursor_mask_height
, scr
->depth
);
1561 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1562 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1564 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1565 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1566 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1567 /* (2,2) puts center pixel on center of glass */
1574 static WMView
*magnifyCreateView(W_ColorPanel
* panel
)
1576 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1579 magView
= W_CreateTopView(scr
);
1583 magView
->self
= panel
->win
;
1584 magView
->flags
.topLevel
= 1;
1585 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1586 magView
->attribs
.override_redirect
= True
;
1587 magView
->attribs
.save_under
= True
;
1589 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1591 W_RealizeView(magView
);
1596 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
)
1598 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1599 Pixmap magPixmap
, magPixmap2
;
1601 XColor fgColor
= { 0, 0, 0, 0, DoRed
| DoGreen
| DoBlue
, 0 };
1602 XColor bgColor
= { 0, 0xbf00, 0xa000, 0x5000, DoRed
| DoGreen
| DoBlue
, 0 };
1604 /* Cursor creation stuff */
1605 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1606 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1607 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1608 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1610 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1611 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1613 XFreePixmap(scr
->display
, magPixmap
);
1614 XFreePixmap(scr
->display
, magPixmap2
);
1616 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1618 /* Set up Pointer */
1619 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1620 PointerMotionMask
| ButtonPressMask
,
1621 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1626 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
)
1628 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1631 Pixmap pixmap
, clip_mask
;
1633 Window root_return
, child_return
;
1635 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1636 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1638 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1639 5 * 5 - 1, 5 * 5 - 1, scr
->depth
);
1641 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
, &x
, &y
, &u
, &v
, &mask
);
1643 panel
->magnifyGlass
->image
= NULL
;
1645 /* Clipmask to make magnified view-contents circular */
1647 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1648 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1650 /* Clip circle in glass cursor */
1651 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1652 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1655 XFreePixmap(scr
->display
, clip_mask
);
1657 /* Draw initial magnifying glass contents */
1658 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1660 pixmap
= magnifyCreatePixmap(panel
);
1661 XSetWindowBackgroundPixmap(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1662 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1663 XFlush(scr
->display
);
1666 XFreePixmap(scr
->display
, pixmap
);
1675 static void magnifyPutCursor(WMWidget
* w
, void *data
)
1677 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1678 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1682 WMPoint initialPosition
;
1684 /* Destroy wheelBackImg, so it'll update properly */
1685 if (panel
->selectionBackImg
) {
1686 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1687 panel
->selectionBackImg
= None
;
1690 /* Create magnifying glass */
1691 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1692 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1693 if (!panel
->magnifyGlass
->view
)
1696 initialPosition
= magnifyInitialize(panel
);
1697 panel
->magnifyGlass
->x
= initialPosition
.x
;
1698 panel
->magnifyGlass
->y
= initialPosition
.y
;
1700 W_MoveView(panel
->magnifyGlass
->view
,
1701 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1702 W_MapView(panel
->magnifyGlass
->view
);
1704 magCursor
= magnifyGrabPointer(panel
);
1706 while (panel
->magnifyGlass
->image
) {
1707 WMNextEvent(scr
->display
, &event
);
1709 /* Pack motion events */
1710 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1713 switch (event
.type
) {
1715 XDestroyImage(panel
->magnifyGlass
->image
);
1716 panel
->magnifyGlass
->image
= NULL
;
1718 if (event
.xbutton
.button
== Button1
) {
1719 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1720 panel
->color
.set
= cpRGB
;
1721 updateSwatch(panel
, panel
->color
);
1723 switch (panel
->mode
) {
1724 case WMWheelModeColorPanel
:
1729 case WMGrayModeColorPanel
:
1732 case WMRGBModeColorPanel
:
1735 case WMCMYKModeColorPanel
:
1738 case WMHSBModeColorPanel
:
1744 panel
->lastChanged
= panel
->mode
;
1746 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1750 while (XPending(event
.xmotion
.display
)) {
1752 XPeekEvent(event
.xmotion
.display
, &ev
);
1753 if (ev
.type
== MotionNotify
)
1754 XNextEvent(event
.xmotion
.display
, &event
);
1759 /* Get a "dirty rectangle" */
1760 magnifyGetImageStored(panel
,
1761 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1762 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1764 /* Update coordinates */
1765 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1766 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1769 W_MoveView(panel
->magnifyGlass
->view
,
1770 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1772 /* Put new image (with magn.) in view */
1773 pixmap
= magnifyCreatePixmap(panel
);
1774 if (pixmap
!= None
) {
1775 /* Change the window background */
1776 XSetWindowBackgroundPixmap(scr
->display
,
1777 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1778 /* Force an Expose (handled by X) */
1779 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1780 /* Synchronize the event queue, so the Expose is handled NOW */
1781 XFlush(scr
->display
);
1783 XFreePixmap(scr
->display
, pixmap
);
1788 /* Try XQueryPointer for this !!! It returns windows that the pointer
1789 * is over. Note: We found this solving the invisible donkey cap bug
1791 #if 0 /* As it is impossible to make this work in all cases,
1792 * we consider it confusing. Therefore we disabled it.
1794 case FocusOut
: /* fall through */
1797 * Color Panel window (panel->win) lost or received focus.
1798 * We need to update the pixmap in the magnifying glass.
1800 * BUG Doesn't work with focus switches between two windows
1801 * if none of them is the color panel.
1803 XUngrabPointer(scr
->display
, CurrentTime
);
1804 W_UnmapView(panel
->magnifyGlass
->view
);
1806 magnifyInitialize(panel
);
1808 W_MapView(panel
->magnifyGlass
->view
);
1809 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
,
1810 True
, PointerMotionMask
| ButtonPressMask
,
1811 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1815 WMHandleEvent(&event
);
1820 XUngrabPointer(scr
->display
, CurrentTime
);
1821 XFreeCursor(scr
->display
, magCursor
);
1823 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1824 panel
->magnifyGlass
->magPix
= None
;
1826 W_UnmapView(panel
->magnifyGlass
->view
);
1827 W_DestroyView(panel
->magnifyGlass
->view
);
1828 panel
->magnifyGlass
->view
= NULL
;
1830 wfree(panel
->magnifyGlass
);
1833 /****************** ColorWheel Functions ************************/
1835 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
)
1837 wheelMatrix
*matrix
= NULL
;
1840 assert((width
> 0) && (height
> 0));
1842 matrix
= wmalloc(sizeof(wheelMatrix
));
1843 matrix
->width
= width
;
1844 matrix
->height
= height
;
1846 for (i
= 0; i
< 3; i
++) {
1847 matrix
->data
[i
] = wmalloc(width
* height
* sizeof(unsigned char));
1853 static void wheelDestroyMatrix(wheelMatrix
* matrix
)
1860 for (i
= 0; i
< 3; i
++) {
1861 if (matrix
->data
[i
])
1862 wfree(matrix
->data
[i
]);
1867 static void wheelInitMatrix(W_ColorPanel
* panel
)
1871 unsigned char *rp
, *gp
, *bp
;
1877 const int cw_halfsize
= (colorWheelSize
+ 4) / 2,
1878 cw_sqsize
= (colorWheelSize
+ 4) * (colorWheelSize
+ 4), uchar_shift
= getShift(sizeof(unsigned char));
1880 if (!panel
->wheelMtrx
)
1883 cpColor
.hsv
.value
= 255;
1884 cpColor
.set
= cpHSV
;
1887 ofs
[1] = -(colorWheelSize
+ 4);
1889 /* offsets are counterclockwise (in triangles).
1892 * _______________________________________
1893 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
1894 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
1895 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
1896 * o | | | | | | | | | | | | | | | | | | | | | [3]
1900 * |\ /| <-- triangles
1906 for (y
= 0; y
< cw_halfsize
; y
++) {
1907 for (x
= y
; x
< (colorWheelSize
+ 4 - y
); x
++) {
1908 /* (xcor, ycor) is (x,y) relative to center of matrix */
1909 xcor
= 2 * x
- 4 - colorWheelSize
;
1910 ycor
= 2 * y
- 4 - colorWheelSize
;
1912 /* RColor.saturation is unsigned char and will wrap after 255 */
1913 sat
= rint(255.0 * sqrt(xcor
* xcor
+ ycor
* ycor
) / colorWheelSize
);
1915 cpColor
.hsv
.saturation
= (unsigned char)sat
;
1917 ofs
[0]++; /* top quarter of matrix */
1918 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
1919 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
1920 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
1924 dhue
[0] = rint(atan((double)ycor
/ (double)xcor
) *
1925 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
1929 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
1930 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
1931 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
1932 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
1934 for (i
= 0; i
< 4; i
++) {
1935 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1936 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1937 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1939 cpColor
.hsv
.hue
= dhue
[i
];
1940 convertCPColor(&cpColor
);
1942 *rp
= (unsigned char)(cpColor
.rgb
.red
);
1943 *gp
= (unsigned char)(cpColor
.rgb
.green
);
1944 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
1947 for (i
= 0; i
< 4; i
++) {
1948 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1949 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1950 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1952 *rp
= (unsigned char)0;
1953 *gp
= (unsigned char)0;
1954 *bp
= (unsigned char)0;
1959 ofs
[0] += 2 * y
+ 1;
1960 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2 * y
);
1964 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
)
1969 for (i
= 0; i
< 256; i
++) {
1970 /* We divide by 128 in advance, and check whether that number divides
1971 * by 2 properly. If not, we add one to round the number correctly
1973 v
= (i
* maxvalue
) >> 7;
1974 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) + (v
& 0x01));
1978 static void wheelRender(W_ColorPanel
* panel
)
1980 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1985 unsigned long ofs
= 0;
1986 /*unsigned char shift = getShift(sizeof(unsigned char)); */
1988 image
= RCreateImage(colorWheelSize
+ 4, colorWheelSize
+ 4, True
);
1990 wwarning(_("Color Panel: Could not allocate memory"));
1996 /* TODO Make this transparent istead of gray */
1997 gray
.red
= gray
.blue
= 0xae;
2000 for (y
= 0; y
< colorWheelSize
+ 4; y
++) {
2001 for (x
= 0; x
< colorWheelSize
+ 4; x
++) {
2002 if (wheelInsideColorWheel(panel
, ofs
)) {
2004 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]]);
2006 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]]);
2008 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]]);
2011 *(ptr
++) = (unsigned char)(gray
.red
);
2012 *(ptr
++) = (unsigned char)(gray
.green
);
2013 *(ptr
++) = (unsigned char)(gray
.blue
);
2020 if (panel
->wheelImg
)
2021 XFreePixmap(scr
->display
, panel
->wheelImg
);
2023 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2024 RReleaseImage(image
);
2026 /* Check if backimage exists. If it doesn't, allocate and fill it */
2027 if (!panel
->selectionBackImg
) {
2028 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2029 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2030 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2031 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2032 /* -2 is hot spot correction */
2036 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
)
2038 return ((panel
->wheelMtrx
->data
[0][ofs
] != 0) &&
2039 (panel
->wheelMtrx
->data
[1][ofs
] != 0) && (panel
->wheelMtrx
->data
[2][ofs
] != 0));
2042 static void wheelPaint(W_ColorPanel
* panel
)
2044 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2046 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->wheelView
->window
,
2047 scr
->copyGC
, 0, 0, colorWheelSize
+ 4, colorWheelSize
+ 4, 0, 0);
2049 /* Draw selection image */
2050 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2051 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2054 static void wheelHandleEvents(XEvent
* event
, void *data
)
2056 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2058 switch (event
->type
) {
2060 if (event
->xexpose
.count
!= 0) /* TODO Improve */
2067 static void wheelHandleActionEvents(XEvent
* event
, void *data
)
2069 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2071 switch (event
->type
) {
2073 if (getPickerPart(panel
, event
->xbutton
.x
, event
->xbutton
.y
) == COLORWHEEL_PART
) {
2075 panel
->lastChanged
= WMWheelModeColorPanel
;
2076 panel
->flags
.dragging
= 1;
2078 wheelPositionSelection(panel
, event
->xbutton
.x
, event
->xbutton
.y
);
2083 panel
->flags
.dragging
= 0;
2084 if (!panel
->flags
.continuous
) {
2086 (*panel
->action
) (panel
, panel
->clientData
);
2091 if (panel
->flags
.dragging
) {
2092 if (getPickerPart(panel
, event
->xmotion
.x
, event
->xmotion
.y
) == COLORWHEEL_PART
) {
2093 wheelPositionSelection(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2095 wheelPositionSelectionOutBounds(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2101 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
)
2109 if (panel
->mode
== WMWheelModeColorPanel
) {
2110 if ((lx
>= 2) && (lx
<= 2 + colorWheelSize
) && (ly
>= 2) && (ly
<= 2 + colorWheelSize
)) {
2112 ofs
= ly
* panel
->wheelMtrx
->width
+ lx
;
2114 if (wheelInsideColorWheel(panel
, ofs
))
2115 return COLORWHEEL_PART
;
2119 if (panel
->mode
== WMCustomPaletteModeColorPanel
) {
2120 if ((lx
>= 2) && (lx
< customPaletteWidth
- 2) && (ly
>= 2) && (ly
< customPaletteHeight
- 2)) {
2121 return CUSTOMPALETTE_PART
;
2128 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
)
2132 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2134 value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2136 wheelCalculateValues(panel
, value
);
2138 if (panel
->color
.set
== cpRGB
) {
2139 convertCPColor(&panel
->color
);
2140 panel
->color
.set
= cpHSV
;
2143 panel
->color
.hsv
.value
= value
;
2147 wheelUpdateSelection(panel
);
2150 static void wheelUpdateSelection(W_ColorPanel
* panel
)
2152 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2154 updateSwatch(panel
, panel
->color
);
2155 panel
->lastChanged
= WMWheelModeColorPanel
;
2157 /* Redraw color selector (and make a backup of the part it will cover) */
2158 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2159 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2160 /* "-2" is correction for hotspot location */
2161 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2162 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2166 static void wheelUndrawSelection(W_ColorPanel
* panel
)
2168 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2170 XCopyArea(scr
->display
, panel
->selectionBackImg
, panel
->wheelView
->window
,
2171 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2175 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2177 unsigned long ofs
= (y
* panel
->wheelMtrx
->width
) + x
;
2179 panel
->color
.rgb
.red
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]];
2181 panel
->color
.rgb
.green
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]];
2183 panel
->color
.rgb
.blue
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]];
2184 panel
->color
.set
= cpRGB
;
2186 wheelUndrawSelection(panel
);
2191 wheelUpdateSelection(panel
);
2192 wheelUpdateBrightnessGradientFromLocation(panel
);
2195 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2201 xcor
= x
* 2 - colorWheelSize
- 4;
2202 ycor
= y
* 2 - colorWheelSize
- 4;
2204 panel
->color
.hsv
.saturation
= 255;
2205 panel
->color
.hsv
.value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2208 hue
= rint(atan(-(double)ycor
/ (double)xcor
) * (180.0 / M_PI
));
2219 if ((xcor
> 0) && (ycor
> 0))
2222 panel
->color
.hsv
.hue
= hue
;
2223 panel
->color
.set
= cpHSV
;
2224 convertCPColor(&panel
->color
);
2226 wheelUndrawSelection(panel
);
2228 panel
->colx
= 2 + rint((colorWheelSize
* (1.0 + cos(panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2229 /* "+2" because of "colorWheelSize + 4" */
2230 panel
->coly
= 2 + rint((colorWheelSize
* (1.0 + sin(-panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2232 wheelUpdateSelection(panel
);
2233 cpColor
= panel
->color
;
2234 wheelUpdateBrightnessGradient(panel
, cpColor
);
2237 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
)
2242 ofs
= panel
->coly
* panel
->wheelMtrx
->width
+ panel
->colx
;
2244 from
.rgb
.red
= panel
->wheelMtrx
->data
[0][ofs
];
2245 from
.rgb
.green
= panel
->wheelMtrx
->data
[1][ofs
];
2246 from
.rgb
.blue
= panel
->wheelMtrx
->data
[2][ofs
];
2249 wheelUpdateBrightnessGradient(panel
, from
);
2252 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
)
2256 WMPixmap
*sliderPxmp
;
2258 to
.red
= to
.green
= to
.blue
= 0;
2260 if (topColor
.set
== cpHSV
)
2261 convertCPColor(&topColor
);
2263 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2264 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
), sliderImg
, 0);
2265 RReleaseImage(sliderImg
);
2266 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2267 WMReleasePixmap(sliderPxmp
);
2270 /****************** Grayscale Panel Functions ***************/
2272 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
)
2277 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2279 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2281 sprintf(tmp
, "%d", value
);
2283 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2284 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55 * value
);
2285 cpColor
.set
= cpRGB
;
2287 updateSwatch(panel
, cpColor
);
2288 panel
->lastChanged
= WMGrayModeColorPanel
;
2291 static void grayPresetButtonCallback(WMWidget
* w
, void *data
)
2297 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2300 if (w
== panel
->grayPresetBtn
[i
])
2305 value
= rint((100.0 * i
) / 6.0);
2306 sprintf(tmp
, "%d", value
);
2308 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2309 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * i
) / 6.0);
2310 cpColor
.set
= cpRGB
;
2312 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0 * i
) / 6.0));
2314 updateSwatch(panel
, cpColor
);
2315 panel
->lastChanged
= WMGrayModeColorPanel
;
2318 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
)
2323 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2325 value
= atoi(WMGetTextFieldText(panel
->grayBrightnessT
));
2331 sprintf(tmp
, "%d", value
);
2332 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2333 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2335 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * value
) / 100.0);
2336 cpColor
.set
= cpRGB
;
2338 updateSwatch(panel
, cpColor
);
2339 panel
->lastChanged
= WMGrayModeColorPanel
;
2342 /******************* RGB Panel Functions *****************/
2344 static void rgbSliderCallback(WMWidget
* w
, void *data
)
2349 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2351 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2352 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2353 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2355 sprintf(tmp
, "%d", value
[0]);
2356 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2357 sprintf(tmp
, "%d", value
[1]);
2358 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2359 sprintf(tmp
, "%d", value
[2]);
2360 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2362 cpColor
.rgb
.red
= value
[0];
2363 cpColor
.rgb
.green
= value
[1];
2364 cpColor
.rgb
.blue
= value
[2];
2365 cpColor
.set
= cpRGB
;
2367 updateSwatch(panel
, cpColor
);
2368 panel
->lastChanged
= WMRGBModeColorPanel
;
2371 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2377 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2379 value
[0] = atoi(WMGetTextFieldText(panel
->rgbRedT
));
2380 value
[1] = atoi(WMGetTextFieldText(panel
->rgbGreenT
));
2381 value
[2] = atoi(WMGetTextFieldText(panel
->rgbBlueT
));
2383 for (n
= 0; n
< 3; n
++) {
2390 sprintf(tmp
, "%d", value
[0]);
2391 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2392 sprintf(tmp
, "%d", value
[1]);
2393 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2394 sprintf(tmp
, "%d", value
[2]);
2395 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2397 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2398 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2399 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2401 cpColor
.rgb
.red
= value
[0];
2402 cpColor
.rgb
.green
= value
[1];
2403 cpColor
.rgb
.blue
= value
[2];
2404 cpColor
.set
= cpRGB
;
2406 updateSwatch(panel
, cpColor
);
2407 panel
->lastChanged
= WMRGBModeColorPanel
;
2410 /******************* CMYK Panel Functions *****************/
2412 static void cmykSliderCallback(WMWidget
* w
, void *data
)
2417 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2420 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2421 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2422 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2423 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2425 sprintf(tmp
, "%d", value
[0]);
2426 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2427 sprintf(tmp
, "%d", value
[1]);
2428 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2429 sprintf(tmp
, "%d", value
[2]);
2430 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2431 sprintf(tmp
, "%d", value
[3]);
2432 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2434 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2435 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2436 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2437 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2438 cpColor
.set
= cpRGB
;
2440 updateSwatch(panel
, cpColor
);
2441 panel
->lastChanged
= WMCMYKModeColorPanel
;
2444 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
)
2451 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2453 value
[0] = atoi(WMGetTextFieldText(panel
->cmykCyanT
));
2454 value
[1] = atoi(WMGetTextFieldText(panel
->cmykMagentaT
));
2455 value
[2] = atoi(WMGetTextFieldText(panel
->cmykYellowT
));
2456 value
[3] = atoi(WMGetTextFieldText(panel
->cmykBlackT
));
2458 for (n
= 0; n
< 4; n
++) {
2465 sprintf(tmp
, "%d", value
[0]);
2466 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2468 sprintf(tmp
, "%d", value
[1]);
2469 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2471 sprintf(tmp
, "%d", value
[2]);
2472 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2474 sprintf(tmp
, "%d", value
[3]);
2475 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2477 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2478 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2479 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2480 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2482 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2483 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2484 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2485 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2486 cpColor
.set
= cpRGB
;
2488 updateSwatch(panel
, cpColor
);
2489 panel
->lastChanged
= WMCMYKModeColorPanel
;
2492 /********************** HSB Panel Functions ***********************/
2494 static void hsbSliderCallback(WMWidget
* w
, void *data
)
2499 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2501 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2502 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2503 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2505 sprintf(tmp
, "%d", value
[0]);
2506 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2507 sprintf(tmp
, "%d", value
[1]);
2508 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2509 sprintf(tmp
, "%d", value
[2]);
2510 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2512 cpColor
.hsv
.hue
= value
[0];
2513 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2514 cpColor
.hsv
.value
= value
[2] * 2.55;
2515 cpColor
.set
= cpHSV
;
2517 convertCPColor(&cpColor
);
2519 panel
->lastChanged
= WMHSBModeColorPanel
;
2520 updateSwatch(panel
, cpColor
);
2522 if (w
!= panel
->hsbBrightnessS
)
2523 hsbUpdateBrightnessGradient(panel
);
2524 if (w
!= panel
->hsbSaturationS
)
2525 hsbUpdateSaturationGradient(panel
);
2526 if (w
!= panel
->hsbHueS
)
2527 hsbUpdateHueGradient(panel
);
2530 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2536 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2538 value
[0] = atoi(WMGetTextFieldText(panel
->hsbHueT
));
2539 value
[1] = atoi(WMGetTextFieldText(panel
->hsbSaturationT
));
2540 value
[2] = atoi(WMGetTextFieldText(panel
->hsbBrightnessT
));
2547 for (n
= 1; n
< 3; n
++) {
2554 sprintf(tmp
, "%d", value
[0]);
2555 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2556 sprintf(tmp
, "%d", value
[1]);
2557 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2558 sprintf(tmp
, "%d", value
[2]);
2559 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2561 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2562 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2563 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2565 cpColor
.hsv
.hue
= value
[0];
2566 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2567 cpColor
.hsv
.value
= value
[2] * 2.55;
2568 cpColor
.set
= cpHSV
;
2570 convertCPColor(&cpColor
);
2572 panel
->lastChanged
= WMHSBModeColorPanel
;
2573 updateSwatch(panel
, cpColor
);
2575 hsbUpdateBrightnessGradient(panel
);
2576 hsbUpdateSaturationGradient(panel
);
2577 hsbUpdateHueGradient(panel
);
2580 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
)
2582 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2586 WMPixmap
*sliderPxmp
;
2588 from
.red
= from
.green
= from
.blue
= 0;
2589 to
.hsv
= panel
->color
.hsv
;
2593 convertCPColor(&to
);
2595 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2596 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2597 RReleaseImage(sliderImg
);
2600 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2601 panel
->font12
, 2, 0, 100, WALeft
, scr
->white
,
2602 False
, _("Brightness"), strlen(_("Brightness")));
2604 wwarning(_("Color Panel: Could not allocate memory"));
2606 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2607 WMReleasePixmap(sliderPxmp
);
2610 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
)
2612 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2616 WMPixmap
*sliderPxmp
;
2618 from
.hsv
= panel
->color
.hsv
;
2619 from
.hsv
.saturation
= 0;
2621 convertCPColor(&from
);
2623 to
.hsv
= panel
->color
.hsv
;
2624 to
.hsv
.saturation
= 255;
2626 convertCPColor(&to
);
2628 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
), RGRD_HORIZONTAL
);
2629 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2630 RReleaseImage(sliderImg
);
2633 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2634 panel
->font12
, 2, 0, 100, WALeft
,
2635 from
.hsv
.value
< 128 ? scr
->white
: scr
->black
, False
,
2636 _("Saturation"), strlen(_("Saturation")));
2638 wwarning(_("Color Panel: Could not allocate memory"));
2640 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2641 WMReleasePixmap(sliderPxmp
);
2644 static void hsbUpdateHueGradient(W_ColorPanel
* panel
)
2646 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2647 RColor
**colors
= NULL
;
2650 WMPixmap
*sliderPxmp
;
2653 hsvcolor
= panel
->color
.hsv
;
2655 colors
= wmalloc(sizeof(RColor
*) * (8));
2656 for (i
= 0; i
< 7; i
++) {
2657 hsvcolor
.hue
= (360 * i
) / 6;
2658 colors
[i
] = wmalloc(sizeof(RColor
));
2659 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2663 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2664 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2665 RReleaseImage(sliderImg
);
2668 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2669 panel
->font12
, 2, 0, 100, WALeft
,
2670 hsvcolor
.value
< 128 ? scr
->white
: scr
->black
, False
, _("Hue"), strlen(_("Hue")));
2672 wwarning(_("Color Panel: Could not allocate memory"));
2674 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2675 WMReleasePixmap(sliderPxmp
);
2677 for (i
= 0; i
< 7; i
++)
2683 /*************** Custom Palette Functions ****************/
2685 static void customRenderSpectrum(W_ColorPanel
* panel
)
2692 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, False
);
2694 ptr
= spectrum
->data
;
2696 for (y
= 0; y
< SPECTRUM_HEIGHT
; y
++) {
2697 cpColor
.hsv
.hue
= y
;
2698 cpColor
.hsv
.saturation
= 0;
2699 cpColor
.hsv
.value
= 255;
2700 cpColor
.set
= cpHSV
;
2702 for (x
= 0; x
< SPECTRUM_WIDTH
; x
++) {
2703 convertCPColor(&cpColor
);
2705 *(ptr
++) = (unsigned char)cpColor
.rgb
.red
;
2706 *(ptr
++) = (unsigned char)cpColor
.rgb
.green
;
2707 *(ptr
++) = (unsigned char)cpColor
.rgb
.blue
;
2709 if (x
< (SPECTRUM_WIDTH
/ 2))
2710 cpColor
.hsv
.saturation
++;
2712 if (x
> (SPECTRUM_WIDTH
/ 2))
2713 cpColor
.hsv
.value
--;
2716 if (panel
->customPaletteImg
) {
2717 RReleaseImage(panel
->customPaletteImg
);
2718 panel
->customPaletteImg
= NULL
;
2720 panel
->customPaletteImg
= spectrum
;
2723 static void customSetPalette(W_ColorPanel
* panel
)
2725 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2729 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
, customPaletteHeight
, scr
->depth
);
2730 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
, customPaletteHeight
);
2731 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2732 RReleaseImage(scaledImg
);
2734 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2735 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2737 /* Check backimage exists. If it doesn't, allocate and fill it */
2738 if (!panel
->selectionBackImg
) {
2739 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2740 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2743 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2744 panel
->palx
- 2, panel
->paly
- 2, 4, 4, 0, 0);
2745 XCopyArea(scr
->display
, panel
->selectionImg
,
2746 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2747 panel
->palx
- 2, panel
->paly
- 2);
2748 XFreePixmap(scr
->display
, image
);
2750 panel
->palXRatio
= (double)(panel
->customPaletteImg
->width
) / (double)(customPaletteWidth
);
2751 panel
->palYRatio
= (double)(panel
->customPaletteImg
->height
) / (double)(customPaletteHeight
);
2753 WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2756 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2758 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2761 /* undraw selection */
2762 XCopyArea(scr
->display
, panel
->selectionBackImg
,
2763 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2764 panel
->palx
- 2, panel
->paly
- 2);
2769 ofs
= (rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) * panel
->customPaletteImg
->width
) * 3;
2771 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[ofs
];
2772 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[ofs
+ 1];
2773 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[ofs
+ 2];
2774 panel
->color
.set
= cpRGB
;
2776 updateSwatch(panel
, panel
->color
);
2777 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
2779 /* Redraw color selector (and make a backup of the part it will cover) */
2780 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 */
2781 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4, panel
->palx
- 2, panel
->paly
- 2); /* see above */
2784 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2790 if (x
>= customPaletteWidth
)
2791 x
= customPaletteWidth
- 2;
2792 if (y
>= customPaletteHeight
)
2793 y
= customPaletteHeight
- 2;
2795 customPalettePositionSelection(panel
, x
, y
);
2798 static void customPaletteHandleEvents(XEvent
* event
, void *data
)
2800 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2802 switch (event
->type
) {
2804 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
2806 customSetPalette(panel
);
2811 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
)
2813 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2816 switch (event
->type
) {
2818 x
= event
->xbutton
.x
;
2819 y
= event
->xbutton
.y
;
2821 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2822 panel
->flags
.dragging
= 1;
2823 customPalettePositionSelection(panel
, x
, y
);
2828 panel
->flags
.dragging
= 0;
2829 if (!panel
->flags
.continuous
) {
2831 (*panel
->action
) (panel
, panel
->clientData
);
2836 x
= event
->xmotion
.x
;
2837 y
= event
->xmotion
.y
;
2839 if (panel
->flags
.dragging
) {
2840 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2841 customPalettePositionSelection(panel
, x
, y
);
2843 customPalettePositionSelectionOutBounds(panel
, x
, y
);
2849 static void customPaletteMenuCallback(WMWidget
* w
, void *data
)
2851 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2852 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
2855 case CPmenuNewFromFile
:
2856 customPaletteMenuNewFromFile(panel
);
2859 customPaletteMenuRename(panel
);
2862 customPaletteMenuRemove(panel
);
2866 case CPmenuNewFromClipboard
:
2871 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
)
2873 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2874 WMOpenPanel
*browseP
;
2876 char *filename
= NULL
;
2880 RImage
*tmpImg
= NULL
;
2882 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
, "\0") == 0))
2883 spath
= wexpandpath(wgethomedir());
2885 spath
= wexpandpath(panel
->lastBrowseDir
);
2887 browseP
= WMGetOpenPanel(scr
);
2888 WMSetFilePanelCanChooseDirectories(browseP
, 0);
2889 WMSetFilePanelCanChooseFiles(browseP
, 1);
2891 /* Get a filename */
2892 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
2893 _("Open Palette"), RSupportedFileFormats())) {
2894 filepath
= WMGetFilePanelFileName(browseP
);
2896 /* Get seperation position between path and filename */
2897 i
= strrchr(filepath
, '/') - filepath
+ 1;
2898 if (i
> strlen(filepath
))
2899 i
= strlen(filepath
);
2901 /* Store last browsed path */
2902 if (panel
->lastBrowseDir
)
2903 wfree(panel
->lastBrowseDir
);
2904 panel
->lastBrowseDir
= wmalloc((i
+ 1) * sizeof(char));
2905 strncpy(panel
->lastBrowseDir
, filepath
, i
);
2906 panel
->lastBrowseDir
[i
] = '\0';
2908 /* Get filename from path */
2909 filename
= wstrdup(filepath
+ i
);
2911 /* Check for duplicate files, and rename it if there are any */
2912 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2913 while (access(tmp
, F_OK
) == 0) {
2918 newName
= generateNewFilename(filename
);
2922 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2926 /* Copy image to $(gnustepdir)/Library/Colors/ &
2927 * Add filename to history menu */
2928 if (fetchFile(panel
->configurationPath
, filepath
, filename
) == 0) {
2930 /* filepath is a "local" path now the file has been copied */
2932 filepath
= wstrconcat(panel
->configurationPath
, filename
);
2934 /* load the image & add menu entries */
2935 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
2937 if (panel
->customPaletteImg
)
2938 RReleaseImage(panel
->customPaletteImg
);
2939 panel
->customPaletteImg
= tmpImg
;
2941 customSetPalette(panel
);
2942 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
2944 panel
->currentPalette
=
2945 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1;
2947 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
2948 panel
->currentPalette
);
2951 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2953 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
2954 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2955 _("Invalid file format !"), _("OK"), NULL
, NULL
);
2957 werror(_("can't remove file %s"), tmp
);
2958 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2959 _("Couldn't remove file from Configuration Directory !"),
2960 _("OK"), NULL
, NULL
);
2967 WMFreeFilePanel(browseP
);
2972 static void customPaletteMenuRename(W_ColorPanel
* panel
)
2974 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2975 char *toName
= NULL
;
2977 char *toPath
, *fromPath
;
2981 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2982 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
2984 toName
= WMRunInputPanel(scr
, panel
->win
, _("Rename"), _("Rename palette to:"),
2985 fromName
, _("OK"), _("Cancel"));
2989 /* As some people do certain stupid things... */
2990 if (strcmp(toName
, fromName
) == 0) {
2995 /* For normal people */
2996 fromPath
= wstrconcat(panel
->configurationPath
, fromName
);
2997 toPath
= wstrconcat(panel
->configurationPath
, toName
);
2999 if (access(toPath
, F_OK
) == 0) {
3000 /* Careful, this palette exists already */
3001 if (WMRunAlertPanel(scr
, panel
->win
, _("Warning"),
3002 _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"),
3004 /* "No" = 0, "Yes" = 1 */
3005 int items
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
3009 /* Remove from History list too */
3011 while ((index
< items
)
3013 (strcmp(WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, index
), toName
)
3017 if (index
< items
) {
3018 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, index
);
3032 if (rename(fromPath
, toPath
) != 0)
3033 werror(_("Couldn't rename palette %s to %s"), fromName
, toName
);
3035 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3036 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
, toName
);
3038 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3046 static void customPaletteMenuRemove(W_ColorPanel
* panel
)
3048 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3054 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3056 tmp
= wstrconcat(_("This will permanently remove the palette "),
3057 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3058 text
= wstrconcat(tmp
, _(".\n\nAre you sure you want to remove this palette ?"));
3061 choice
= WMRunAlertPanel(scr
, panel
->win
, _("Remove"), text
, _("Yes"), _("No"), NULL
);
3062 /* returns 0 (= "Yes") or 1 (="No") */
3067 tmp
= wstrconcat(panel
->configurationPath
,
3068 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3070 if (remove(tmp
) == 0) {
3071 /* item-1 always exists */
3072 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3074 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
, panel
);
3075 customSetPalette(panel
);
3077 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3080 werror(_("Couldn't remove palette %s"), tmp
);
3087 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
)
3089 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3090 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3094 unsigned char perm_mask
;
3096 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3097 if (item
== panel
->currentPalette
)
3101 customRenderSpectrum(panel
);
3103 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, False
);
3104 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, False
);
3106 /* Load file from configpath */
3107 filename
= wstrconcat(panel
->configurationPath
,
3108 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3110 /* If the file corresponding to the item does not exist,
3111 * remove it from the history list and select the next one.
3113 perm_mask
= (access(filename
, F_OK
) == 0);
3115 /* File does not exist */
3117 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3118 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3119 customPaletteHistoryCallback(w
, data
);
3124 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3126 if (panel
->customPaletteImg
) {
3127 RReleaseImage(panel
->customPaletteImg
);
3128 panel
->customPaletteImg
= NULL
;
3130 panel
->customPaletteImg
= tmp
;
3133 /* If the image is not writable, don't allow removing/renaming */
3134 perm_mask
= (access(filename
, W_OK
) == 0);
3135 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, perm_mask
);
3136 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, perm_mask
);
3140 customSetPalette(panel
);
3142 panel
->currentPalette
= item
;
3145 /************************* ColorList Panel Functions **********************/
3147 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
)
3149 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3150 Display
*dpy
= WMScreenDisplay(scr
);
3151 WMView
*view
= W_VIEW(lPtr
);
3152 RColor
*color
= (RColor
*) WMGetListItem(lPtr
, index
)->clientData
;
3153 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3154 int width
, height
, x
, y
;
3157 width
= rect
->size
.width
;
3158 height
= rect
->size
.height
;
3162 if (state
& WLDSSelected
)
3163 XFillRectangle(dpy
, d
, WMColorGC(scr
->white
), x
, y
, width
, height
);
3165 XFillRectangle(dpy
, d
, WMColorGC(view
->backColor
), x
, y
, width
, height
);
3167 fillColor
= WMCreateRGBColor(scr
, color
->red
<< 8, color
->green
<< 8, color
->blue
<< 8, True
);
3169 XFillRectangle(dpy
, d
, WMColorGC(fillColor
), x
, y
, 15, height
);
3170 WMReleaseColor(fillColor
);
3172 WMDrawString(scr
, d
, scr
->black
, panel
->font12
, x
+ 18, y
, text
, strlen(text
));
3175 static void colorListSelect(WMWidget
* w
, void *data
)
3177 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3180 cpColor
.rgb
= *((RColor
*) WMGetListSelectedItem(w
)->clientData
);
3181 cpColor
.set
= cpRGB
;
3183 panel
->lastChanged
= WMColorListModeColorPanel
;
3184 updateSwatch(panel
, cpColor
);
3187 static void colorListColorMenuCallback(WMWidget
* w
, void *data
)
3189 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3190 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3202 static void colorListListMenuCallback(WMWidget
* w
, void *data
)
3204 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3205 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3209 /* New Color List */
3210 colorListListMenuNew(panel
);
3219 static void colorListListMenuNew(W_ColorPanel
* panel
)
3224 /*************** Panel Initialisation Functions *****************/
3226 static void wheelInit(W_ColorPanel
* panel
)
3230 if (panel
->color
.set
!= cpHSV
)
3231 convertCPColor(&panel
->color
);
3233 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3235 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3236 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3237 cos(panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3238 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3239 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3240 sin(-panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3242 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3244 cpColor
= panel
->color
;
3245 cpColor
.hsv
.value
= 255;
3246 cpColor
.set
= cpHSV
;
3247 wheelUpdateBrightnessGradient(panel
, cpColor
);
3250 static void grayInit(W_ColorPanel
* panel
)
3255 if (panel
->color
.set
!= cpHSV
)
3256 convertCPColor(&panel
->color
);
3258 value
= rint(panel
->color
.hsv
.value
/ 2.55);
3259 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3261 sprintf(tmp
, "%d", value
);
3262 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3265 static void rgbInit(W_ColorPanel
* panel
)
3269 if (panel
->color
.set
!= cpRGB
)
3270 convertCPColor(&panel
->color
);
3272 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3273 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3274 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3276 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3277 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3278 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3279 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3280 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3281 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3284 static void cmykInit(W_ColorPanel
* panel
)
3289 if (panel
->color
.set
!= cpRGB
)
3290 convertCPColor(&panel
->color
);
3292 value
[0] = rint((255 - panel
->color
.rgb
.red
) / 2.55);
3293 value
[1] = rint((255 - panel
->color
.rgb
.green
) / 2.55);
3294 value
[2] = rint((255 - panel
->color
.rgb
.blue
) / 2.55);
3296 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3297 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3298 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3299 WMSetSliderValue(panel
->cmykBlackS
, 0);
3301 sprintf(tmp
, "%d", value
[0]);
3302 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3303 sprintf(tmp
, "%d", value
[1]);
3304 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3305 sprintf(tmp
, "%d", value
[2]);
3306 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3307 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3310 static void hsbInit(W_ColorPanel
* panel
)
3315 if (panel
->color
.set
!= cpHSV
)
3316 convertCPColor(&panel
->color
);
3318 value
[0] = panel
->color
.hsv
.hue
;
3319 value
[1] = rint(panel
->color
.hsv
.saturation
/ 2.55);
3320 value
[2] = rint(panel
->color
.hsv
.value
/ 2.55);
3322 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
3323 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
3324 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
3326 sprintf(tmp
, "%d", value
[0]);
3327 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3328 sprintf(tmp
, "%d", value
[1]);
3329 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3330 sprintf(tmp
, "%d", value
[2]);
3331 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3333 hsbUpdateBrightnessGradient(panel
);
3334 hsbUpdateSaturationGradient(panel
);
3335 hsbUpdateHueGradient(panel
);
3338 /************************** Common utility functions ************************/
3340 static int fetchFile(char *toPath
, char *srcFile
, char *destFile
)
3343 size_t nread
, nwritten
;
3347 RETRY( src
= fopen(srcFile
, "rb") )
3349 werror(_("Could not open %s"), srcFile
);
3353 dstpath
= wstrconcat(toPath
, destFile
);
3354 RETRY( dst
= fopen(dstpath
, "wb") )
3356 werror(_("Could not create %s"), dstpath
);
3358 RETRY( fclose(src
) )
3363 RETRY( nread
= fread(buf
, 1, sizeof(buf
), src
) )
3367 RETRY( nwritten
= fwrite(buf
, 1, nread
, dst
) )
3368 if (ferror(dst
) || feof(src
) || nread
!= nwritten
)
3373 if (ferror(src
) || ferror(dst
))
3376 RETRY( fclose(src
) )
3378 RETRY( fclose(dst
) )
3384 char *generateNewFilename(char *curName
)
3396 if (((ptr
= strrchr(ptr
, '{')) == 0) || sscanf(ptr
, "{%i}%c", &n
, &c
) != 1)
3397 return wstrconcat(curName
, " {1}");
3399 baseLen
= ptr
- curName
- 1;
3401 newName
= wmalloc(baseLen
+ 16);
3402 strncpy(newName
, curName
, baseLen
);
3404 snprintf(&newName
[baseLen
], 16, " {%i}", n
+ 1);
3409 void convertCPColor(CPColor
* color
)
3411 unsigned short old_hue
= 0;
3413 switch (color
->set
) {
3415 wwarning(_("Color Panel: Color unspecified"));
3418 old_hue
= color
->hsv
.hue
;
3419 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3421 /* In black the hue is undefined, and may change by conversion
3422 * Same for white. */
3423 if (((color
->rgb
.red
== 0) &&
3424 (color
->rgb
.green
== 0) &&
3425 (color
->rgb
.blue
== 0)) ||
3426 ((color
->rgb
.red
== 0) && (color
->rgb
.green
== 0) && (color
->rgb
.blue
== 255))
3428 color
->hsv
.hue
= old_hue
;
3431 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3436 #define ABS_SHIFT(val, shift) \
3437 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3439 RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
)
3442 XColor
*xcolor
= NULL
;
3444 xcolor
= wmalloc(sizeof(XColor
));
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;
3458 unsigned char getShift(unsigned char value
)
3460 unsigned char i
= -1;
3473 #ifdef SHAPE_WAS_DEFINED
3474 #undef SHAPE_WAS_DEFINED