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