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 # include <X11/extensions/shape.h>
50 char *WMColorPanelColorChangedNotification
= "WMColorPanelColorChangedNotification";
53 * Bitmaps for magnifying glass cursor
57 #define Cursor_x_hot 11
58 #define Cursor_y_hot 11
59 #define Cursor_width 32
60 #define Cursor_height 32
61 static unsigned char Cursor_bits
[] = {
62 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
63 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
64 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
65 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
66 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
67 0x00, 0x08, 0x00, 0x50, 0x00, 0x10, 0x00, 0x88, 0x00, 0x20, 0x00, 0x5c, 0x01, 0xc0, 0x81,
68 0x3b, 0x02, 0x00, 0x7e, 0x70, 0x05, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0xc0, 0x15, 0x00,
69 0x00, 0x80, 0x23, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x5c,
70 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x70
73 /* Cursor shape-mask */
74 #define Cursor_shape_width 32
75 #define Cursor_shape_height 32
76 static unsigned char Cursor_shape_bits
[] = {
77 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
78 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
79 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
80 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
81 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
82 0x00, 0x08, 0x00, 0x70, 0x00, 0x10, 0x00, 0xf8, 0x00, 0x20, 0x00, 0xfc, 0x01, 0xc0, 0x81,
83 0xfb, 0x03, 0x00, 0x7e, 0xf0, 0x07, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xc0, 0x1f, 0x00,
84 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfc,
85 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x70
88 /* Clip-mask for magnified pixels */
89 #define Cursor_mask_width 24
90 #define Cursor_mask_height 24
91 static unsigned char Cursor_mask_bits
[] = {
92 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07,
93 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
94 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
95 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f,
96 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f,
97 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00
100 typedef struct MovingView
{
101 WMView
*view
; /* The view this is all about */
102 XImage
*image
; /* What's under the view */
103 XImage
*dirtyRect
; /* Storage of overlapped image area */
104 Pixmap magPix
; /* Magnified part of pixmap */
105 RColor color
; /* Color of a pixel in the image */
106 int x
, y
; /* Position of view */
109 typedef struct CPColor
{
110 RColor rgb
; /* The RGB values of the color */
111 RHSVColor hsv
; /* The HSV values of the color */
112 enum { /* Which one was last set ? */
119 typedef struct WheelMatrix
{
120 unsigned int width
, height
; /* Size of the colorwheel */
121 unsigned char *data
[3]; /* Wheel data (R,G,B) */
122 unsigned char values
[256]; /* Precalculated values R,G & B = 0-255 */
125 typedef struct W_ColorPanel
{
133 WMColorWell
*colorWell
;
134 WMButton
*magnifyBtn
;
136 WMButton
*slidersBtn
;
137 WMButton
*customPaletteBtn
;
138 WMButton
*colorListBtn
;
140 /* Magnifying Glass */
141 MovingView
*magnifyGlass
;
143 /* ColorWheel Panel */
145 WMSlider
*wheelBrightnessS
;
150 WMFrame
*seperatorFrm
;
155 /* Gray Scale Panel */
159 WMSlider
*grayBrightnessS
;
160 WMTextField
*grayBrightnessT
;
161 WMButton
*grayPresetBtn
[7];
170 WMTextField
*rgbRedT
;
171 WMTextField
*rgbGreenT
;
172 WMTextField
*rgbBlueT
;
179 WMSlider
*cmykMagentaS
;
180 WMSlider
*cmykYellowS
;
181 WMSlider
*cmykBlackS
;
182 WMTextField
*cmykCyanT
;
183 WMTextField
*cmykMagentaT
;
184 WMTextField
*cmykYellowT
;
185 WMTextField
*cmykBlackT
;
190 WMSlider
*hsbSaturationS
;
191 WMSlider
*hsbBrightnessS
;
192 WMTextField
*hsbHueT
;
193 WMTextField
*hsbSaturationT
;
194 WMTextField
*hsbBrightnessT
;
196 /* Custom Palette Panel */
197 WMFrame
*customPaletteFrm
;
198 WMPopUpButton
*customPaletteHistoryBtn
;
199 WMFrame
*customPaletteContentFrm
;
200 WMPopUpButton
*customPaletteMenuBtn
;
201 WMView
*customPaletteContentView
;
203 /* Color List Panel */
204 WMFrame
*colorListFrm
;
205 WMPopUpButton
*colorListHistoryBtn
;
206 WMList
*colorListContentLst
;
207 WMPopUpButton
*colorListColorMenuBtn
;
208 WMPopUpButton
*colorListListMenuBtn
;
210 /* Look-Up Tables and Images */
211 wheelMatrix
*wheelMtrx
;
214 Pixmap selectionBackImg
;
215 RImage
*customPaletteImg
;
218 /* Common Data Fields */
219 CPColor color
; /* Current color */
220 WMColorPanelMode mode
; /* Current color selection mode */
221 WMColorPanelMode slidersmode
; /* Current color sel. mode sliders panel */
222 WMColorPanelMode lastChanged
; /* Panel that last changed the color */
223 int colx
, coly
; /* (x,y) of sel.-marker in WheelMode */
224 int palx
, paly
; /* (x,y) of sel.-marker in
226 double palXRatio
, palYRatio
; /* Ratios in x & y between
230 char *configurationPath
;
233 unsigned int continuous
:1;
234 unsigned int dragging
:1;
243 CPmenuNewFromClipboard
244 } customPaletteMenuItem
;
254 #define colorWheelSize 150
255 #define customPaletteWidth 182
256 #define customPaletteHeight 106
257 #define knobThickness 8
259 #define SPECTRUM_WIDTH 511
260 #define SPECTRUM_HEIGHT 360
262 #define COLORWHEEL_PART 1
263 #define CUSTOMPALETTE_PART 2
266 #define MAX_LENGTH 1024
269 #define M_PI 3.14159265358979323846
272 static char *generateNewFilename(const char *curName
);
273 static void convertCPColor(CPColor
* color
);
274 static RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
);
275 static unsigned char getShift(unsigned char value
);
277 static void modeButtonCallback(WMWidget
* w
, void *data
);
278 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
);
279 static void readConfiguration(W_ColorPanel
* panel
);
280 static void readXColors(W_ColorPanel
* panel
);
282 static void closeWindowCallback(WMWidget
* w
, void *data
);
284 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
);
285 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
);
286 static void magnifyPutCursor(WMWidget
* w
, void *data
);
287 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
);
288 static void magnifyGetImageStored(W_ColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
);
289 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
);
291 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
);
292 static void wheelDestroyMatrix(wheelMatrix
* matrix
);
293 static void wheelInitMatrix(W_ColorPanel
* panel
);
294 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
);
295 static void wheelRender(W_ColorPanel
* panel
);
296 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
);
297 static void wheelPaint(W_ColorPanel
* panel
);
299 static void wheelHandleEvents(XEvent
* event
, void *data
);
300 static void wheelHandleActionEvents(XEvent
* event
, void *data
);
301 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
);
302 static void wheelUpdateSelection(W_ColorPanel
* panel
);
303 static void wheelUndrawSelection(W_ColorPanel
* panel
);
305 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
);
306 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
307 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
);
308 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
);
310 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
);
311 static void grayPresetButtonCallback(WMWidget
* w
, void *data
);
312 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
);
314 static void rgbSliderCallback(WMWidget
* w
, void *data
);
315 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
);
317 static void cmykSliderCallback(WMWidget
* w
, void *data
);
318 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
);
320 static void hsbSliderCallback(WMWidget
* w
, void *data
);
321 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
);
322 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
);
323 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
);
324 static void hsbUpdateHueGradient(W_ColorPanel
* panel
);
326 static void customRenderSpectrum(W_ColorPanel
* panel
);
327 static void customSetPalette(W_ColorPanel
* panel
);
328 static void customPaletteHandleEvents(XEvent
* event
, void *data
);
329 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
);
330 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
);
331 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
332 static void customPaletteMenuCallback(WMWidget
* w
, void *data
);
333 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
);
335 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
);
336 static void customPaletteMenuRename(W_ColorPanel
* panel
);
337 static void customPaletteMenuRemove(W_ColorPanel
* panel
);
339 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
);
340 static void colorListSelect(WMWidget
* w
, void *data
);
341 static void colorListColorMenuCallback(WMWidget
* w
, void *data
);
342 static void colorListListMenuCallback(WMWidget
* w
, void *data
);
343 static void colorListListMenuNew(W_ColorPanel
* panel
);
345 static void wheelInit(W_ColorPanel
* panel
);
346 static void grayInit(W_ColorPanel
* panel
);
347 static void rgbInit(W_ColorPanel
* panel
);
348 static void cmykInit(W_ColorPanel
* panel
);
349 static void hsbInit(W_ColorPanel
* panel
);
351 void WMSetColorPanelAction(WMColorPanel
* panel
, WMAction2
* action
, void *data
)
353 panel
->action
= action
;
354 panel
->clientData
= data
;
357 static WMColorPanel
*makeColorPanel(WMScreen
* scrPtr
, const char *name
)
364 WMColor
*textcolor
, *graybuttoncolor
;
366 GC bgc
= WMColorGC(scrPtr
->black
);
367 GC wgc
= WMColorGC(scrPtr
->white
);
369 panel
= wmalloc(sizeof(WMColorPanel
));
370 panel
->color
.rgb
.red
= 0;
371 panel
->color
.rgb
.green
= 0;
372 panel
->color
.rgb
.blue
= 0;
373 panel
->color
.hsv
.hue
= 0;
374 panel
->color
.hsv
.saturation
= 0;
375 panel
->color
.hsv
.value
= 0;
376 panel
->color
.set
= cpNone
; /* Color has not been set yet */
378 panel
->font8
= WMSystemFontOfSize(scrPtr
, 8);
379 panel
->font12
= WMSystemFontOfSize(scrPtr
, 12);
381 panel
->win
= WMCreateWindowWithStyle(scrPtr
, name
,
382 WMTitledWindowMask
| WMClosableWindowMask
| WMResizableWindowMask
);
383 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
384 WMSetWindowTitle(panel
->win
, _("Colors"));
385 WMSetWindowCloseAction(panel
->win
, closeWindowCallback
, panel
);
387 /* Set Default ColorPanel Mode(s) */
388 panel
->mode
= WMWheelModeColorPanel
;
389 panel
->lastChanged
= 0;
390 panel
->slidersmode
= WMRGBModeColorPanel
;
391 panel
->configurationPath
= wstrconcat(wusergnusteppath(), "/Library/Colors/");
393 /* Some General Purpose Widgets */
394 panel
->colorWell
= WMCreateColorWell(panel
->win
);
395 WMResizeWidget(panel
->colorWell
, 134, 36);
396 WSetColorWellBordered(panel
->colorWell
, False
);
397 WMMoveWidget(panel
->colorWell
, 56, 4);
399 panel
->magnifyBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
400 WMResizeWidget(panel
->magnifyBtn
, 46, 36);
401 WMMoveWidget(panel
->magnifyBtn
, 6, 4);
402 WMSetButtonAction(panel
->magnifyBtn
, magnifyPutCursor
, panel
);
403 WMSetButtonImagePosition(panel
->magnifyBtn
, WIPImageOnly
);
404 WMSetButtonImage(panel
->magnifyBtn
, scrPtr
->magnifyIcon
);
406 panel
->wheelBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
407 WMResizeWidget(panel
->wheelBtn
, 46, 32);
408 WMMoveWidget(panel
->wheelBtn
, 6, 44);
409 WMSetButtonAction(panel
->wheelBtn
, modeButtonCallback
, panel
);
410 WMSetButtonImagePosition(panel
->wheelBtn
, WIPImageOnly
);
411 WMSetButtonImage(panel
->wheelBtn
, scrPtr
->wheelIcon
);
413 panel
->slidersBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
414 WMResizeWidget(panel
->slidersBtn
, 46, 32);
415 WMMoveWidget(panel
->slidersBtn
, 52, 44);
416 WMSetButtonAction(panel
->slidersBtn
, modeButtonCallback
, panel
);
417 WMSetButtonImagePosition(panel
->slidersBtn
, WIPImageOnly
);
418 WMSetButtonImage(panel
->slidersBtn
, scrPtr
->rgbIcon
);
420 panel
->customPaletteBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
421 WMResizeWidget(panel
->customPaletteBtn
, 46, 32);
422 WMMoveWidget(panel
->customPaletteBtn
, 98, 44);
423 WMSetButtonAction(panel
->customPaletteBtn
, modeButtonCallback
, panel
);
424 WMSetButtonImagePosition(panel
->customPaletteBtn
, WIPImageOnly
);
425 WMSetButtonImage(panel
->customPaletteBtn
, scrPtr
->customPaletteIcon
);
427 panel
->colorListBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
428 WMResizeWidget(panel
->colorListBtn
, 46, 32);
429 WMMoveWidget(panel
->colorListBtn
, 144, 44);
430 WMSetButtonAction(panel
->colorListBtn
, modeButtonCallback
, panel
);
431 WMSetButtonImagePosition(panel
->colorListBtn
, WIPImageOnly
);
432 WMSetButtonImage(panel
->colorListBtn
, scrPtr
->colorListIcon
);
434 /* Let's Group some of them together */
435 WMGroupButtons(panel
->wheelBtn
, panel
->slidersBtn
);
436 WMGroupButtons(panel
->wheelBtn
, panel
->customPaletteBtn
);
437 WMGroupButtons(panel
->wheelBtn
, panel
->colorListBtn
);
439 /* Widgets for the ColorWheel Panel */
440 panel
->wheelFrm
= WMCreateFrame(panel
->win
);
441 WMSetFrameRelief(panel
->wheelFrm
, WRFlat
);
442 WMResizeWidget(panel
->wheelFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
443 WMMoveWidget(panel
->wheelFrm
, 5, 80);
445 panel
->wheelView
= W_CreateView(W_VIEW(panel
->wheelFrm
));
446 /* XXX Can we create a view ? */
447 W_ResizeView(panel
->wheelView
, colorWheelSize
+ 4, colorWheelSize
+ 4);
448 W_MoveView(panel
->wheelView
, 0, 0);
450 /* Create an event handler to handle expose/click events in ColorWheel */
451 WMCreateEventHandler(panel
->wheelView
,
452 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
|
453 LeaveWindowMask
| ButtonMotionMask
, wheelHandleActionEvents
, panel
);
455 WMCreateEventHandler(panel
->wheelView
, ExposureMask
, wheelHandleEvents
, panel
);
457 panel
->wheelBrightnessS
= WMCreateSlider(panel
->wheelFrm
);
458 WMResizeWidget(panel
->wheelBrightnessS
, 16, 153);
459 WMMoveWidget(panel
->wheelBrightnessS
, 5 + colorWheelSize
+ 14, 1);
460 WMSetSliderMinValue(panel
->wheelBrightnessS
, 0);
461 WMSetSliderMaxValue(panel
->wheelBrightnessS
, 255);
462 WMSetSliderAction(panel
->wheelBrightnessS
, wheelBrightnessSliderCallback
, panel
);
463 WMSetSliderKnobThickness(panel
->wheelBrightnessS
, knobThickness
);
465 panel
->wheelMtrx
= wheelCreateMatrix(colorWheelSize
+ 4, colorWheelSize
+ 4);
466 wheelInitMatrix(panel
);
468 /* Widgets for the Slider Panels */
469 panel
->slidersFrm
= WMCreateFrame(panel
->win
);
470 WMSetFrameRelief(panel
->slidersFrm
, WRFlat
);
471 WMResizeWidget(panel
->slidersFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
472 WMMoveWidget(panel
->slidersFrm
, 4, 80);
474 panel
->seperatorFrm
= WMCreateFrame(panel
->slidersFrm
);
475 WMSetFrameRelief(panel
->seperatorFrm
, WRPushed
);
476 WMResizeWidget(panel
->seperatorFrm
, PWIDTH
- 8, 2);
477 WMMoveWidget(panel
->seperatorFrm
, 0, 1);
479 panel
->grayBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
480 WMResizeWidget(panel
->grayBtn
, 46, 24);
481 WMMoveWidget(panel
->grayBtn
, 1, 8);
482 WMSetButtonAction(panel
->grayBtn
, modeButtonCallback
, panel
);
483 WMSetButtonImagePosition(panel
->grayBtn
, WIPImageOnly
);
484 WMSetButtonImage(panel
->grayBtn
, scrPtr
->grayIcon
);
486 panel
->rgbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
487 WMResizeWidget(panel
->rgbBtn
, 46, 24);
488 WMMoveWidget(panel
->rgbBtn
, 47, 8);
489 WMSetButtonAction(panel
->rgbBtn
, modeButtonCallback
, panel
);
490 WMSetButtonImagePosition(panel
->rgbBtn
, WIPImageOnly
);
491 WMSetButtonImage(panel
->rgbBtn
, scrPtr
->rgbIcon
);
493 panel
->cmykBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
494 WMResizeWidget(panel
->cmykBtn
, 46, 24);
495 WMMoveWidget(panel
->cmykBtn
, 93, 8);
496 WMSetButtonAction(panel
->cmykBtn
, modeButtonCallback
, panel
);
497 WMSetButtonImagePosition(panel
->cmykBtn
, WIPImageOnly
);
498 WMSetButtonImage(panel
->cmykBtn
, scrPtr
->cmykIcon
);
500 panel
->hsbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
501 WMResizeWidget(panel
->hsbBtn
, 46, 24);
502 WMMoveWidget(panel
->hsbBtn
, 139, 8);
503 WMSetButtonAction(panel
->hsbBtn
, modeButtonCallback
, panel
);
504 WMSetButtonImagePosition(panel
->hsbBtn
, WIPImageOnly
);
505 WMSetButtonImage(panel
->hsbBtn
, scrPtr
->hsbIcon
);
507 /* Let's Group the Slider Panel Buttons Together */
508 WMGroupButtons(panel
->grayBtn
, panel
->rgbBtn
);
509 WMGroupButtons(panel
->grayBtn
, panel
->cmykBtn
);
510 WMGroupButtons(panel
->grayBtn
, panel
->hsbBtn
);
512 textcolor
= WMDarkGrayColor(scrPtr
);
514 /* Widgets for GrayScale Panel */
515 panel
->grayFrm
= WMCreateFrame(panel
->slidersFrm
);
516 WMSetFrameRelief(panel
->grayFrm
, WRFlat
);
517 WMResizeWidget(panel
->grayFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
518 WMMoveWidget(panel
->grayFrm
, 0, 34);
520 panel
->grayMinL
= WMCreateLabel(panel
->grayFrm
);
521 WMResizeWidget(panel
->grayMinL
, 20, 10);
522 WMMoveWidget(panel
->grayMinL
, 2, 2);
523 WMSetLabelText(panel
->grayMinL
, "0");
524 WMSetLabelTextAlignment(panel
->grayMinL
, WALeft
);
525 WMSetLabelTextColor(panel
->grayMinL
, textcolor
);
526 WMSetLabelFont(panel
->grayMinL
, panel
->font8
);
528 panel
->grayMaxL
= WMCreateLabel(panel
->grayFrm
);
529 WMResizeWidget(panel
->grayMaxL
, 40, 10);
530 WMMoveWidget(panel
->grayMaxL
, 104, 2);
531 WMSetLabelText(panel
->grayMaxL
, "100");
532 WMSetLabelTextAlignment(panel
->grayMaxL
, WARight
);
533 WMSetLabelTextColor(panel
->grayMaxL
, textcolor
);
534 WMSetLabelFont(panel
->grayMaxL
, panel
->font8
);
536 panel
->grayBrightnessS
= WMCreateSlider(panel
->grayFrm
);
537 WMResizeWidget(panel
->grayBrightnessS
, 141, 16);
538 WMMoveWidget(panel
->grayBrightnessS
, 2, 14);
539 WMSetSliderMinValue(panel
->grayBrightnessS
, 0);
540 WMSetSliderMaxValue(panel
->grayBrightnessS
, 100);
541 WMSetSliderKnobThickness(panel
->grayBrightnessS
, knobThickness
);
542 WMSetSliderAction(panel
->grayBrightnessS
, grayBrightnessSliderCallback
, panel
);
552 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
553 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
554 RReleaseImage(image
);
557 W_PaintText(W_VIEW(panel
->grayBrightnessS
), pixmap
->pixmap
,
558 panel
->font12
, 2, 0, 100, WALeft
, scrPtr
->white
,
559 False
, _("Brightness"), strlen(_("Brightness")));
561 wwarning(_("Color Panel: Could not allocate memory"));
563 WMSetSliderImage(panel
->grayBrightnessS
, pixmap
);
564 WMReleasePixmap(pixmap
);
566 panel
->grayBrightnessT
= WMCreateTextField(panel
->grayFrm
);
567 WMResizeWidget(panel
->grayBrightnessT
, 40, 18);
568 WMMoveWidget(panel
->grayBrightnessT
, 146, 13);
569 WMSetTextFieldAlignment(panel
->grayBrightnessT
, WALeft
);
570 WMAddNotificationObserver(grayBrightnessTextFieldCallback
, panel
,
571 WMTextDidEndEditingNotification
, panel
->grayBrightnessT
);
573 for (i
= 0; i
< 7; i
++) {
574 pixmap
= WMCreatePixmap(scrPtr
, 13, 13, scrPtr
->depth
, False
);
576 graybuttoncolor
= WMCreateRGBColor(scrPtr
, (255 / 6) * i
<< 8,
577 (255 / 6) * i
<< 8, (255 / 6) * i
<< 8, True
);
578 WMPaintColorSwatch(graybuttoncolor
, pixmap
->pixmap
, 0, 0, 15, 15);
579 WMReleaseColor(graybuttoncolor
);
581 panel
->grayPresetBtn
[i
] = WMCreateCommandButton(panel
->grayFrm
);
582 WMResizeWidget(panel
->grayPresetBtn
[i
], 20, 24);
583 WMMoveWidget(panel
->grayPresetBtn
[i
], 2 + (i
* 20), 34);
584 WMSetButtonAction(panel
->grayPresetBtn
[i
], grayPresetButtonCallback
, panel
);
585 WMSetButtonImage(panel
->grayPresetBtn
[i
], pixmap
);
586 WMSetButtonImagePosition(panel
->grayPresetBtn
[i
], WIPImageOnly
);
587 WMReleasePixmap(pixmap
);
591 /* End of GrayScale Panel */
593 /* Widgets for RGB Panel */
594 panel
->rgbFrm
= WMCreateFrame(panel
->slidersFrm
);
595 WMSetFrameRelief(panel
->rgbFrm
, WRFlat
);
596 WMResizeWidget(panel
->rgbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
597 WMMoveWidget(panel
->rgbFrm
, 0, 34);
599 panel
->rgbMinL
= WMCreateLabel(panel
->rgbFrm
);
600 WMResizeWidget(panel
->rgbMinL
, 20, 10);
601 WMMoveWidget(panel
->rgbMinL
, 2, 2);
602 WMSetLabelText(panel
->rgbMinL
, "0");
603 WMSetLabelTextAlignment(panel
->rgbMinL
, WALeft
);
604 WMSetLabelTextColor(panel
->rgbMinL
, textcolor
);
605 WMSetLabelFont(panel
->rgbMinL
, panel
->font8
);
607 panel
->rgbMaxL
= WMCreateLabel(panel
->rgbFrm
);
608 WMResizeWidget(panel
->rgbMaxL
, 40, 10);
609 WMMoveWidget(panel
->rgbMaxL
, 104, 2);
610 WMSetLabelText(panel
->rgbMaxL
, "255");
611 WMSetLabelTextAlignment(panel
->rgbMaxL
, WARight
);
612 WMSetLabelTextColor(panel
->rgbMaxL
, textcolor
);
613 WMSetLabelFont(panel
->rgbMaxL
, panel
->font8
);
615 panel
->rgbRedS
= WMCreateSlider(panel
->rgbFrm
);
616 WMResizeWidget(panel
->rgbRedS
, 141, 16);
617 WMMoveWidget(panel
->rgbRedS
, 2, 14);
618 WMSetSliderMinValue(panel
->rgbRedS
, 0);
619 WMSetSliderMaxValue(panel
->rgbRedS
, 255);
620 WMSetSliderKnobThickness(panel
->rgbRedS
, knobThickness
);
621 WMSetSliderAction(panel
->rgbRedS
, rgbSliderCallback
, panel
);
627 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
628 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
629 RReleaseImage(image
);
632 W_PaintText(W_VIEW(panel
->rgbRedS
), pixmap
->pixmap
, panel
->font12
,
633 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Red"), strlen(_("Red")));
635 wwarning(_("Color Panel: Could not allocate memory"));
637 WMSetSliderImage(panel
->rgbRedS
, pixmap
);
638 WMReleasePixmap(pixmap
);
640 panel
->rgbRedT
= WMCreateTextField(panel
->rgbFrm
);
641 WMResizeWidget(panel
->rgbRedT
, 40, 18);
642 WMMoveWidget(panel
->rgbRedT
, 146, 13);
643 WMSetTextFieldAlignment(panel
->rgbRedT
, WALeft
);
644 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbRedT
);
646 panel
->rgbGreenS
= WMCreateSlider(panel
->rgbFrm
);
647 WMResizeWidget(panel
->rgbGreenS
, 141, 16);
648 WMMoveWidget(panel
->rgbGreenS
, 2, 36);
649 WMSetSliderMinValue(panel
->rgbGreenS
, 0);
650 WMSetSliderMaxValue(panel
->rgbGreenS
, 255);
651 WMSetSliderKnobThickness(panel
->rgbGreenS
, knobThickness
);
652 WMSetSliderAction(panel
->rgbGreenS
, rgbSliderCallback
, panel
);
658 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
659 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
660 RReleaseImage(image
);
663 W_PaintText(W_VIEW(panel
->rgbGreenS
), pixmap
->pixmap
, panel
->font12
,
664 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Green"), strlen(_("Green")));
666 wwarning(_("Color Panel: Could not allocate memory"));
668 WMSetSliderImage(panel
->rgbGreenS
, pixmap
);
669 WMReleasePixmap(pixmap
);
671 panel
->rgbGreenT
= WMCreateTextField(panel
->rgbFrm
);
672 WMResizeWidget(panel
->rgbGreenT
, 40, 18);
673 WMMoveWidget(panel
->rgbGreenT
, 146, 35);
674 WMSetTextFieldAlignment(panel
->rgbGreenT
, WALeft
);
675 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbGreenT
);
677 panel
->rgbBlueS
= WMCreateSlider(panel
->rgbFrm
);
678 WMResizeWidget(panel
->rgbBlueS
, 141, 16);
679 WMMoveWidget(panel
->rgbBlueS
, 2, 58);
680 WMSetSliderMinValue(panel
->rgbBlueS
, 0);
681 WMSetSliderMaxValue(panel
->rgbBlueS
, 255);
682 WMSetSliderKnobThickness(panel
->rgbBlueS
, knobThickness
);
683 WMSetSliderAction(panel
->rgbBlueS
, rgbSliderCallback
, panel
);
689 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
690 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
691 RReleaseImage(image
);
694 W_PaintText(W_VIEW(panel
->rgbBlueS
), pixmap
->pixmap
, panel
->font12
,
695 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Blue"), strlen(_("Blue")));
697 wwarning(_("Color Panel: Could not allocate memory"));
699 WMSetSliderImage(panel
->rgbBlueS
, pixmap
);
700 WMReleasePixmap(pixmap
);
702 panel
->rgbBlueT
= WMCreateTextField(panel
->rgbFrm
);
703 WMResizeWidget(panel
->rgbBlueT
, 40, 18);
704 WMMoveWidget(panel
->rgbBlueT
, 146, 57);
705 WMSetTextFieldAlignment(panel
->rgbBlueT
, WALeft
);
706 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbBlueT
);
707 /* End of RGB Panel */
709 /* Widgets for CMYK Panel */
710 panel
->cmykFrm
= WMCreateFrame(panel
->slidersFrm
);
711 WMSetFrameRelief(panel
->cmykFrm
, WRFlat
);
712 WMResizeWidget(panel
->cmykFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
713 WMMoveWidget(panel
->cmykFrm
, 0, 34);
715 panel
->cmykMinL
= WMCreateLabel(panel
->cmykFrm
);
716 WMResizeWidget(panel
->cmykMinL
, 20, 10);
717 WMMoveWidget(panel
->cmykMinL
, 2, 2);
718 WMSetLabelText(panel
->cmykMinL
, "0");
719 WMSetLabelTextAlignment(panel
->cmykMinL
, WALeft
);
720 WMSetLabelTextColor(panel
->cmykMinL
, textcolor
);
721 WMSetLabelFont(panel
->cmykMinL
, panel
->font8
);
723 panel
->cmykMaxL
= WMCreateLabel(panel
->cmykFrm
);
724 WMResizeWidget(panel
->cmykMaxL
, 40, 10);
725 WMMoveWidget(panel
->cmykMaxL
, 104, 2);
726 WMSetLabelText(panel
->cmykMaxL
, "100");
727 WMSetLabelTextAlignment(panel
->cmykMaxL
, WARight
);
728 WMSetLabelTextColor(panel
->cmykMaxL
, textcolor
);
729 WMSetLabelFont(panel
->cmykMaxL
, panel
->font8
);
731 panel
->cmykCyanS
= WMCreateSlider(panel
->cmykFrm
);
732 WMResizeWidget(panel
->cmykCyanS
, 141, 16);
733 WMMoveWidget(panel
->cmykCyanS
, 2, 14);
734 WMSetSliderMinValue(panel
->cmykCyanS
, 0);
735 WMSetSliderMaxValue(panel
->cmykCyanS
, 100);
736 WMSetSliderKnobThickness(panel
->cmykCyanS
, knobThickness
);
737 WMSetSliderAction(panel
->cmykCyanS
, cmykSliderCallback
, panel
);
747 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
748 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
749 RReleaseImage(image
);
752 W_PaintText(W_VIEW(panel
->cmykCyanS
), pixmap
->pixmap
, panel
->font12
,
753 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Cyan"), strlen(_("Cyan")));
755 wwarning(_("Color Panel: Could not allocate memory"));
757 WMSetSliderImage(panel
->cmykCyanS
, pixmap
);
758 WMReleasePixmap(pixmap
);
760 panel
->cmykCyanT
= WMCreateTextField(panel
->cmykFrm
);
761 WMResizeWidget(panel
->cmykCyanT
, 40, 18);
762 WMMoveWidget(panel
->cmykCyanT
, 146, 13);
763 WMSetTextFieldAlignment(panel
->cmykCyanT
, WALeft
);
764 WMAddNotificationObserver(cmykTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->cmykCyanT
);
766 panel
->cmykMagentaS
= WMCreateSlider(panel
->cmykFrm
);
767 WMResizeWidget(panel
->cmykMagentaS
, 141, 16);
768 WMMoveWidget(panel
->cmykMagentaS
, 2, 36);
769 WMSetSliderMinValue(panel
->cmykMagentaS
, 0);
770 WMSetSliderMaxValue(panel
->cmykMagentaS
, 100);
771 WMSetSliderKnobThickness(panel
->cmykMagentaS
, knobThickness
);
772 WMSetSliderAction(panel
->cmykMagentaS
, cmykSliderCallback
, panel
);
778 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
779 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
780 RReleaseImage(image
);
783 W_PaintText(W_VIEW(panel
->cmykMagentaS
), pixmap
->pixmap
, panel
->font12
,
784 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Magenta"), strlen(_("Magenta")));
786 wwarning(_("Color Panel: Could not allocate memory"));
788 WMSetSliderImage(panel
->cmykMagentaS
, pixmap
);
789 WMReleasePixmap(pixmap
);
791 panel
->cmykMagentaT
= WMCreateTextField(panel
->cmykFrm
);
792 WMResizeWidget(panel
->cmykMagentaT
, 40, 18);
793 WMMoveWidget(panel
->cmykMagentaT
, 146, 35);
794 WMSetTextFieldAlignment(panel
->cmykMagentaT
, WALeft
);
795 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
796 WMTextDidEndEditingNotification
, panel
->cmykMagentaT
);
798 panel
->cmykYellowS
= WMCreateSlider(panel
->cmykFrm
);
799 WMResizeWidget(panel
->cmykYellowS
, 141, 16);
800 WMMoveWidget(panel
->cmykYellowS
, 2, 58);
801 WMSetSliderMinValue(panel
->cmykYellowS
, 0);
802 WMSetSliderMaxValue(panel
->cmykYellowS
, 100);
803 WMSetSliderKnobThickness(panel
->cmykYellowS
, knobThickness
);
804 WMSetSliderAction(panel
->cmykYellowS
, cmykSliderCallback
, panel
);
810 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
811 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
812 RReleaseImage(image
);
815 W_PaintText(W_VIEW(panel
->cmykYellowS
), pixmap
->pixmap
, panel
->font12
,
816 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Yellow"), strlen(_("Yellow")));
818 wwarning(_("Color Panel: Could not allocate memory"));
820 WMSetSliderImage(panel
->cmykYellowS
, pixmap
);
821 WMReleasePixmap(pixmap
);
823 panel
->cmykYellowT
= WMCreateTextField(panel
->cmykFrm
);
824 WMResizeWidget(panel
->cmykYellowT
, 40, 18);
825 WMMoveWidget(panel
->cmykYellowT
, 146, 57);
826 WMSetTextFieldAlignment(panel
->cmykYellowT
, WALeft
);
827 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
828 WMTextDidEndEditingNotification
, panel
->cmykYellowT
);
830 panel
->cmykBlackS
= WMCreateSlider(panel
->cmykFrm
);
831 WMResizeWidget(panel
->cmykBlackS
, 141, 16);
832 WMMoveWidget(panel
->cmykBlackS
, 2, 80);
833 WMSetSliderMinValue(panel
->cmykBlackS
, 0);
834 WMSetSliderMaxValue(panel
->cmykBlackS
, 100);
835 WMSetSliderValue(panel
->cmykBlackS
, 0);
836 WMSetSliderKnobThickness(panel
->cmykBlackS
, knobThickness
);
837 WMSetSliderAction(panel
->cmykBlackS
, cmykSliderCallback
, panel
);
843 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
844 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
845 RReleaseImage(image
);
848 W_PaintText(W_VIEW(panel
->cmykBlackS
), pixmap
->pixmap
, panel
->font12
,
849 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Black"), strlen(_("Black")));
851 wwarning(_("Color Panel: Could not allocate memory"));
853 WMSetSliderImage(panel
->cmykBlackS
, pixmap
);
854 WMReleasePixmap(pixmap
);
856 panel
->cmykBlackT
= WMCreateTextField(panel
->cmykFrm
);
857 WMResizeWidget(panel
->cmykBlackT
, 40, 18);
858 WMMoveWidget(panel
->cmykBlackT
, 146, 79);
859 WMSetTextFieldAlignment(panel
->cmykBlackT
, WALeft
);
860 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
861 WMTextDidEndEditingNotification
, panel
->cmykBlackT
);
862 /* End of CMYK Panel */
864 /* Widgets for HSB Panel */
865 panel
->hsbFrm
= WMCreateFrame(panel
->slidersFrm
);
866 WMSetFrameRelief(panel
->hsbFrm
, WRFlat
);
867 WMResizeWidget(panel
->hsbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
868 WMMoveWidget(panel
->hsbFrm
, 0, 34);
870 panel
->hsbHueS
= WMCreateSlider(panel
->hsbFrm
);
871 WMResizeWidget(panel
->hsbHueS
, 141, 16);
872 WMMoveWidget(panel
->hsbHueS
, 2, 14);
873 WMSetSliderMinValue(panel
->hsbHueS
, 0);
874 WMSetSliderMaxValue(panel
->hsbHueS
, 359);
875 WMSetSliderKnobThickness(panel
->hsbHueS
, knobThickness
);
876 WMSetSliderAction(panel
->hsbHueS
, hsbSliderCallback
, panel
);
878 panel
->hsbHueT
= WMCreateTextField(panel
->hsbFrm
);
879 WMResizeWidget(panel
->hsbHueT
, 40, 18);
880 WMMoveWidget(panel
->hsbHueT
, 146, 13);
881 WMSetTextFieldAlignment(panel
->hsbHueT
, WALeft
);
882 WMAddNotificationObserver(hsbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->hsbHueT
);
884 panel
->hsbSaturationS
= WMCreateSlider(panel
->hsbFrm
);
885 WMResizeWidget(panel
->hsbSaturationS
, 141, 16);
886 WMMoveWidget(panel
->hsbSaturationS
, 2, 36);
887 WMSetSliderMinValue(panel
->hsbSaturationS
, 0);
888 WMSetSliderMaxValue(panel
->hsbSaturationS
, 100);
889 WMSetSliderKnobThickness(panel
->hsbSaturationS
, knobThickness
);
890 WMSetSliderAction(panel
->hsbSaturationS
, hsbSliderCallback
, panel
);
892 panel
->hsbSaturationT
= WMCreateTextField(panel
->hsbFrm
);
893 WMResizeWidget(panel
->hsbSaturationT
, 40, 18);
894 WMMoveWidget(panel
->hsbSaturationT
, 146, 35);
895 WMSetTextFieldAlignment(panel
->hsbSaturationT
, WALeft
);
896 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
897 WMTextDidEndEditingNotification
, panel
->hsbSaturationT
);
899 panel
->hsbBrightnessS
= WMCreateSlider(panel
->hsbFrm
);
900 WMResizeWidget(panel
->hsbBrightnessS
, 141, 16);
901 WMMoveWidget(panel
->hsbBrightnessS
, 2, 58);
902 WMSetSliderMinValue(panel
->hsbBrightnessS
, 0);
903 WMSetSliderMaxValue(panel
->hsbBrightnessS
, 100);
904 WMSetSliderKnobThickness(panel
->hsbBrightnessS
, knobThickness
);
905 WMSetSliderAction(panel
->hsbBrightnessS
, hsbSliderCallback
, panel
);
907 panel
->hsbBrightnessT
= WMCreateTextField(panel
->hsbFrm
);
908 WMResizeWidget(panel
->hsbBrightnessT
, 40, 18);
909 WMMoveWidget(panel
->hsbBrightnessT
, 146, 57);
910 WMSetTextFieldAlignment(panel
->hsbBrightnessT
, WALeft
);
911 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
912 WMTextDidEndEditingNotification
, panel
->hsbBrightnessT
);
913 /* End of HSB Panel */
915 WMReleaseColor(textcolor
);
917 /* Widgets for the CustomPalette Panel */
918 panel
->customPaletteFrm
= WMCreateFrame(panel
->win
);
919 WMSetFrameRelief(panel
->customPaletteFrm
, WRFlat
);
920 WMResizeWidget(panel
->customPaletteFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
921 WMMoveWidget(panel
->customPaletteFrm
, 5, 80);
923 panel
->customPaletteHistoryBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
924 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, _("Spectrum"));
925 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
926 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1);
927 WMSetPopUpButtonAction(panel
->customPaletteHistoryBtn
, customPaletteHistoryCallback
, panel
);
928 WMResizeWidget(panel
->customPaletteHistoryBtn
, PWIDTH
- 8, 20);
929 WMMoveWidget(panel
->customPaletteHistoryBtn
, 0, 0);
931 panel
->customPaletteContentFrm
= WMCreateFrame(panel
->customPaletteFrm
);
932 WMSetFrameRelief(panel
->customPaletteContentFrm
, WRSunken
);
933 WMResizeWidget(panel
->customPaletteContentFrm
, PWIDTH
- 8, PHEIGHT
- 156);
934 WMMoveWidget(panel
->customPaletteContentFrm
, 0, 23);
936 panel
->customPaletteContentView
= W_CreateView(W_VIEW(panel
->customPaletteContentFrm
));
937 /* XXX Test if we can create a view */
938 W_ResizeView(panel
->customPaletteContentView
, customPaletteWidth
, customPaletteHeight
);
939 W_MoveView(panel
->customPaletteContentView
, 2, 2);
941 /* Create event handler to handle expose/click events in CustomPalette */
942 WMCreateEventHandler(panel
->customPaletteContentView
,
943 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
| LeaveWindowMask
|
944 ButtonMotionMask
, customPaletteHandleActionEvents
, panel
);
946 WMCreateEventHandler(panel
->customPaletteContentView
, ExposureMask
, customPaletteHandleEvents
, panel
);
948 panel
->customPaletteMenuBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
949 WMSetPopUpButtonPullsDown(panel
->customPaletteMenuBtn
, 1);
950 WMSetPopUpButtonText(panel
->customPaletteMenuBtn
, _("Palette"));
951 WMSetPopUpButtonAction(panel
->customPaletteMenuBtn
, customPaletteMenuCallback
, panel
);
952 WMResizeWidget(panel
->customPaletteMenuBtn
, PWIDTH
- 8, 20);
953 WMMoveWidget(panel
->customPaletteMenuBtn
, 0, PHEIGHT
- 130);
955 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from File..."));
956 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Rename..."));
957 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Remove"));
958 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Copy"));
959 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from Clipboard"));
961 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, 0);
962 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, 0);
963 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuCopy
, 0);
964 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuNewFromClipboard
, 0);
966 customRenderSpectrum(panel
);
967 panel
->currentPalette
= 0;
968 panel
->palx
= customPaletteWidth
/ 2;
969 panel
->paly
= customPaletteHeight
/ 2;
971 /* Widgets for the ColorList Panel */
972 panel
->colorListFrm
= WMCreateFrame(panel
->win
);
973 WMSetFrameRelief(panel
->colorListFrm
, WRFlat
);
974 WMResizeWidget(panel
->colorListFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
975 WMMoveWidget(panel
->colorListFrm
, 5, 80);
977 panel
->colorListHistoryBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
978 WMAddPopUpButtonItem(panel
->colorListHistoryBtn
, _("X11-Colors"));
979 WMSetPopUpButtonSelectedItem(panel
->colorListHistoryBtn
,
980 WMGetPopUpButtonNumberOfItems(panel
->colorListHistoryBtn
) - 1);
981 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
982 * colorListHistoryCallback, panel); */
983 WMResizeWidget(panel
->colorListHistoryBtn
, PWIDTH
- 8, 20);
984 WMMoveWidget(panel
->colorListHistoryBtn
, 0, 0);
986 panel
->colorListContentLst
= WMCreateList(panel
->colorListFrm
);
987 WMSetListAction(panel
->colorListContentLst
, colorListSelect
, panel
);
988 WMSetListUserDrawProc(panel
->colorListContentLst
, colorListPaintItem
);
989 WMResizeWidget(panel
->colorListContentLst
, PWIDTH
- 8, PHEIGHT
- 156);
990 WMMoveWidget(panel
->colorListContentLst
, 0, 23);
991 WMHangData(panel
->colorListContentLst
, panel
);
993 panel
->colorListColorMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
994 WMSetPopUpButtonPullsDown(panel
->colorListColorMenuBtn
, 1);
995 WMSetPopUpButtonText(panel
->colorListColorMenuBtn
, _("Color"));
996 WMSetPopUpButtonAction(panel
->colorListColorMenuBtn
, colorListColorMenuCallback
, panel
);
997 WMResizeWidget(panel
->colorListColorMenuBtn
, (PWIDTH
- 16) / 2, 20);
998 WMMoveWidget(panel
->colorListColorMenuBtn
, 0, PHEIGHT
- 130);
1000 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Add..."));
1001 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Rename..."));
1002 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Remove"));
1004 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuAdd
, 0);
1005 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRename
, 0);
1006 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRemove
, 0);
1008 panel
->colorListListMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1009 WMSetPopUpButtonPullsDown(panel
->colorListListMenuBtn
, 1);
1010 WMSetPopUpButtonText(panel
->colorListListMenuBtn
, _("List"));
1011 WMSetPopUpButtonAction(panel
->colorListListMenuBtn
, colorListListMenuCallback
, panel
);
1012 WMResizeWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2, 20);
1013 WMMoveWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2 + 8, PHEIGHT
- 130);
1015 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("New..."));
1016 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Rename..."));
1017 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Remove"));
1019 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuAdd
, 0);
1020 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRename
, 0);
1021 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRemove
, 0);
1023 WMRealizeWidget(panel
->win
);
1024 WMMapSubwidgets(panel
->win
);
1026 WMMapSubwidgets(panel
->wheelFrm
);
1027 WMMapSubwidgets(panel
->slidersFrm
);
1028 WMMapSubwidgets(panel
->grayFrm
);
1029 WMMapSubwidgets(panel
->rgbFrm
);
1030 WMMapSubwidgets(panel
->cmykFrm
);
1031 WMMapSubwidgets(panel
->hsbFrm
);
1032 WMMapSubwidgets(panel
->customPaletteFrm
);
1033 WMMapSubwidgets(panel
->customPaletteContentFrm
);
1034 WMMapSubwidgets(panel
->colorListFrm
);
1036 /* Pixmap to indicate selection positions
1037 * wheelframe MUST be mapped.
1039 panel
->selectionImg
= XCreatePixmap(scrPtr
->display
, WMWidgetXID(panel
->win
), 4, 4, scrPtr
->depth
);
1040 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, bgc
, 0, 0, 4, 4);
1041 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, wgc
, 1, 1, 2, 2);
1043 readConfiguration(panel
);
1049 WMColorPanel
*WMGetColorPanel(WMScreen
* scrPtr
)
1051 WMColorPanel
*panel
;
1053 if (scrPtr
->sharedColorPanel
)
1054 return scrPtr
->sharedColorPanel
;
1056 panel
= makeColorPanel(scrPtr
, "colorPanel");
1058 scrPtr
->sharedColorPanel
= panel
;
1063 void WMFreeColorPanel(WMColorPanel
* panel
)
1065 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1067 if (panel
== scr
->sharedColorPanel
) {
1068 scr
->sharedColorPanel
= NULL
;
1074 WMRemoveNotificationObserver(panel
);
1075 WMUnmapWidget(panel
->win
);
1078 WMReleaseFont(panel
->font8
);
1079 WMReleaseFont(panel
->font12
);
1082 wheelDestroyMatrix(panel
->wheelMtrx
);
1083 if (panel
->wheelImg
)
1084 XFreePixmap(scr
->display
, panel
->wheelImg
);
1085 if (panel
->selectionImg
)
1086 XFreePixmap(scr
->display
, panel
->selectionImg
);
1087 if (panel
->selectionBackImg
)
1088 XFreePixmap(scr
->display
, panel
->selectionBackImg
);
1089 RReleaseImage(panel
->customPaletteImg
);
1092 if (panel
->lastBrowseDir
)
1093 wfree(panel
->lastBrowseDir
);
1094 if (panel
->configurationPath
)
1095 wfree(panel
->configurationPath
);
1097 WMDestroyWidget(panel
->win
);
1102 void WMCloseColorPanel(WMColorPanel
* panel
)
1104 WMFreeColorPanel(panel
);
1107 void WMShowColorPanel(WMColorPanel
* panel
)
1109 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1110 WMColor
*white
= WMWhiteColor(scr
);
1112 if (panel
->color
.set
== cpNone
)
1113 WMSetColorPanelColor(panel
, white
);
1114 WMReleaseColor(white
);
1116 if (panel
->mode
!= WMWheelModeColorPanel
)
1117 WMPerformButtonClick(panel
->wheelBtn
);
1119 WMMapWidget(panel
->win
);
1122 static void closeWindowCallback(WMWidget
* w
, void *data
)
1124 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
1126 /* Parameter not used, but tell the compiler that it is ok */
1129 WMCloseColorPanel(panel
);
1132 static void readConfiguration(W_ColorPanel
* panel
)
1134 /* XXX Doesn't take care of "invalid" files */
1138 struct stat stat_buf
;
1141 if (stat(panel
->configurationPath
, &stat_buf
) != 0) {
1142 if (mkdir(panel
->configurationPath
, S_IRWXU
| S_IRGRP
| S_IROTH
| S_IXGRP
| S_IXOTH
) != 0) {
1143 werror(_("Color Panel: Could not create directory %s needed"
1144 " to store configurations"), panel
->configurationPath
);
1145 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1146 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1147 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1148 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1150 _("Could not create ColorPanel configuration directory"),
1151 _("OK"), NULL
, NULL
);
1156 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1157 wwarning("%s: %s", _("Color Panel: Could not find file"), panel
->configurationPath
);
1161 while ((dp
= readdir(dPtr
)) != NULL
) {
1162 unsigned int perm_mask
;
1163 char *path
= wstrconcat(panel
->configurationPath
,
1166 if (dp
->d_name
[0] != '.') {
1167 item
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
1168 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1170 perm_mask
= (access(path
, R_OK
) == 0);
1171 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
, item
, perm_mask
);
1178 static void readXColors(W_ColorPanel
* panel
)
1181 const RGBColor
*entry
;
1183 for (entry
= rgbColors
; entry
->name
!= NULL
; entry
++) {
1184 item
= WMAddListItem(panel
->colorListContentLst
, entry
->name
);
1185 item
->clientData
= (void *)&(entry
->color
);
1189 void WMSetColorPanelPickerMode(WMColorPanel
* panel
, WMColorPanelMode mode
)
1191 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1193 if (mode
!= WMWheelModeColorPanel
) {
1194 WMUnmapWidget(panel
->wheelFrm
);
1195 if (panel
->selectionBackImg
) {
1196 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1197 panel
->selectionBackImg
= None
;
1200 if (mode
!= WMGrayModeColorPanel
)
1201 WMUnmapWidget(panel
->grayFrm
);
1202 if (mode
!= WMRGBModeColorPanel
)
1203 WMUnmapWidget(panel
->rgbFrm
);
1204 if (mode
!= WMCMYKModeColorPanel
)
1205 WMUnmapWidget(panel
->cmykFrm
);
1206 if (mode
!= WMHSBModeColorPanel
)
1207 WMUnmapWidget(panel
->hsbFrm
);
1208 if (mode
!= WMCustomPaletteModeColorPanel
) {
1209 WMUnmapWidget(panel
->customPaletteFrm
);
1210 if (panel
->selectionBackImg
) {
1211 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1212 panel
->selectionBackImg
= None
;
1215 if (mode
!= WMColorListModeColorPanel
)
1216 WMUnmapWidget(panel
->colorListFrm
);
1217 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1218 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1219 WMUnmapWidget(panel
->slidersFrm
);
1221 panel
->slidersmode
= mode
;
1223 if (mode
== WMWheelModeColorPanel
) {
1224 WMMapWidget(panel
->wheelFrm
);
1225 WMSetButtonSelected(panel
->wheelBtn
, True
);
1226 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1230 } else if (mode
== WMGrayModeColorPanel
) {
1231 WMMapWidget(panel
->slidersFrm
);
1232 WMSetButtonSelected(panel
->slidersBtn
, True
);
1233 WMMapWidget(panel
->grayFrm
);
1234 WMSetButtonSelected(panel
->grayBtn
, True
);
1235 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1236 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1238 } else if (mode
== WMRGBModeColorPanel
) {
1239 WMMapWidget(panel
->slidersFrm
);
1240 WMSetButtonSelected(panel
->slidersBtn
, True
);
1241 WMMapWidget(panel
->rgbFrm
);
1242 WMSetButtonSelected(panel
->rgbBtn
, True
);
1243 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1244 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1246 } else if (mode
== WMCMYKModeColorPanel
) {
1247 WMMapWidget(panel
->slidersFrm
);
1248 WMSetButtonSelected(panel
->slidersBtn
, True
);
1249 WMMapWidget(panel
->cmykFrm
);
1250 WMSetButtonSelected(panel
->cmykBtn
, True
);
1251 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1252 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1254 } else if (mode
== WMHSBModeColorPanel
) {
1255 WMMapWidget(panel
->slidersFrm
);
1256 WMSetButtonSelected(panel
->slidersBtn
, True
);
1257 WMMapWidget(panel
->hsbFrm
);
1258 WMSetButtonSelected(panel
->hsbBtn
, True
);
1259 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1260 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1262 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1263 WMMapWidget(panel
->customPaletteFrm
);
1264 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1265 customSetPalette(panel
);
1266 } else if (mode
== WMColorListModeColorPanel
) {
1267 WMMapWidget(panel
->colorListFrm
);
1268 WMSetButtonSelected(panel
->colorListBtn
, True
);
1274 WMColor
*WMGetColorPanelColor(WMColorPanel
* panel
)
1276 return WMGetColorWellColor(panel
->colorWell
);
1279 void WMSetColorPanelColor(WMColorPanel
* panel
, WMColor
* color
)
1281 WMSetColorWellColor(panel
->colorWell
, color
);
1283 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1284 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1285 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1286 panel
->color
.set
= cpRGB
;
1288 if (panel
->mode
== panel
->lastChanged
)
1289 panel
->lastChanged
= 0;
1291 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1294 static void updateSwatch(WMColorPanel
* panel
, CPColor color
)
1296 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1299 if (color
.set
!= cpRGB
)
1300 convertCPColor(&color
);
1302 panel
->color
= color
;
1304 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8, color
.rgb
.green
<< 8, color
.rgb
.blue
<< 8, True
);
1306 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1307 WMReleaseColor(wellcolor
);
1309 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1311 (*panel
->action
) (panel
, panel
->clientData
);
1313 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
, NULL
);
1317 static void modeButtonCallback(WMWidget
* w
, void *data
)
1319 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1321 if (w
== panel
->wheelBtn
)
1322 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1323 else if (w
== panel
->slidersBtn
)
1324 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1325 else if (w
== panel
->customPaletteBtn
)
1326 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1327 else if (w
== panel
->colorListBtn
)
1328 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1329 else if (w
== panel
->grayBtn
)
1330 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1331 else if (w
== panel
->rgbBtn
)
1332 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1333 else if (w
== panel
->cmykBtn
)
1334 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1335 else if (w
== panel
->hsbBtn
)
1336 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1339 /****************** Magnifying Cursor Functions *******************/
1341 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
)
1343 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1344 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1345 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1347 if (!(image
&& image
->data
)) {
1348 /* The image in panel->magnifyGlass->image does not exist yet.
1349 * Grab one from the screen (not beyond) and use it from now on.
1351 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1352 x
- Cursor_x_hot
, y
- Cursor_y_hot
, w
, h
, AllPlanes
, ZPixmap
)))
1353 wwarning(_("Color Panel: X failed request"));
1358 /* Coordinate correction for back pixmap
1359 * if magnifying glass is at screen-borders
1362 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1363 * Hatched area is beyond screen border.
1365 * |<-Cursor_x_hot->|
1366 * ________________|_____
1367 * |/ / / / / / /| | |
1368 * | / / / / / / |(x,y) |
1369 * |/_/_/_/_/_/_/|________|
1370 * |<----x0----->|<--w0-->|
1374 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1376 * Hatched area is beyond screen border
1378 * |<-Cursor_x_hot->|
1379 * ________________|_______________
1380 * | | | / / / / / /|
1381 * | (x,y)|/ / / / / / |
1382 * |___________________|_/_/_/_/_/_/|
1383 * |<-------w0-------->| |
1384 * |<---------------w--|----------->|
1389 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1390 x0
= Cursor_x_hot
- x
;
1394 if (displayWidth
- 1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1395 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1398 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1399 y0
= Cursor_y_hot
- y
;
1403 if (displayHeight
- 1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1404 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1406 /* end of coordinate correction */
1408 /* Grab an image from the screen, clipped if necessary,
1409 * and put it in the existing panel->magnifyGlass->image
1410 * with the corresponding clipping offset.
1412 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1413 x
- Cursor_x_hot
+ x0
, y
- Cursor_y_hot
+ y0
, w0
, h0
, AllPlanes
, ZPixmap
, image
, x0
, y0
))
1414 wwarning(_("Color Panel: X failed request"));
1419 static void magnifyGetImageStored(WMColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
)
1421 /* (x1, y1) = topleft corner of existing rectangle
1422 * (x2, y2) = topleft corner of new position
1425 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1426 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1428 const int dx
= abs(x2
- x1
), dy
= abs(y2
- y1
);
1430 const int x_min
= Cursor_x_hot
,
1431 y_min
= Cursor_y_hot
,
1432 x_max
= DisplayWidth(scr
->display
, scr
->screen
) - 1 -
1433 (Cursor_mask_width
- Cursor_x_hot
),
1434 y_max
= DisplayHeight(scr
->display
, scr
->screen
) - 1 - (Cursor_mask_height
- Cursor_y_hot
);
1436 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1437 return; /* No movement */
1449 width
= Cursor_mask_width
- dx
;
1450 height
= Cursor_mask_height
- dy
;
1452 /* If the traversed distance is larger than the size of the magnifying
1453 * glass contents, there is no need to do dirty rectangles. A whole new
1454 * rectangle can be grabbed (unless that rectangle falls partially
1456 * Destroying the image and setting it to NULL will achieve that later on.
1458 * Of course, grabbing an XImage beyond the borders of the screen will
1459 * cause trouble, this is considdered a special case. Part of the screen
1460 * is grabbed, but there is no need for dirty rectangles.
1462 if ((width
<= 0) || (height
<= 0)) {
1463 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1464 if (panel
->magnifyGlass
->image
)
1465 XDestroyImage(panel
->magnifyGlass
->image
);
1466 panel
->magnifyGlass
->image
= NULL
;
1469 if (panel
->magnifyGlass
->image
) {
1470 /* Get dirty rectangle from panel->magnifyGlass->image */
1471 panel
->magnifyGlass
->dirtyRect
=
1472 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1473 if (!panel
->magnifyGlass
->dirtyRect
) {
1474 wwarning(_("Color Panel: X failed request"));
1475 return; /* X returned a NULL from XSubImage */
1480 /* Get image from screen */
1481 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
, Cursor_mask_width
, Cursor_mask_height
);
1482 if (image
) { /* Only reassign if a *new* image was grabbed */
1483 panel
->magnifyGlass
->image
= image
;
1487 /* Copy previously stored rectangle on covered part of image */
1488 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1491 /* "width" and "height" are used as coordinates here,
1492 * and run from [0...width-1] and [0...height-1] respectively.
1496 old_height
= height
;
1498 for (; width
>= 0; width
--)
1499 for (height
= old_height
; height
>= 0; height
--)
1500 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1501 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1502 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1503 panel
->magnifyGlass
->dirtyRect
= NULL
;
1509 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
)
1511 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1516 unsigned long color
;
1518 if (!panel
->magnifyGlass
->image
)
1521 if (!panel
->magnifyGlass
->magPix
)
1525 * Copy an area of only 5x5 pixels from the center of the image.
1527 for (u
= 0; u
< 5; u
++) {
1528 for (v
= 0; v
< 5; v
++) {
1529 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1531 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1533 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1534 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1536 /* The center square must eventually be centered around the
1537 * hotspot. The image needs shifting to achieve this. The amount of
1538 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1541 * ^------- center of center square == Cursor_x_hot
1543 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1545 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1546 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1551 return panel
->magnifyGlass
->magPix
;
1553 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
, Cursor_mask_height
, scr
->depth
);
1557 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1558 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1560 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1561 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1562 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1563 /* (2,2) puts center pixel on center of glass */
1570 static WMView
*magnifyCreateView(W_ColorPanel
* panel
)
1572 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1575 magView
= W_CreateTopView(scr
);
1579 magView
->self
= panel
->win
;
1580 magView
->flags
.topLevel
= 1;
1581 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1582 magView
->attribs
.override_redirect
= True
;
1583 magView
->attribs
.save_under
= True
;
1585 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1587 W_RealizeView(magView
);
1592 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
)
1594 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1595 Pixmap magPixmap
, magPixmap2
;
1597 XColor fgColor
= { 0, 0, 0, 0, DoRed
| DoGreen
| DoBlue
, 0 };
1598 XColor bgColor
= { 0, 0xbf00, 0xa000, 0x5000, DoRed
| DoGreen
| DoBlue
, 0 };
1600 /* Cursor creation stuff */
1601 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1602 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1603 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1604 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1606 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1607 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1609 XFreePixmap(scr
->display
, magPixmap
);
1610 XFreePixmap(scr
->display
, magPixmap2
);
1612 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1614 /* Set up Pointer */
1615 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1616 PointerMotionMask
| ButtonPressMask
,
1617 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1622 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
)
1624 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1627 Pixmap pixmap
, clip_mask
;
1629 Window root_return
, child_return
;
1631 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1632 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1634 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1635 5 * 5 - 1, 5 * 5 - 1, scr
->depth
);
1637 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
, &x
, &y
, &u
, &v
, &mask
);
1639 panel
->magnifyGlass
->image
= NULL
;
1641 /* Clipmask to make magnified view-contents circular */
1643 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1644 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1646 /* Clip circle in glass cursor */
1647 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1648 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1651 XFreePixmap(scr
->display
, clip_mask
);
1653 /* Draw initial magnifying glass contents */
1654 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1656 pixmap
= magnifyCreatePixmap(panel
);
1657 XSetWindowBackgroundPixmap(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1658 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1659 XFlush(scr
->display
);
1662 XFreePixmap(scr
->display
, pixmap
);
1671 static void magnifyPutCursor(WMWidget
* w
, void *data
)
1673 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1674 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1678 WMPoint initialPosition
;
1680 /* Parameter not used, but tell the compiler that it is ok */
1683 /* Destroy wheelBackImg, so it'll update properly */
1684 if (panel
->selectionBackImg
) {
1685 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1686 panel
->selectionBackImg
= None
;
1689 /* Create magnifying glass */
1690 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1691 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1692 if (!panel
->magnifyGlass
->view
)
1695 initialPosition
= magnifyInitialize(panel
);
1696 panel
->magnifyGlass
->x
= initialPosition
.x
;
1697 panel
->magnifyGlass
->y
= initialPosition
.y
;
1699 W_MoveView(panel
->magnifyGlass
->view
,
1700 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1701 W_MapView(panel
->magnifyGlass
->view
);
1703 magCursor
= magnifyGrabPointer(panel
);
1705 while (panel
->magnifyGlass
->image
) {
1706 WMNextEvent(scr
->display
, &event
);
1708 /* Pack motion events */
1709 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1712 switch (event
.type
) {
1714 XDestroyImage(panel
->magnifyGlass
->image
);
1715 panel
->magnifyGlass
->image
= NULL
;
1717 if (event
.xbutton
.button
== Button1
) {
1718 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1719 panel
->color
.set
= cpRGB
;
1720 updateSwatch(panel
, panel
->color
);
1722 switch (panel
->mode
) {
1723 case WMWheelModeColorPanel
:
1728 case WMGrayModeColorPanel
:
1731 case WMRGBModeColorPanel
:
1734 case WMCMYKModeColorPanel
:
1737 case WMHSBModeColorPanel
:
1743 panel
->lastChanged
= panel
->mode
;
1745 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1749 while (XPending(event
.xmotion
.display
)) {
1751 XPeekEvent(event
.xmotion
.display
, &ev
);
1752 if (ev
.type
== MotionNotify
)
1753 XNextEvent(event
.xmotion
.display
, &event
);
1758 /* Get a "dirty rectangle" */
1759 magnifyGetImageStored(panel
,
1760 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1761 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1763 /* Update coordinates */
1764 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1765 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1768 W_MoveView(panel
->magnifyGlass
->view
,
1769 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1771 /* Put new image (with magn.) in view */
1772 pixmap
= magnifyCreatePixmap(panel
);
1773 if (pixmap
!= None
) {
1774 /* Change the window background */
1775 XSetWindowBackgroundPixmap(scr
->display
,
1776 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1777 /* Force an Expose (handled by X) */
1778 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1779 /* Synchronize the event queue, so the Expose is handled NOW */
1780 XFlush(scr
->display
);
1782 XFreePixmap(scr
->display
, pixmap
);
1787 /* Try XQueryPointer for this !!! It returns windows that the pointer
1788 * is over. Note: We found this solving the invisible donkey cap bug
1790 #if 0 /* As it is impossible to make this work in all cases,
1791 * we consider it confusing. Therefore we disabled it.
1793 case FocusOut
: /* fall through */
1796 * Color Panel window (panel->win) lost or received focus.
1797 * We need to update the pixmap in the magnifying glass.
1799 * BUG Doesn't work with focus switches between two windows
1800 * if none of them is the color panel.
1802 XUngrabPointer(scr
->display
, CurrentTime
);
1803 W_UnmapView(panel
->magnifyGlass
->view
);
1805 magnifyInitialize(panel
);
1807 W_MapView(panel
->magnifyGlass
->view
);
1808 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
,
1809 True
, PointerMotionMask
| ButtonPressMask
,
1810 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1814 WMHandleEvent(&event
);
1819 XUngrabPointer(scr
->display
, CurrentTime
);
1820 XFreeCursor(scr
->display
, magCursor
);
1822 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1823 panel
->magnifyGlass
->magPix
= None
;
1825 W_UnmapView(panel
->magnifyGlass
->view
);
1826 W_DestroyView(panel
->magnifyGlass
->view
);
1827 panel
->magnifyGlass
->view
= NULL
;
1829 wfree(panel
->magnifyGlass
);
1832 /****************** ColorWheel Functions ************************/
1834 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
)
1836 wheelMatrix
*matrix
= NULL
;
1839 assert((width
> 0) && (height
> 0));
1841 matrix
= wmalloc(sizeof(wheelMatrix
));
1842 matrix
->width
= width
;
1843 matrix
->height
= height
;
1845 for (i
= 0; i
< 3; i
++) {
1846 matrix
->data
[i
] = wmalloc(width
* height
* sizeof(unsigned char));
1852 static void wheelDestroyMatrix(wheelMatrix
* matrix
)
1859 for (i
= 0; i
< 3; i
++) {
1860 if (matrix
->data
[i
])
1861 wfree(matrix
->data
[i
]);
1866 static void wheelInitMatrix(W_ColorPanel
* panel
)
1870 unsigned char *rp
, *gp
, *bp
;
1876 const int cw_halfsize
= (colorWheelSize
+ 4) / 2,
1877 cw_sqsize
= (colorWheelSize
+ 4) * (colorWheelSize
+ 4), uchar_shift
= getShift(sizeof(unsigned char));
1879 if (!panel
->wheelMtrx
)
1882 cpColor
.hsv
.value
= 255;
1883 cpColor
.set
= cpHSV
;
1886 ofs
[1] = -(colorWheelSize
+ 4);
1888 /* offsets are counterclockwise (in triangles).
1891 * _______________________________________
1892 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
1893 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
1894 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
1895 * o | | | | | | | | | | | | | | | | | | | | | [3]
1899 * |\ /| <-- triangles
1905 for (y
= 0; y
< cw_halfsize
; y
++) {
1906 for (x
= y
; x
< (colorWheelSize
+ 4 - y
); x
++) {
1907 /* (xcor, ycor) is (x,y) relative to center of matrix */
1908 xcor
= 2 * x
- 4 - colorWheelSize
;
1909 ycor
= 2 * y
- 4 - colorWheelSize
;
1911 /* RColor.saturation is unsigned char and will wrap after 255 */
1912 sat
= rint(255.0 * sqrt(xcor
* xcor
+ ycor
* ycor
) / colorWheelSize
);
1914 cpColor
.hsv
.saturation
= (unsigned char)sat
;
1916 ofs
[0]++; /* top quarter of matrix */
1917 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
1918 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
1919 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
1923 dhue
[0] = rint(atan((double)ycor
/ (double)xcor
) *
1924 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
1928 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
1929 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
1930 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
1931 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
1933 for (i
= 0; i
< 4; i
++) {
1934 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1935 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1936 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1938 cpColor
.hsv
.hue
= dhue
[i
];
1939 convertCPColor(&cpColor
);
1941 *rp
= (unsigned char)(cpColor
.rgb
.red
);
1942 *gp
= (unsigned char)(cpColor
.rgb
.green
);
1943 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
1946 for (i
= 0; i
< 4; i
++) {
1947 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1948 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1949 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1951 *rp
= (unsigned char)0;
1952 *gp
= (unsigned char)0;
1953 *bp
= (unsigned char)0;
1958 ofs
[0] += 2 * y
+ 1;
1959 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2 * y
);
1963 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
)
1968 for (i
= 0; i
< 256; i
++) {
1969 /* We divide by 128 in advance, and check whether that number divides
1970 * by 2 properly. If not, we add one to round the number correctly
1972 v
= (i
* maxvalue
) >> 7;
1973 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) + (v
& 0x01));
1977 static void wheelRender(W_ColorPanel
* panel
)
1979 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1984 unsigned long ofs
= 0;
1985 /*unsigned char shift = getShift(sizeof(unsigned char)); */
1987 image
= RCreateImage(colorWheelSize
+ 4, colorWheelSize
+ 4, True
);
1989 wwarning(_("Color Panel: Could not allocate memory"));
1995 /* TODO Make this transparent istead of gray */
1996 gray
.red
= gray
.blue
= 0xae;
1999 for (y
= 0; y
< colorWheelSize
+ 4; y
++) {
2000 for (x
= 0; x
< colorWheelSize
+ 4; x
++) {
2001 if (wheelInsideColorWheel(panel
, ofs
)) {
2003 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]]);
2005 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]]);
2007 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]]);
2010 *(ptr
++) = (unsigned char)(gray
.red
);
2011 *(ptr
++) = (unsigned char)(gray
.green
);
2012 *(ptr
++) = (unsigned char)(gray
.blue
);
2019 if (panel
->wheelImg
)
2020 XFreePixmap(scr
->display
, panel
->wheelImg
);
2022 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2023 RReleaseImage(image
);
2025 /* Check if backimage exists. If it doesn't, allocate and fill it */
2026 if (!panel
->selectionBackImg
) {
2027 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2028 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2029 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2030 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2031 /* -2 is hot spot correction */
2035 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
)
2037 return ((panel
->wheelMtrx
->data
[0][ofs
] != 0) &&
2038 (panel
->wheelMtrx
->data
[1][ofs
] != 0) && (panel
->wheelMtrx
->data
[2][ofs
] != 0));
2041 static void wheelPaint(W_ColorPanel
* panel
)
2043 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2045 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->wheelView
->window
,
2046 scr
->copyGC
, 0, 0, colorWheelSize
+ 4, colorWheelSize
+ 4, 0, 0);
2048 /* Draw selection image */
2049 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2050 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2053 static void wheelHandleEvents(XEvent
* event
, void *data
)
2055 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2057 switch (event
->type
) {
2059 if (event
->xexpose
.count
!= 0) /* TODO Improve */
2066 static void wheelHandleActionEvents(XEvent
* event
, void *data
)
2068 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2070 switch (event
->type
) {
2072 if (getPickerPart(panel
, event
->xbutton
.x
, event
->xbutton
.y
) == COLORWHEEL_PART
) {
2074 panel
->lastChanged
= WMWheelModeColorPanel
;
2075 panel
->flags
.dragging
= 1;
2077 wheelPositionSelection(panel
, event
->xbutton
.x
, event
->xbutton
.y
);
2082 panel
->flags
.dragging
= 0;
2083 if (!panel
->flags
.continuous
) {
2085 (*panel
->action
) (panel
, panel
->clientData
);
2090 if (panel
->flags
.dragging
) {
2091 if (getPickerPart(panel
, event
->xmotion
.x
, event
->xmotion
.y
) == COLORWHEEL_PART
) {
2092 wheelPositionSelection(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2094 wheelPositionSelectionOutBounds(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2100 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
)
2108 if (panel
->mode
== WMWheelModeColorPanel
) {
2109 if ((lx
>= 2) && (lx
<= 2 + colorWheelSize
) && (ly
>= 2) && (ly
<= 2 + colorWheelSize
)) {
2111 ofs
= ly
* panel
->wheelMtrx
->width
+ lx
;
2113 if (wheelInsideColorWheel(panel
, ofs
))
2114 return COLORWHEEL_PART
;
2118 if (panel
->mode
== WMCustomPaletteModeColorPanel
) {
2119 if ((lx
>= 2) && (lx
< customPaletteWidth
- 2) && (ly
>= 2) && (ly
< customPaletteHeight
- 2)) {
2120 return CUSTOMPALETTE_PART
;
2127 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
)
2131 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2133 /* Parameter not used, but tell the compiler that it is ok */
2136 value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2138 wheelCalculateValues(panel
, value
);
2140 if (panel
->color
.set
== cpRGB
) {
2141 convertCPColor(&panel
->color
);
2142 panel
->color
.set
= cpHSV
;
2145 panel
->color
.hsv
.value
= value
;
2149 wheelUpdateSelection(panel
);
2152 static void wheelUpdateSelection(W_ColorPanel
* panel
)
2154 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2156 updateSwatch(panel
, panel
->color
);
2157 panel
->lastChanged
= WMWheelModeColorPanel
;
2159 /* Redraw color selector (and make a backup of the part it will cover) */
2160 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2161 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2162 /* "-2" is correction for hotspot location */
2163 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2164 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2168 static void wheelUndrawSelection(W_ColorPanel
* panel
)
2170 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2172 XCopyArea(scr
->display
, panel
->selectionBackImg
, panel
->wheelView
->window
,
2173 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2177 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2179 unsigned long ofs
= (y
* panel
->wheelMtrx
->width
) + x
;
2181 panel
->color
.rgb
.red
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]];
2183 panel
->color
.rgb
.green
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]];
2185 panel
->color
.rgb
.blue
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]];
2186 panel
->color
.set
= cpRGB
;
2188 wheelUndrawSelection(panel
);
2193 wheelUpdateSelection(panel
);
2194 wheelUpdateBrightnessGradientFromLocation(panel
);
2197 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2203 xcor
= x
* 2 - colorWheelSize
- 4;
2204 ycor
= y
* 2 - colorWheelSize
- 4;
2206 panel
->color
.hsv
.saturation
= 255;
2207 panel
->color
.hsv
.value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2210 hue
= rint(atan(-(double)ycor
/ (double)xcor
) * (180.0 / M_PI
));
2221 if ((xcor
> 0) && (ycor
> 0))
2224 panel
->color
.hsv
.hue
= hue
;
2225 panel
->color
.set
= cpHSV
;
2226 convertCPColor(&panel
->color
);
2228 wheelUndrawSelection(panel
);
2230 panel
->colx
= 2 + rint((colorWheelSize
* (1.0 + cos(panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2231 /* "+2" because of "colorWheelSize + 4" */
2232 panel
->coly
= 2 + rint((colorWheelSize
* (1.0 + sin(-panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2234 wheelUpdateSelection(panel
);
2235 cpColor
= panel
->color
;
2236 wheelUpdateBrightnessGradient(panel
, cpColor
);
2239 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
)
2244 ofs
= panel
->coly
* panel
->wheelMtrx
->width
+ panel
->colx
;
2246 from
.rgb
.red
= panel
->wheelMtrx
->data
[0][ofs
];
2247 from
.rgb
.green
= panel
->wheelMtrx
->data
[1][ofs
];
2248 from
.rgb
.blue
= panel
->wheelMtrx
->data
[2][ofs
];
2251 wheelUpdateBrightnessGradient(panel
, from
);
2254 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
)
2258 WMPixmap
*sliderPxmp
;
2260 to
.red
= to
.green
= to
.blue
= 0;
2262 if (topColor
.set
== cpHSV
)
2263 convertCPColor(&topColor
);
2265 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2266 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
), sliderImg
, 0);
2267 RReleaseImage(sliderImg
);
2268 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2269 WMReleasePixmap(sliderPxmp
);
2272 /****************** Grayscale Panel Functions ***************/
2274 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
)
2279 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2281 /* Parameter not used, but tell the compiler that it is ok */
2284 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2286 sprintf(tmp
, "%d", value
);
2288 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2289 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55 * value
);
2290 cpColor
.set
= cpRGB
;
2292 updateSwatch(panel
, cpColor
);
2293 panel
->lastChanged
= WMGrayModeColorPanel
;
2296 static void grayPresetButtonCallback(WMWidget
* w
, void *data
)
2302 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2305 if (w
== panel
->grayPresetBtn
[i
])
2310 value
= rint((100.0 * i
) / 6.0);
2311 sprintf(tmp
, "%d", value
);
2313 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2314 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * i
) / 6.0);
2315 cpColor
.set
= cpRGB
;
2317 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0 * i
) / 6.0));
2319 updateSwatch(panel
, cpColor
);
2320 panel
->lastChanged
= WMGrayModeColorPanel
;
2323 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
)
2328 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2330 /* Parameter not used, but tell the compiler that it is ok */
2331 (void) notification
;
2333 value
= atoi(WMGetTextFieldText(panel
->grayBrightnessT
));
2339 sprintf(tmp
, "%d", value
);
2340 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2341 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2343 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * value
) / 100.0);
2344 cpColor
.set
= cpRGB
;
2346 updateSwatch(panel
, cpColor
);
2347 panel
->lastChanged
= WMGrayModeColorPanel
;
2350 /******************* RGB Panel Functions *****************/
2352 static void rgbSliderCallback(WMWidget
* w
, void *data
)
2357 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2359 /* Parameter not used, but tell the compiler that it is ok */
2362 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2363 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2364 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2366 sprintf(tmp
, "%d", value
[0]);
2367 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2368 sprintf(tmp
, "%d", value
[1]);
2369 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2370 sprintf(tmp
, "%d", value
[2]);
2371 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2373 cpColor
.rgb
.red
= value
[0];
2374 cpColor
.rgb
.green
= value
[1];
2375 cpColor
.rgb
.blue
= value
[2];
2376 cpColor
.set
= cpRGB
;
2378 updateSwatch(panel
, cpColor
);
2379 panel
->lastChanged
= WMRGBModeColorPanel
;
2382 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2388 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2390 /* Parameter not used, but tell the compiler that it is ok */
2391 (void) notification
;
2393 value
[0] = atoi(WMGetTextFieldText(panel
->rgbRedT
));
2394 value
[1] = atoi(WMGetTextFieldText(panel
->rgbGreenT
));
2395 value
[2] = atoi(WMGetTextFieldText(panel
->rgbBlueT
));
2397 for (n
= 0; n
< 3; n
++) {
2404 sprintf(tmp
, "%d", value
[0]);
2405 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2406 sprintf(tmp
, "%d", value
[1]);
2407 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2408 sprintf(tmp
, "%d", value
[2]);
2409 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2411 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2412 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2413 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2415 cpColor
.rgb
.red
= value
[0];
2416 cpColor
.rgb
.green
= value
[1];
2417 cpColor
.rgb
.blue
= value
[2];
2418 cpColor
.set
= cpRGB
;
2420 updateSwatch(panel
, cpColor
);
2421 panel
->lastChanged
= WMRGBModeColorPanel
;
2424 /******************* CMYK Panel Functions *****************/
2426 static void cmykSliderCallback(WMWidget
* w
, void *data
)
2431 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2434 /* Parameter not used, but tell the compiler that it is ok */
2437 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2438 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2439 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2440 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2442 sprintf(tmp
, "%d", value
[0]);
2443 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2444 sprintf(tmp
, "%d", value
[1]);
2445 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2446 sprintf(tmp
, "%d", value
[2]);
2447 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2448 sprintf(tmp
, "%d", value
[3]);
2449 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2451 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2452 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2453 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2454 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2455 cpColor
.set
= cpRGB
;
2457 updateSwatch(panel
, cpColor
);
2458 panel
->lastChanged
= WMCMYKModeColorPanel
;
2461 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
)
2468 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2470 /* Parameter not used, but tell the compiler that it is ok */
2471 (void) notification
;
2473 value
[0] = atoi(WMGetTextFieldText(panel
->cmykCyanT
));
2474 value
[1] = atoi(WMGetTextFieldText(panel
->cmykMagentaT
));
2475 value
[2] = atoi(WMGetTextFieldText(panel
->cmykYellowT
));
2476 value
[3] = atoi(WMGetTextFieldText(panel
->cmykBlackT
));
2478 for (n
= 0; n
< 4; n
++) {
2485 sprintf(tmp
, "%d", value
[0]);
2486 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2488 sprintf(tmp
, "%d", value
[1]);
2489 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2491 sprintf(tmp
, "%d", value
[2]);
2492 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2494 sprintf(tmp
, "%d", value
[3]);
2495 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2497 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2498 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2499 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2500 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2502 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2503 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2504 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2505 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2506 cpColor
.set
= cpRGB
;
2508 updateSwatch(panel
, cpColor
);
2509 panel
->lastChanged
= WMCMYKModeColorPanel
;
2512 /********************** HSB Panel Functions ***********************/
2514 static void hsbSliderCallback(WMWidget
* w
, void *data
)
2519 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2521 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2522 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2523 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2525 sprintf(tmp
, "%d", value
[0]);
2526 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2527 sprintf(tmp
, "%d", value
[1]);
2528 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2529 sprintf(tmp
, "%d", value
[2]);
2530 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2532 cpColor
.hsv
.hue
= value
[0];
2533 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2534 cpColor
.hsv
.value
= value
[2] * 2.55;
2535 cpColor
.set
= cpHSV
;
2537 convertCPColor(&cpColor
);
2539 panel
->lastChanged
= WMHSBModeColorPanel
;
2540 updateSwatch(panel
, cpColor
);
2542 if (w
!= panel
->hsbBrightnessS
)
2543 hsbUpdateBrightnessGradient(panel
);
2544 if (w
!= panel
->hsbSaturationS
)
2545 hsbUpdateSaturationGradient(panel
);
2546 if (w
!= panel
->hsbHueS
)
2547 hsbUpdateHueGradient(panel
);
2550 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2556 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2558 /* Parameter not used, but tell the compiler that it is ok */
2559 (void) notification
;
2561 value
[0] = atoi(WMGetTextFieldText(panel
->hsbHueT
));
2562 value
[1] = atoi(WMGetTextFieldText(panel
->hsbSaturationT
));
2563 value
[2] = atoi(WMGetTextFieldText(panel
->hsbBrightnessT
));
2570 for (n
= 1; n
< 3; n
++) {
2577 sprintf(tmp
, "%d", value
[0]);
2578 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2579 sprintf(tmp
, "%d", value
[1]);
2580 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2581 sprintf(tmp
, "%d", value
[2]);
2582 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2584 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2585 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2586 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2588 cpColor
.hsv
.hue
= value
[0];
2589 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2590 cpColor
.hsv
.value
= value
[2] * 2.55;
2591 cpColor
.set
= cpHSV
;
2593 convertCPColor(&cpColor
);
2595 panel
->lastChanged
= WMHSBModeColorPanel
;
2596 updateSwatch(panel
, cpColor
);
2598 hsbUpdateBrightnessGradient(panel
);
2599 hsbUpdateSaturationGradient(panel
);
2600 hsbUpdateHueGradient(panel
);
2603 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
)
2605 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2609 WMPixmap
*sliderPxmp
;
2611 from
.red
= from
.green
= from
.blue
= 0;
2612 to
.hsv
= panel
->color
.hsv
;
2616 convertCPColor(&to
);
2618 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2619 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2620 RReleaseImage(sliderImg
);
2623 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2624 panel
->font12
, 2, 0, 100, WALeft
, scr
->white
,
2625 False
, _("Brightness"), strlen(_("Brightness")));
2627 wwarning(_("Color Panel: Could not allocate memory"));
2629 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2630 WMReleasePixmap(sliderPxmp
);
2633 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
)
2635 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2639 WMPixmap
*sliderPxmp
;
2641 from
.hsv
= panel
->color
.hsv
;
2642 from
.hsv
.saturation
= 0;
2644 convertCPColor(&from
);
2646 to
.hsv
= panel
->color
.hsv
;
2647 to
.hsv
.saturation
= 255;
2649 convertCPColor(&to
);
2651 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
), RGRD_HORIZONTAL
);
2652 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2653 RReleaseImage(sliderImg
);
2656 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2657 panel
->font12
, 2, 0, 100, WALeft
,
2658 from
.hsv
.value
< 128 ? scr
->white
: scr
->black
, False
,
2659 _("Saturation"), strlen(_("Saturation")));
2661 wwarning(_("Color Panel: Could not allocate memory"));
2663 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2664 WMReleasePixmap(sliderPxmp
);
2667 static void hsbUpdateHueGradient(W_ColorPanel
* panel
)
2669 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2670 RColor
**colors
= NULL
;
2673 WMPixmap
*sliderPxmp
;
2676 hsvcolor
= panel
->color
.hsv
;
2678 colors
= wmalloc(sizeof(RColor
*) * (8));
2679 for (i
= 0; i
< 7; i
++) {
2680 hsvcolor
.hue
= (360 * i
) / 6;
2681 colors
[i
] = wmalloc(sizeof(RColor
));
2682 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2686 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2687 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2688 RReleaseImage(sliderImg
);
2691 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2692 panel
->font12
, 2, 0, 100, WALeft
,
2693 hsvcolor
.value
< 128 ? scr
->white
: scr
->black
, False
, _("Hue"), strlen(_("Hue")));
2695 wwarning(_("Color Panel: Could not allocate memory"));
2697 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2698 WMReleasePixmap(sliderPxmp
);
2700 for (i
= 0; i
< 7; i
++)
2706 /*************** Custom Palette Functions ****************/
2708 static void customRenderSpectrum(W_ColorPanel
* panel
)
2715 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, False
);
2717 ptr
= spectrum
->data
;
2719 for (y
= 0; y
< SPECTRUM_HEIGHT
; y
++) {
2720 cpColor
.hsv
.hue
= y
;
2721 cpColor
.hsv
.saturation
= 0;
2722 cpColor
.hsv
.value
= 255;
2723 cpColor
.set
= cpHSV
;
2725 for (x
= 0; x
< SPECTRUM_WIDTH
; x
++) {
2726 convertCPColor(&cpColor
);
2728 *(ptr
++) = (unsigned char)cpColor
.rgb
.red
;
2729 *(ptr
++) = (unsigned char)cpColor
.rgb
.green
;
2730 *(ptr
++) = (unsigned char)cpColor
.rgb
.blue
;
2732 if (x
< (SPECTRUM_WIDTH
/ 2))
2733 cpColor
.hsv
.saturation
++;
2735 if (x
> (SPECTRUM_WIDTH
/ 2))
2736 cpColor
.hsv
.value
--;
2739 if (panel
->customPaletteImg
) {
2740 RReleaseImage(panel
->customPaletteImg
);
2741 panel
->customPaletteImg
= NULL
;
2743 panel
->customPaletteImg
= spectrum
;
2746 static void customSetPalette(W_ColorPanel
* panel
)
2748 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2752 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
, customPaletteHeight
, scr
->depth
);
2753 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
, customPaletteHeight
);
2754 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2755 RReleaseImage(scaledImg
);
2757 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2758 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2760 /* Check backimage exists. If it doesn't, allocate and fill it */
2761 if (!panel
->selectionBackImg
) {
2762 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2763 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2766 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2767 panel
->palx
- 2, panel
->paly
- 2, 4, 4, 0, 0);
2768 XCopyArea(scr
->display
, panel
->selectionImg
,
2769 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2770 panel
->palx
- 2, panel
->paly
- 2);
2771 XFreePixmap(scr
->display
, image
);
2773 panel
->palXRatio
= (double)(panel
->customPaletteImg
->width
) / (double)(customPaletteWidth
);
2774 panel
->palYRatio
= (double)(panel
->customPaletteImg
->height
) / (double)(customPaletteHeight
);
2776 WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2779 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2781 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2784 /* undraw selection */
2785 XCopyArea(scr
->display
, panel
->selectionBackImg
,
2786 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2787 panel
->palx
- 2, panel
->paly
- 2);
2792 ofs
= (rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) * panel
->customPaletteImg
->width
) * 3;
2794 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[ofs
];
2795 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[ofs
+ 1];
2796 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[ofs
+ 2];
2797 panel
->color
.set
= cpRGB
;
2799 updateSwatch(panel
, panel
->color
);
2800 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
2802 /* Redraw color selector (and make a backup of the part it will cover) */
2803 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 */
2804 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4, panel
->palx
- 2, panel
->paly
- 2); /* see above */
2807 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2813 if (x
>= customPaletteWidth
)
2814 x
= customPaletteWidth
- 2;
2815 if (y
>= customPaletteHeight
)
2816 y
= customPaletteHeight
- 2;
2818 customPalettePositionSelection(panel
, x
, y
);
2821 static void customPaletteHandleEvents(XEvent
* event
, void *data
)
2823 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2825 switch (event
->type
) {
2827 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
2829 customSetPalette(panel
);
2834 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
)
2836 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2839 switch (event
->type
) {
2841 x
= event
->xbutton
.x
;
2842 y
= event
->xbutton
.y
;
2844 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2845 panel
->flags
.dragging
= 1;
2846 customPalettePositionSelection(panel
, x
, y
);
2851 panel
->flags
.dragging
= 0;
2852 if (!panel
->flags
.continuous
) {
2854 (*panel
->action
) (panel
, panel
->clientData
);
2859 x
= event
->xmotion
.x
;
2860 y
= event
->xmotion
.y
;
2862 if (panel
->flags
.dragging
) {
2863 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2864 customPalettePositionSelection(panel
, x
, y
);
2866 customPalettePositionSelectionOutBounds(panel
, x
, y
);
2872 static void customPaletteMenuCallback(WMWidget
* w
, void *data
)
2874 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2875 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
2877 /* Parameter not used, but tell the compiler that it is ok */
2881 case CPmenuNewFromFile
:
2882 customPaletteMenuNewFromFile(panel
);
2885 customPaletteMenuRename(panel
);
2888 customPaletteMenuRemove(panel
);
2892 case CPmenuNewFromClipboard
:
2897 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
)
2899 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2900 WMOpenPanel
*browseP
;
2902 char *filename
= NULL
;
2906 RImage
*tmpImg
= NULL
;
2908 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
, "\0") == 0))
2909 spath
= wexpandpath(wgethomedir());
2911 spath
= wexpandpath(panel
->lastBrowseDir
);
2913 browseP
= WMGetOpenPanel(scr
);
2914 WMSetFilePanelCanChooseDirectories(browseP
, 0);
2915 WMSetFilePanelCanChooseFiles(browseP
, 1);
2917 /* Get a filename */
2918 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
2919 _("Open Palette"), RSupportedFileFormats())) {
2920 filepath
= WMGetFilePanelFileName(browseP
);
2922 /* Get seperation position between path and filename */
2923 i
= strrchr(filepath
, '/') - filepath
+ 1;
2924 if (i
> strlen(filepath
))
2925 i
= strlen(filepath
);
2927 /* Store last browsed path */
2928 if (panel
->lastBrowseDir
)
2929 wfree(panel
->lastBrowseDir
);
2930 panel
->lastBrowseDir
= wmalloc((i
+ 1) * sizeof(char));
2931 strncpy(panel
->lastBrowseDir
, filepath
, i
);
2932 panel
->lastBrowseDir
[i
] = '\0';
2934 /* Get filename from path */
2935 filename
= wstrdup(filepath
+ i
);
2937 /* Check for duplicate files, and rename it if there are any */
2938 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2939 while (access(tmp
, F_OK
) == 0) {
2944 newName
= generateNewFilename(filename
);
2948 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2952 /* Copy image to $(gnustepdir)/Library/Colors/ &
2953 * Add filename to history menu */
2954 if (wcopy_file(panel
->configurationPath
, filepath
, filename
) == 0) {
2956 /* filepath is a "local" path now the file has been copied */
2958 filepath
= wstrconcat(panel
->configurationPath
, filename
);
2960 /* load the image & add menu entries */
2961 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
2963 if (panel
->customPaletteImg
)
2964 RReleaseImage(panel
->customPaletteImg
);
2965 panel
->customPaletteImg
= tmpImg
;
2967 customSetPalette(panel
);
2968 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
2970 panel
->currentPalette
=
2971 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1;
2973 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
2974 panel
->currentPalette
);
2977 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2979 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
2980 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2981 _("Invalid file format !"), _("OK"), NULL
, NULL
);
2983 werror(_("can't remove file %s"), tmp
);
2984 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2985 _("Couldn't remove file from Configuration Directory !"),
2986 _("OK"), NULL
, NULL
);
2993 WMFreeFilePanel(browseP
);
2998 static void customPaletteMenuRename(W_ColorPanel
* panel
)
3000 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3001 char *toName
= NULL
;
3003 char *toPath
, *fromPath
;
3007 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3008 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3010 toName
= WMRunInputPanel(scr
, panel
->win
, _("Rename"), _("Rename palette to:"),
3011 fromName
, _("OK"), _("Cancel"));
3015 /* As some people do certain stupid things... */
3016 if (strcmp(toName
, fromName
) == 0) {
3021 /* For normal people */
3022 fromPath
= wstrconcat(panel
->configurationPath
, fromName
);
3023 toPath
= wstrconcat(panel
->configurationPath
, toName
);
3025 if (access(toPath
, F_OK
) == 0) {
3026 /* Careful, this palette exists already */
3027 if (WMRunAlertPanel(scr
, panel
->win
, _("Warning"),
3028 _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"),
3030 /* "No" = 0, "Yes" = 1 */
3031 int items
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
3035 /* Remove from History list too */
3037 while ((index
< items
)
3039 (strcmp(WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, index
), toName
)
3043 if (index
< items
) {
3044 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, index
);
3058 if (rename(fromPath
, toPath
) != 0)
3059 werror(_("Couldn't rename palette %s to %s"), fromName
, toName
);
3061 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3062 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
, toName
);
3064 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3072 static void customPaletteMenuRemove(W_ColorPanel
* panel
)
3074 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3080 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3082 tmp
= wstrconcat(_("This will permanently remove the palette "),
3083 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3084 text
= wstrconcat(tmp
, _(".\n\nAre you sure you want to remove this palette ?"));
3087 choice
= WMRunAlertPanel(scr
, panel
->win
, _("Remove"), text
, _("Yes"), _("No"), NULL
);
3088 /* returns 0 (= "Yes") or 1 (="No") */
3093 tmp
= wstrconcat(panel
->configurationPath
,
3094 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3096 if (remove(tmp
) == 0) {
3097 /* item-1 always exists */
3098 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3100 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
, panel
);
3101 customSetPalette(panel
);
3103 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3106 werror(_("Couldn't remove palette %s"), tmp
);
3113 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
)
3115 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3116 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3120 unsigned char perm_mask
;
3122 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3123 if (item
== panel
->currentPalette
)
3127 customRenderSpectrum(panel
);
3129 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, False
);
3130 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, False
);
3132 /* Load file from configpath */
3133 filename
= wstrconcat(panel
->configurationPath
,
3134 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3136 /* If the file corresponding to the item does not exist,
3137 * remove it from the history list and select the next one.
3139 perm_mask
= (access(filename
, F_OK
) == 0);
3141 /* File does not exist */
3143 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3144 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3145 customPaletteHistoryCallback(w
, data
);
3150 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3152 if (panel
->customPaletteImg
) {
3153 RReleaseImage(panel
->customPaletteImg
);
3154 panel
->customPaletteImg
= NULL
;
3156 panel
->customPaletteImg
= tmp
;
3159 /* If the image is not writable, don't allow removing/renaming */
3160 perm_mask
= (access(filename
, W_OK
) == 0);
3161 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, perm_mask
);
3162 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, perm_mask
);
3166 customSetPalette(panel
);
3168 panel
->currentPalette
= item
;
3171 /************************* ColorList Panel Functions **********************/
3173 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
)
3175 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3176 Display
*dpy
= WMScreenDisplay(scr
);
3177 WMView
*view
= W_VIEW(lPtr
);
3178 RColor
*color
= (RColor
*) WMGetListItem(lPtr
, index
)->clientData
;
3179 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3180 int width
, height
, x
, y
;
3183 width
= rect
->size
.width
;
3184 height
= rect
->size
.height
;
3188 if (state
& WLDSSelected
)
3189 XFillRectangle(dpy
, d
, WMColorGC(scr
->white
), x
, y
, width
, height
);
3191 XFillRectangle(dpy
, d
, WMColorGC(view
->backColor
), x
, y
, width
, height
);
3193 fillColor
= WMCreateRGBColor(scr
, color
->red
<< 8, color
->green
<< 8, color
->blue
<< 8, True
);
3195 XFillRectangle(dpy
, d
, WMColorGC(fillColor
), x
, y
, 15, height
);
3196 WMReleaseColor(fillColor
);
3198 WMDrawString(scr
, d
, scr
->black
, panel
->font12
, x
+ 18, y
, text
, strlen(text
));
3201 static void colorListSelect(WMWidget
* w
, void *data
)
3203 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3206 cpColor
.rgb
= *((RColor
*) WMGetListSelectedItem(w
)->clientData
);
3207 cpColor
.set
= cpRGB
;
3209 panel
->lastChanged
= WMColorListModeColorPanel
;
3210 updateSwatch(panel
, cpColor
);
3213 static void colorListColorMenuCallback(WMWidget
* w
, void *data
)
3215 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3216 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3218 /* Parameter not used, but tell the compiler that it is ok */
3231 static void colorListListMenuCallback(WMWidget
* w
, void *data
)
3233 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3234 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3236 /* Parameter not used, but tell the compiler that it is ok */
3241 /* New Color List */
3242 colorListListMenuNew(panel
);
3251 static void colorListListMenuNew(W_ColorPanel
* panel
)
3256 /*************** Panel Initialisation Functions *****************/
3258 static void wheelInit(W_ColorPanel
* panel
)
3262 if (panel
->color
.set
!= cpHSV
)
3263 convertCPColor(&panel
->color
);
3265 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3267 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3268 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3269 cos(panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3270 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3271 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3272 sin(-panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3274 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3276 cpColor
= panel
->color
;
3277 cpColor
.hsv
.value
= 255;
3278 cpColor
.set
= cpHSV
;
3279 wheelUpdateBrightnessGradient(panel
, cpColor
);
3282 static void grayInit(W_ColorPanel
* panel
)
3287 if (panel
->color
.set
!= cpHSV
)
3288 convertCPColor(&panel
->color
);
3290 value
= rint(panel
->color
.hsv
.value
/ 2.55);
3291 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3293 sprintf(tmp
, "%d", value
);
3294 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3297 static void rgbInit(W_ColorPanel
* panel
)
3301 if (panel
->color
.set
!= cpRGB
)
3302 convertCPColor(&panel
->color
);
3304 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3305 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3306 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3308 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3309 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3310 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3311 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3312 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3313 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3316 static void cmykInit(W_ColorPanel
* panel
)
3321 if (panel
->color
.set
!= cpRGB
)
3322 convertCPColor(&panel
->color
);
3324 value
[0] = rint((255 - panel
->color
.rgb
.red
) / 2.55);
3325 value
[1] = rint((255 - panel
->color
.rgb
.green
) / 2.55);
3326 value
[2] = rint((255 - panel
->color
.rgb
.blue
) / 2.55);
3328 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3329 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3330 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3331 WMSetSliderValue(panel
->cmykBlackS
, 0);
3333 sprintf(tmp
, "%d", value
[0]);
3334 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3335 sprintf(tmp
, "%d", value
[1]);
3336 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3337 sprintf(tmp
, "%d", value
[2]);
3338 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3339 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3342 static void hsbInit(W_ColorPanel
* panel
)
3347 if (panel
->color
.set
!= cpHSV
)
3348 convertCPColor(&panel
->color
);
3350 value
[0] = panel
->color
.hsv
.hue
;
3351 value
[1] = rint(panel
->color
.hsv
.saturation
/ 2.55);
3352 value
[2] = rint(panel
->color
.hsv
.value
/ 2.55);
3354 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
3355 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
3356 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
3358 sprintf(tmp
, "%d", value
[0]);
3359 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3360 sprintf(tmp
, "%d", value
[1]);
3361 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3362 sprintf(tmp
, "%d", value
[2]);
3363 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3365 hsbUpdateBrightnessGradient(panel
);
3366 hsbUpdateSaturationGradient(panel
);
3367 hsbUpdateHueGradient(panel
);
3370 /************************** Common utility functions ************************/
3372 static char *generateNewFilename(const char *curName
)
3384 if (((ptr
= strrchr(ptr
, '{')) == 0) || sscanf(ptr
, "{%i}%c", &n
, &c
) != 1)
3385 return wstrconcat(curName
, " {1}");
3387 baseLen
= ptr
- curName
- 1;
3389 newName
= wmalloc(baseLen
+ 16);
3390 strncpy(newName
, curName
, baseLen
);
3392 snprintf(&newName
[baseLen
], 16, " {%i}", n
+ 1);
3397 static void convertCPColor(CPColor
* color
)
3399 unsigned short old_hue
= 0;
3401 switch (color
->set
) {
3403 wwarning(_("Color Panel: Color unspecified"));
3406 old_hue
= color
->hsv
.hue
;
3407 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3409 /* In black the hue is undefined, and may change by conversion
3410 * Same for white. */
3411 if (((color
->rgb
.red
== 0) &&
3412 (color
->rgb
.green
== 0) &&
3413 (color
->rgb
.blue
== 0)) ||
3414 ((color
->rgb
.red
== 0) && (color
->rgb
.green
== 0) && (color
->rgb
.blue
== 255))
3416 color
->hsv
.hue
= old_hue
;
3419 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3424 #define ABS_SHIFT(val, shift) \
3425 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3427 static RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
)
3430 XColor
*xcolor
= NULL
;
3432 xcolor
= wmalloc(sizeof(XColor
));
3433 xcolor
->pixel
= value
;
3434 XQueryColor(scr
->display
, scr
->rcontext
->cmap
, xcolor
);
3436 color
.red
= xcolor
->red
>> 8;
3437 color
.green
= xcolor
->green
>> 8;
3438 color
.blue
= xcolor
->blue
>> 8;
3446 static unsigned char getShift(unsigned char value
)
3448 unsigned char i
= -1;