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 char *generateNewFilename(const char *curName
);
279 static void convertCPColor(CPColor
* color
);
280 static RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
);
281 static unsigned char getShift(unsigned char value
);
283 static void modeButtonCallback(WMWidget
* w
, void *data
);
284 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
);
285 static void readConfiguration(W_ColorPanel
* panel
);
286 static void readXColors(W_ColorPanel
* panel
);
288 static void closeWindowCallback(WMWidget
* w
, void *data
);
290 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
);
291 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
);
292 static void magnifyPutCursor(WMWidget
* w
, void *data
);
293 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
);
294 static void magnifyGetImageStored(W_ColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
);
295 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
);
297 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
);
298 static void wheelDestroyMatrix(wheelMatrix
* matrix
);
299 static void wheelInitMatrix(W_ColorPanel
* panel
);
300 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
);
301 static void wheelRender(W_ColorPanel
* panel
);
302 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
);
303 static void wheelPaint(W_ColorPanel
* panel
);
305 static void wheelHandleEvents(XEvent
* event
, void *data
);
306 static void wheelHandleActionEvents(XEvent
* event
, void *data
);
307 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
);
308 static void wheelUpdateSelection(W_ColorPanel
* panel
);
309 static void wheelUndrawSelection(W_ColorPanel
* panel
);
311 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
);
312 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
313 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
);
314 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
);
316 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
);
317 static void grayPresetButtonCallback(WMWidget
* w
, void *data
);
318 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
);
320 static void rgbSliderCallback(WMWidget
* w
, void *data
);
321 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
);
323 static void cmykSliderCallback(WMWidget
* w
, void *data
);
324 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
);
326 static void hsbSliderCallback(WMWidget
* w
, void *data
);
327 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
);
328 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
);
329 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
);
330 static void hsbUpdateHueGradient(W_ColorPanel
* panel
);
332 static void customRenderSpectrum(W_ColorPanel
* panel
);
333 static void customSetPalette(W_ColorPanel
* panel
);
334 static void customPaletteHandleEvents(XEvent
* event
, void *data
);
335 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
);
336 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
);
337 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
338 static void customPaletteMenuCallback(WMWidget
* w
, void *data
);
339 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
);
341 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
);
342 static void customPaletteMenuRename(W_ColorPanel
* panel
);
343 static void customPaletteMenuRemove(W_ColorPanel
* panel
);
345 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
);
346 static void colorListSelect(WMWidget
* w
, void *data
);
347 static void colorListColorMenuCallback(WMWidget
* w
, void *data
);
348 static void colorListListMenuCallback(WMWidget
* w
, void *data
);
349 static void colorListListMenuNew(W_ColorPanel
* panel
);
351 static void wheelInit(W_ColorPanel
* panel
);
352 static void grayInit(W_ColorPanel
* panel
);
353 static void rgbInit(W_ColorPanel
* panel
);
354 static void cmykInit(W_ColorPanel
* panel
);
355 static void hsbInit(W_ColorPanel
* panel
);
357 void WMSetColorPanelAction(WMColorPanel
* panel
, WMAction2
* action
, void *data
)
359 panel
->action
= action
;
360 panel
->clientData
= data
;
363 static WMColorPanel
*makeColorPanel(WMScreen
* scrPtr
, const char *name
)
370 WMColor
*textcolor
, *graybuttoncolor
;
372 GC bgc
= WMColorGC(scrPtr
->black
);
373 GC wgc
= WMColorGC(scrPtr
->white
);
375 panel
= wmalloc(sizeof(WMColorPanel
));
376 panel
->color
.rgb
.red
= 0;
377 panel
->color
.rgb
.green
= 0;
378 panel
->color
.rgb
.blue
= 0;
379 panel
->color
.hsv
.hue
= 0;
380 panel
->color
.hsv
.saturation
= 0;
381 panel
->color
.hsv
.value
= 0;
382 panel
->color
.set
= cpNone
; /* Color has not been set yet */
384 panel
->font8
= WMSystemFontOfSize(scrPtr
, 8);
385 panel
->font12
= WMSystemFontOfSize(scrPtr
, 12);
387 panel
->win
= WMCreateWindowWithStyle(scrPtr
, name
,
388 WMTitledWindowMask
| WMClosableWindowMask
| WMResizableWindowMask
);
389 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
390 WMSetWindowTitle(panel
->win
, _("Colors"));
391 WMSetWindowCloseAction(panel
->win
, closeWindowCallback
, panel
);
393 /* Set Default ColorPanel Mode(s) */
394 panel
->mode
= WMWheelModeColorPanel
;
395 panel
->lastChanged
= 0;
396 panel
->slidersmode
= WMRGBModeColorPanel
;
397 panel
->configurationPath
= wstrconcat(wusergnusteppath(), "/Library/Colors/");
399 /* Some General Purpose Widgets */
400 panel
->colorWell
= WMCreateColorWell(panel
->win
);
401 WMResizeWidget(panel
->colorWell
, 134, 36);
402 WSetColorWellBordered(panel
->colorWell
, False
);
403 WMMoveWidget(panel
->colorWell
, 56, 4);
405 panel
->magnifyBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
406 WMResizeWidget(panel
->magnifyBtn
, 46, 36);
407 WMMoveWidget(panel
->magnifyBtn
, 6, 4);
408 WMSetButtonAction(panel
->magnifyBtn
, magnifyPutCursor
, panel
);
409 WMSetButtonImagePosition(panel
->magnifyBtn
, WIPImageOnly
);
410 WMSetButtonImage(panel
->magnifyBtn
, scrPtr
->magnifyIcon
);
412 panel
->wheelBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
413 WMResizeWidget(panel
->wheelBtn
, 46, 32);
414 WMMoveWidget(panel
->wheelBtn
, 6, 44);
415 WMSetButtonAction(panel
->wheelBtn
, modeButtonCallback
, panel
);
416 WMSetButtonImagePosition(panel
->wheelBtn
, WIPImageOnly
);
417 WMSetButtonImage(panel
->wheelBtn
, scrPtr
->wheelIcon
);
419 panel
->slidersBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
420 WMResizeWidget(panel
->slidersBtn
, 46, 32);
421 WMMoveWidget(panel
->slidersBtn
, 52, 44);
422 WMSetButtonAction(panel
->slidersBtn
, modeButtonCallback
, panel
);
423 WMSetButtonImagePosition(panel
->slidersBtn
, WIPImageOnly
);
424 WMSetButtonImage(panel
->slidersBtn
, scrPtr
->rgbIcon
);
426 panel
->customPaletteBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
427 WMResizeWidget(panel
->customPaletteBtn
, 46, 32);
428 WMMoveWidget(panel
->customPaletteBtn
, 98, 44);
429 WMSetButtonAction(panel
->customPaletteBtn
, modeButtonCallback
, panel
);
430 WMSetButtonImagePosition(panel
->customPaletteBtn
, WIPImageOnly
);
431 WMSetButtonImage(panel
->customPaletteBtn
, scrPtr
->customPaletteIcon
);
433 panel
->colorListBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
434 WMResizeWidget(panel
->colorListBtn
, 46, 32);
435 WMMoveWidget(panel
->colorListBtn
, 144, 44);
436 WMSetButtonAction(panel
->colorListBtn
, modeButtonCallback
, panel
);
437 WMSetButtonImagePosition(panel
->colorListBtn
, WIPImageOnly
);
438 WMSetButtonImage(panel
->colorListBtn
, scrPtr
->colorListIcon
);
440 /* Let's Group some of them together */
441 WMGroupButtons(panel
->wheelBtn
, panel
->slidersBtn
);
442 WMGroupButtons(panel
->wheelBtn
, panel
->customPaletteBtn
);
443 WMGroupButtons(panel
->wheelBtn
, panel
->colorListBtn
);
445 /* Widgets for the ColorWheel Panel */
446 panel
->wheelFrm
= WMCreateFrame(panel
->win
);
447 WMSetFrameRelief(panel
->wheelFrm
, WRFlat
);
448 WMResizeWidget(panel
->wheelFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
449 WMMoveWidget(panel
->wheelFrm
, 5, 80);
451 panel
->wheelView
= W_CreateView(W_VIEW(panel
->wheelFrm
));
452 /* XXX Can we create a view ? */
453 W_ResizeView(panel
->wheelView
, colorWheelSize
+ 4, colorWheelSize
+ 4);
454 W_MoveView(panel
->wheelView
, 0, 0);
456 /* Create an event handler to handle expose/click events in ColorWheel */
457 WMCreateEventHandler(panel
->wheelView
,
458 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
|
459 LeaveWindowMask
| ButtonMotionMask
, wheelHandleActionEvents
, panel
);
461 WMCreateEventHandler(panel
->wheelView
, ExposureMask
, wheelHandleEvents
, panel
);
463 panel
->wheelBrightnessS
= WMCreateSlider(panel
->wheelFrm
);
464 WMResizeWidget(panel
->wheelBrightnessS
, 16, 153);
465 WMMoveWidget(panel
->wheelBrightnessS
, 5 + colorWheelSize
+ 14, 1);
466 WMSetSliderMinValue(panel
->wheelBrightnessS
, 0);
467 WMSetSliderMaxValue(panel
->wheelBrightnessS
, 255);
468 WMSetSliderAction(panel
->wheelBrightnessS
, wheelBrightnessSliderCallback
, panel
);
469 WMSetSliderKnobThickness(panel
->wheelBrightnessS
, knobThickness
);
471 panel
->wheelMtrx
= wheelCreateMatrix(colorWheelSize
+ 4, colorWheelSize
+ 4);
472 wheelInitMatrix(panel
);
474 /* Widgets for the Slider Panels */
475 panel
->slidersFrm
= WMCreateFrame(panel
->win
);
476 WMSetFrameRelief(panel
->slidersFrm
, WRFlat
);
477 WMResizeWidget(panel
->slidersFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
478 WMMoveWidget(panel
->slidersFrm
, 4, 80);
480 panel
->seperatorFrm
= WMCreateFrame(panel
->slidersFrm
);
481 WMSetFrameRelief(panel
->seperatorFrm
, WRPushed
);
482 WMResizeWidget(panel
->seperatorFrm
, PWIDTH
- 8, 2);
483 WMMoveWidget(panel
->seperatorFrm
, 0, 1);
485 panel
->grayBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
486 WMResizeWidget(panel
->grayBtn
, 46, 24);
487 WMMoveWidget(panel
->grayBtn
, 1, 8);
488 WMSetButtonAction(panel
->grayBtn
, modeButtonCallback
, panel
);
489 WMSetButtonImagePosition(panel
->grayBtn
, WIPImageOnly
);
490 WMSetButtonImage(panel
->grayBtn
, scrPtr
->grayIcon
);
492 panel
->rgbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
493 WMResizeWidget(panel
->rgbBtn
, 46, 24);
494 WMMoveWidget(panel
->rgbBtn
, 47, 8);
495 WMSetButtonAction(panel
->rgbBtn
, modeButtonCallback
, panel
);
496 WMSetButtonImagePosition(panel
->rgbBtn
, WIPImageOnly
);
497 WMSetButtonImage(panel
->rgbBtn
, scrPtr
->rgbIcon
);
499 panel
->cmykBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
500 WMResizeWidget(panel
->cmykBtn
, 46, 24);
501 WMMoveWidget(panel
->cmykBtn
, 93, 8);
502 WMSetButtonAction(panel
->cmykBtn
, modeButtonCallback
, panel
);
503 WMSetButtonImagePosition(panel
->cmykBtn
, WIPImageOnly
);
504 WMSetButtonImage(panel
->cmykBtn
, scrPtr
->cmykIcon
);
506 panel
->hsbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
507 WMResizeWidget(panel
->hsbBtn
, 46, 24);
508 WMMoveWidget(panel
->hsbBtn
, 139, 8);
509 WMSetButtonAction(panel
->hsbBtn
, modeButtonCallback
, panel
);
510 WMSetButtonImagePosition(panel
->hsbBtn
, WIPImageOnly
);
511 WMSetButtonImage(panel
->hsbBtn
, scrPtr
->hsbIcon
);
513 /* Let's Group the Slider Panel Buttons Together */
514 WMGroupButtons(panel
->grayBtn
, panel
->rgbBtn
);
515 WMGroupButtons(panel
->grayBtn
, panel
->cmykBtn
);
516 WMGroupButtons(panel
->grayBtn
, panel
->hsbBtn
);
518 textcolor
= WMDarkGrayColor(scrPtr
);
520 /* Widgets for GrayScale Panel */
521 panel
->grayFrm
= WMCreateFrame(panel
->slidersFrm
);
522 WMSetFrameRelief(panel
->grayFrm
, WRFlat
);
523 WMResizeWidget(panel
->grayFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
524 WMMoveWidget(panel
->grayFrm
, 0, 34);
526 panel
->grayMinL
= WMCreateLabel(panel
->grayFrm
);
527 WMResizeWidget(panel
->grayMinL
, 20, 10);
528 WMMoveWidget(panel
->grayMinL
, 2, 2);
529 WMSetLabelText(panel
->grayMinL
, "0");
530 WMSetLabelTextAlignment(panel
->grayMinL
, WALeft
);
531 WMSetLabelTextColor(panel
->grayMinL
, textcolor
);
532 WMSetLabelFont(panel
->grayMinL
, panel
->font8
);
534 panel
->grayMaxL
= WMCreateLabel(panel
->grayFrm
);
535 WMResizeWidget(panel
->grayMaxL
, 40, 10);
536 WMMoveWidget(panel
->grayMaxL
, 104, 2);
537 WMSetLabelText(panel
->grayMaxL
, "100");
538 WMSetLabelTextAlignment(panel
->grayMaxL
, WARight
);
539 WMSetLabelTextColor(panel
->grayMaxL
, textcolor
);
540 WMSetLabelFont(panel
->grayMaxL
, panel
->font8
);
542 panel
->grayBrightnessS
= WMCreateSlider(panel
->grayFrm
);
543 WMResizeWidget(panel
->grayBrightnessS
, 141, 16);
544 WMMoveWidget(panel
->grayBrightnessS
, 2, 14);
545 WMSetSliderMinValue(panel
->grayBrightnessS
, 0);
546 WMSetSliderMaxValue(panel
->grayBrightnessS
, 100);
547 WMSetSliderKnobThickness(panel
->grayBrightnessS
, knobThickness
);
548 WMSetSliderAction(panel
->grayBrightnessS
, grayBrightnessSliderCallback
, panel
);
558 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
559 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
560 RReleaseImage(image
);
563 W_PaintText(W_VIEW(panel
->grayBrightnessS
), pixmap
->pixmap
,
564 panel
->font12
, 2, 0, 100, WALeft
, scrPtr
->white
,
565 False
, _("Brightness"), strlen(_("Brightness")));
567 wwarning(_("Color Panel: Could not allocate memory"));
569 WMSetSliderImage(panel
->grayBrightnessS
, pixmap
);
570 WMReleasePixmap(pixmap
);
572 panel
->grayBrightnessT
= WMCreateTextField(panel
->grayFrm
);
573 WMResizeWidget(panel
->grayBrightnessT
, 40, 18);
574 WMMoveWidget(panel
->grayBrightnessT
, 146, 13);
575 WMSetTextFieldAlignment(panel
->grayBrightnessT
, WALeft
);
576 WMAddNotificationObserver(grayBrightnessTextFieldCallback
, panel
,
577 WMTextDidEndEditingNotification
, panel
->grayBrightnessT
);
579 for (i
= 0; i
< 7; i
++) {
580 pixmap
= WMCreatePixmap(scrPtr
, 13, 13, scrPtr
->depth
, False
);
582 graybuttoncolor
= WMCreateRGBColor(scrPtr
, (255 / 6) * i
<< 8,
583 (255 / 6) * i
<< 8, (255 / 6) * i
<< 8, True
);
584 WMPaintColorSwatch(graybuttoncolor
, pixmap
->pixmap
, 0, 0, 15, 15);
585 WMReleaseColor(graybuttoncolor
);
587 panel
->grayPresetBtn
[i
] = WMCreateCommandButton(panel
->grayFrm
);
588 WMResizeWidget(panel
->grayPresetBtn
[i
], 20, 24);
589 WMMoveWidget(panel
->grayPresetBtn
[i
], 2 + (i
* 20), 34);
590 WMSetButtonAction(panel
->grayPresetBtn
[i
], grayPresetButtonCallback
, panel
);
591 WMSetButtonImage(panel
->grayPresetBtn
[i
], pixmap
);
592 WMSetButtonImagePosition(panel
->grayPresetBtn
[i
], WIPImageOnly
);
593 WMReleasePixmap(pixmap
);
597 /* End of GrayScale Panel */
599 /* Widgets for RGB Panel */
600 panel
->rgbFrm
= WMCreateFrame(panel
->slidersFrm
);
601 WMSetFrameRelief(panel
->rgbFrm
, WRFlat
);
602 WMResizeWidget(panel
->rgbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
603 WMMoveWidget(panel
->rgbFrm
, 0, 34);
605 panel
->rgbMinL
= WMCreateLabel(panel
->rgbFrm
);
606 WMResizeWidget(panel
->rgbMinL
, 20, 10);
607 WMMoveWidget(panel
->rgbMinL
, 2, 2);
608 WMSetLabelText(panel
->rgbMinL
, "0");
609 WMSetLabelTextAlignment(panel
->rgbMinL
, WALeft
);
610 WMSetLabelTextColor(panel
->rgbMinL
, textcolor
);
611 WMSetLabelFont(panel
->rgbMinL
, panel
->font8
);
613 panel
->rgbMaxL
= WMCreateLabel(panel
->rgbFrm
);
614 WMResizeWidget(panel
->rgbMaxL
, 40, 10);
615 WMMoveWidget(panel
->rgbMaxL
, 104, 2);
616 WMSetLabelText(panel
->rgbMaxL
, "255");
617 WMSetLabelTextAlignment(panel
->rgbMaxL
, WARight
);
618 WMSetLabelTextColor(panel
->rgbMaxL
, textcolor
);
619 WMSetLabelFont(panel
->rgbMaxL
, panel
->font8
);
621 panel
->rgbRedS
= WMCreateSlider(panel
->rgbFrm
);
622 WMResizeWidget(panel
->rgbRedS
, 141, 16);
623 WMMoveWidget(panel
->rgbRedS
, 2, 14);
624 WMSetSliderMinValue(panel
->rgbRedS
, 0);
625 WMSetSliderMaxValue(panel
->rgbRedS
, 255);
626 WMSetSliderKnobThickness(panel
->rgbRedS
, knobThickness
);
627 WMSetSliderAction(panel
->rgbRedS
, rgbSliderCallback
, panel
);
633 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
634 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
635 RReleaseImage(image
);
638 W_PaintText(W_VIEW(panel
->rgbRedS
), pixmap
->pixmap
, panel
->font12
,
639 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Red"), strlen(_("Red")));
641 wwarning(_("Color Panel: Could not allocate memory"));
643 WMSetSliderImage(panel
->rgbRedS
, pixmap
);
644 WMReleasePixmap(pixmap
);
646 panel
->rgbRedT
= WMCreateTextField(panel
->rgbFrm
);
647 WMResizeWidget(panel
->rgbRedT
, 40, 18);
648 WMMoveWidget(panel
->rgbRedT
, 146, 13);
649 WMSetTextFieldAlignment(panel
->rgbRedT
, WALeft
);
650 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbRedT
);
652 panel
->rgbGreenS
= WMCreateSlider(panel
->rgbFrm
);
653 WMResizeWidget(panel
->rgbGreenS
, 141, 16);
654 WMMoveWidget(panel
->rgbGreenS
, 2, 36);
655 WMSetSliderMinValue(panel
->rgbGreenS
, 0);
656 WMSetSliderMaxValue(panel
->rgbGreenS
, 255);
657 WMSetSliderKnobThickness(panel
->rgbGreenS
, knobThickness
);
658 WMSetSliderAction(panel
->rgbGreenS
, rgbSliderCallback
, panel
);
664 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
665 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
666 RReleaseImage(image
);
669 W_PaintText(W_VIEW(panel
->rgbGreenS
), pixmap
->pixmap
, panel
->font12
,
670 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Green"), strlen(_("Green")));
672 wwarning(_("Color Panel: Could not allocate memory"));
674 WMSetSliderImage(panel
->rgbGreenS
, pixmap
);
675 WMReleasePixmap(pixmap
);
677 panel
->rgbGreenT
= WMCreateTextField(panel
->rgbFrm
);
678 WMResizeWidget(panel
->rgbGreenT
, 40, 18);
679 WMMoveWidget(panel
->rgbGreenT
, 146, 35);
680 WMSetTextFieldAlignment(panel
->rgbGreenT
, WALeft
);
681 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbGreenT
);
683 panel
->rgbBlueS
= WMCreateSlider(panel
->rgbFrm
);
684 WMResizeWidget(panel
->rgbBlueS
, 141, 16);
685 WMMoveWidget(panel
->rgbBlueS
, 2, 58);
686 WMSetSliderMinValue(panel
->rgbBlueS
, 0);
687 WMSetSliderMaxValue(panel
->rgbBlueS
, 255);
688 WMSetSliderKnobThickness(panel
->rgbBlueS
, knobThickness
);
689 WMSetSliderAction(panel
->rgbBlueS
, rgbSliderCallback
, panel
);
695 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
696 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
697 RReleaseImage(image
);
700 W_PaintText(W_VIEW(panel
->rgbBlueS
), pixmap
->pixmap
, panel
->font12
,
701 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Blue"), strlen(_("Blue")));
703 wwarning(_("Color Panel: Could not allocate memory"));
705 WMSetSliderImage(panel
->rgbBlueS
, pixmap
);
706 WMReleasePixmap(pixmap
);
708 panel
->rgbBlueT
= WMCreateTextField(panel
->rgbFrm
);
709 WMResizeWidget(panel
->rgbBlueT
, 40, 18);
710 WMMoveWidget(panel
->rgbBlueT
, 146, 57);
711 WMSetTextFieldAlignment(panel
->rgbBlueT
, WALeft
);
712 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbBlueT
);
713 /* End of RGB Panel */
715 /* Widgets for CMYK Panel */
716 panel
->cmykFrm
= WMCreateFrame(panel
->slidersFrm
);
717 WMSetFrameRelief(panel
->cmykFrm
, WRFlat
);
718 WMResizeWidget(panel
->cmykFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
719 WMMoveWidget(panel
->cmykFrm
, 0, 34);
721 panel
->cmykMinL
= WMCreateLabel(panel
->cmykFrm
);
722 WMResizeWidget(panel
->cmykMinL
, 20, 10);
723 WMMoveWidget(panel
->cmykMinL
, 2, 2);
724 WMSetLabelText(panel
->cmykMinL
, "0");
725 WMSetLabelTextAlignment(panel
->cmykMinL
, WALeft
);
726 WMSetLabelTextColor(panel
->cmykMinL
, textcolor
);
727 WMSetLabelFont(panel
->cmykMinL
, panel
->font8
);
729 panel
->cmykMaxL
= WMCreateLabel(panel
->cmykFrm
);
730 WMResizeWidget(panel
->cmykMaxL
, 40, 10);
731 WMMoveWidget(panel
->cmykMaxL
, 104, 2);
732 WMSetLabelText(panel
->cmykMaxL
, "100");
733 WMSetLabelTextAlignment(panel
->cmykMaxL
, WARight
);
734 WMSetLabelTextColor(panel
->cmykMaxL
, textcolor
);
735 WMSetLabelFont(panel
->cmykMaxL
, panel
->font8
);
737 panel
->cmykCyanS
= WMCreateSlider(panel
->cmykFrm
);
738 WMResizeWidget(panel
->cmykCyanS
, 141, 16);
739 WMMoveWidget(panel
->cmykCyanS
, 2, 14);
740 WMSetSliderMinValue(panel
->cmykCyanS
, 0);
741 WMSetSliderMaxValue(panel
->cmykCyanS
, 100);
742 WMSetSliderKnobThickness(panel
->cmykCyanS
, knobThickness
);
743 WMSetSliderAction(panel
->cmykCyanS
, cmykSliderCallback
, panel
);
753 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
754 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
755 RReleaseImage(image
);
758 W_PaintText(W_VIEW(panel
->cmykCyanS
), pixmap
->pixmap
, panel
->font12
,
759 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Cyan"), strlen(_("Cyan")));
761 wwarning(_("Color Panel: Could not allocate memory"));
763 WMSetSliderImage(panel
->cmykCyanS
, pixmap
);
764 WMReleasePixmap(pixmap
);
766 panel
->cmykCyanT
= WMCreateTextField(panel
->cmykFrm
);
767 WMResizeWidget(panel
->cmykCyanT
, 40, 18);
768 WMMoveWidget(panel
->cmykCyanT
, 146, 13);
769 WMSetTextFieldAlignment(panel
->cmykCyanT
, WALeft
);
770 WMAddNotificationObserver(cmykTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->cmykCyanT
);
772 panel
->cmykMagentaS
= WMCreateSlider(panel
->cmykFrm
);
773 WMResizeWidget(panel
->cmykMagentaS
, 141, 16);
774 WMMoveWidget(panel
->cmykMagentaS
, 2, 36);
775 WMSetSliderMinValue(panel
->cmykMagentaS
, 0);
776 WMSetSliderMaxValue(panel
->cmykMagentaS
, 100);
777 WMSetSliderKnobThickness(panel
->cmykMagentaS
, knobThickness
);
778 WMSetSliderAction(panel
->cmykMagentaS
, cmykSliderCallback
, panel
);
784 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
785 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
786 RReleaseImage(image
);
789 W_PaintText(W_VIEW(panel
->cmykMagentaS
), pixmap
->pixmap
, panel
->font12
,
790 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Magenta"), strlen(_("Magenta")));
792 wwarning(_("Color Panel: Could not allocate memory"));
794 WMSetSliderImage(panel
->cmykMagentaS
, pixmap
);
795 WMReleasePixmap(pixmap
);
797 panel
->cmykMagentaT
= WMCreateTextField(panel
->cmykFrm
);
798 WMResizeWidget(panel
->cmykMagentaT
, 40, 18);
799 WMMoveWidget(panel
->cmykMagentaT
, 146, 35);
800 WMSetTextFieldAlignment(panel
->cmykMagentaT
, WALeft
);
801 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
802 WMTextDidEndEditingNotification
, panel
->cmykMagentaT
);
804 panel
->cmykYellowS
= WMCreateSlider(panel
->cmykFrm
);
805 WMResizeWidget(panel
->cmykYellowS
, 141, 16);
806 WMMoveWidget(panel
->cmykYellowS
, 2, 58);
807 WMSetSliderMinValue(panel
->cmykYellowS
, 0);
808 WMSetSliderMaxValue(panel
->cmykYellowS
, 100);
809 WMSetSliderKnobThickness(panel
->cmykYellowS
, knobThickness
);
810 WMSetSliderAction(panel
->cmykYellowS
, cmykSliderCallback
, panel
);
816 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
817 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
818 RReleaseImage(image
);
821 W_PaintText(W_VIEW(panel
->cmykYellowS
), pixmap
->pixmap
, panel
->font12
,
822 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Yellow"), strlen(_("Yellow")));
824 wwarning(_("Color Panel: Could not allocate memory"));
826 WMSetSliderImage(panel
->cmykYellowS
, pixmap
);
827 WMReleasePixmap(pixmap
);
829 panel
->cmykYellowT
= WMCreateTextField(panel
->cmykFrm
);
830 WMResizeWidget(panel
->cmykYellowT
, 40, 18);
831 WMMoveWidget(panel
->cmykYellowT
, 146, 57);
832 WMSetTextFieldAlignment(panel
->cmykYellowT
, WALeft
);
833 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
834 WMTextDidEndEditingNotification
, panel
->cmykYellowT
);
836 panel
->cmykBlackS
= WMCreateSlider(panel
->cmykFrm
);
837 WMResizeWidget(panel
->cmykBlackS
, 141, 16);
838 WMMoveWidget(panel
->cmykBlackS
, 2, 80);
839 WMSetSliderMinValue(panel
->cmykBlackS
, 0);
840 WMSetSliderMaxValue(panel
->cmykBlackS
, 100);
841 WMSetSliderValue(panel
->cmykBlackS
, 0);
842 WMSetSliderKnobThickness(panel
->cmykBlackS
, knobThickness
);
843 WMSetSliderAction(panel
->cmykBlackS
, cmykSliderCallback
, panel
);
849 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
850 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
851 RReleaseImage(image
);
854 W_PaintText(W_VIEW(panel
->cmykBlackS
), pixmap
->pixmap
, panel
->font12
,
855 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Black"), strlen(_("Black")));
857 wwarning(_("Color Panel: Could not allocate memory"));
859 WMSetSliderImage(panel
->cmykBlackS
, pixmap
);
860 WMReleasePixmap(pixmap
);
862 panel
->cmykBlackT
= WMCreateTextField(panel
->cmykFrm
);
863 WMResizeWidget(panel
->cmykBlackT
, 40, 18);
864 WMMoveWidget(panel
->cmykBlackT
, 146, 79);
865 WMSetTextFieldAlignment(panel
->cmykBlackT
, WALeft
);
866 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
867 WMTextDidEndEditingNotification
, panel
->cmykBlackT
);
868 /* End of CMYK Panel */
870 /* Widgets for HSB Panel */
871 panel
->hsbFrm
= WMCreateFrame(panel
->slidersFrm
);
872 WMSetFrameRelief(panel
->hsbFrm
, WRFlat
);
873 WMResizeWidget(panel
->hsbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
874 WMMoveWidget(panel
->hsbFrm
, 0, 34);
876 panel
->hsbHueS
= WMCreateSlider(panel
->hsbFrm
);
877 WMResizeWidget(panel
->hsbHueS
, 141, 16);
878 WMMoveWidget(panel
->hsbHueS
, 2, 14);
879 WMSetSliderMinValue(panel
->hsbHueS
, 0);
880 WMSetSliderMaxValue(panel
->hsbHueS
, 359);
881 WMSetSliderKnobThickness(panel
->hsbHueS
, knobThickness
);
882 WMSetSliderAction(panel
->hsbHueS
, hsbSliderCallback
, panel
);
884 panel
->hsbHueT
= WMCreateTextField(panel
->hsbFrm
);
885 WMResizeWidget(panel
->hsbHueT
, 40, 18);
886 WMMoveWidget(panel
->hsbHueT
, 146, 13);
887 WMSetTextFieldAlignment(panel
->hsbHueT
, WALeft
);
888 WMAddNotificationObserver(hsbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->hsbHueT
);
890 panel
->hsbSaturationS
= WMCreateSlider(panel
->hsbFrm
);
891 WMResizeWidget(panel
->hsbSaturationS
, 141, 16);
892 WMMoveWidget(panel
->hsbSaturationS
, 2, 36);
893 WMSetSliderMinValue(panel
->hsbSaturationS
, 0);
894 WMSetSliderMaxValue(panel
->hsbSaturationS
, 100);
895 WMSetSliderKnobThickness(panel
->hsbSaturationS
, knobThickness
);
896 WMSetSliderAction(panel
->hsbSaturationS
, hsbSliderCallback
, panel
);
898 panel
->hsbSaturationT
= WMCreateTextField(panel
->hsbFrm
);
899 WMResizeWidget(panel
->hsbSaturationT
, 40, 18);
900 WMMoveWidget(panel
->hsbSaturationT
, 146, 35);
901 WMSetTextFieldAlignment(panel
->hsbSaturationT
, WALeft
);
902 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
903 WMTextDidEndEditingNotification
, panel
->hsbSaturationT
);
905 panel
->hsbBrightnessS
= WMCreateSlider(panel
->hsbFrm
);
906 WMResizeWidget(panel
->hsbBrightnessS
, 141, 16);
907 WMMoveWidget(panel
->hsbBrightnessS
, 2, 58);
908 WMSetSliderMinValue(panel
->hsbBrightnessS
, 0);
909 WMSetSliderMaxValue(panel
->hsbBrightnessS
, 100);
910 WMSetSliderKnobThickness(panel
->hsbBrightnessS
, knobThickness
);
911 WMSetSliderAction(panel
->hsbBrightnessS
, hsbSliderCallback
, panel
);
913 panel
->hsbBrightnessT
= WMCreateTextField(panel
->hsbFrm
);
914 WMResizeWidget(panel
->hsbBrightnessT
, 40, 18);
915 WMMoveWidget(panel
->hsbBrightnessT
, 146, 57);
916 WMSetTextFieldAlignment(panel
->hsbBrightnessT
, WALeft
);
917 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
918 WMTextDidEndEditingNotification
, panel
->hsbBrightnessT
);
919 /* End of HSB Panel */
921 WMReleaseColor(textcolor
);
923 /* Widgets for the CustomPalette Panel */
924 panel
->customPaletteFrm
= WMCreateFrame(panel
->win
);
925 WMSetFrameRelief(panel
->customPaletteFrm
, WRFlat
);
926 WMResizeWidget(panel
->customPaletteFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
927 WMMoveWidget(panel
->customPaletteFrm
, 5, 80);
929 panel
->customPaletteHistoryBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
930 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, _("Spectrum"));
931 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
932 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1);
933 WMSetPopUpButtonAction(panel
->customPaletteHistoryBtn
, customPaletteHistoryCallback
, panel
);
934 WMResizeWidget(panel
->customPaletteHistoryBtn
, PWIDTH
- 8, 20);
935 WMMoveWidget(panel
->customPaletteHistoryBtn
, 0, 0);
937 panel
->customPaletteContentFrm
= WMCreateFrame(panel
->customPaletteFrm
);
938 WMSetFrameRelief(panel
->customPaletteContentFrm
, WRSunken
);
939 WMResizeWidget(panel
->customPaletteContentFrm
, PWIDTH
- 8, PHEIGHT
- 156);
940 WMMoveWidget(panel
->customPaletteContentFrm
, 0, 23);
942 panel
->customPaletteContentView
= W_CreateView(W_VIEW(panel
->customPaletteContentFrm
));
943 /* XXX Test if we can create a view */
944 W_ResizeView(panel
->customPaletteContentView
, customPaletteWidth
, customPaletteHeight
);
945 W_MoveView(panel
->customPaletteContentView
, 2, 2);
947 /* Create event handler to handle expose/click events in CustomPalette */
948 WMCreateEventHandler(panel
->customPaletteContentView
,
949 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
| LeaveWindowMask
|
950 ButtonMotionMask
, customPaletteHandleActionEvents
, panel
);
952 WMCreateEventHandler(panel
->customPaletteContentView
, ExposureMask
, customPaletteHandleEvents
, panel
);
954 panel
->customPaletteMenuBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
955 WMSetPopUpButtonPullsDown(panel
->customPaletteMenuBtn
, 1);
956 WMSetPopUpButtonText(panel
->customPaletteMenuBtn
, _("Palette"));
957 WMSetPopUpButtonAction(panel
->customPaletteMenuBtn
, customPaletteMenuCallback
, panel
);
958 WMResizeWidget(panel
->customPaletteMenuBtn
, PWIDTH
- 8, 20);
959 WMMoveWidget(panel
->customPaletteMenuBtn
, 0, PHEIGHT
- 130);
961 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from File..."));
962 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Rename..."));
963 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Remove"));
964 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Copy"));
965 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from Clipboard"));
967 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, 0);
968 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, 0);
969 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuCopy
, 0);
970 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuNewFromClipboard
, 0);
972 customRenderSpectrum(panel
);
973 panel
->currentPalette
= 0;
974 panel
->palx
= customPaletteWidth
/ 2;
975 panel
->paly
= customPaletteHeight
/ 2;
977 /* Widgets for the ColorList Panel */
978 panel
->colorListFrm
= WMCreateFrame(panel
->win
);
979 WMSetFrameRelief(panel
->colorListFrm
, WRFlat
);
980 WMResizeWidget(panel
->colorListFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
981 WMMoveWidget(panel
->colorListFrm
, 5, 80);
983 panel
->colorListHistoryBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
984 WMAddPopUpButtonItem(panel
->colorListHistoryBtn
, _("X11-Colors"));
985 WMSetPopUpButtonSelectedItem(panel
->colorListHistoryBtn
,
986 WMGetPopUpButtonNumberOfItems(panel
->colorListHistoryBtn
) - 1);
987 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
988 * colorListHistoryCallback, panel); */
989 WMResizeWidget(panel
->colorListHistoryBtn
, PWIDTH
- 8, 20);
990 WMMoveWidget(panel
->colorListHistoryBtn
, 0, 0);
992 panel
->colorListContentLst
= WMCreateList(panel
->colorListFrm
);
993 WMSetListAction(panel
->colorListContentLst
, colorListSelect
, panel
);
994 WMSetListUserDrawProc(panel
->colorListContentLst
, colorListPaintItem
);
995 WMResizeWidget(panel
->colorListContentLst
, PWIDTH
- 8, PHEIGHT
- 156);
996 WMMoveWidget(panel
->colorListContentLst
, 0, 23);
997 WMHangData(panel
->colorListContentLst
, panel
);
999 panel
->colorListColorMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1000 WMSetPopUpButtonPullsDown(panel
->colorListColorMenuBtn
, 1);
1001 WMSetPopUpButtonText(panel
->colorListColorMenuBtn
, _("Color"));
1002 WMSetPopUpButtonAction(panel
->colorListColorMenuBtn
, colorListColorMenuCallback
, panel
);
1003 WMResizeWidget(panel
->colorListColorMenuBtn
, (PWIDTH
- 16) / 2, 20);
1004 WMMoveWidget(panel
->colorListColorMenuBtn
, 0, PHEIGHT
- 130);
1006 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Add..."));
1007 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Rename..."));
1008 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Remove"));
1010 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuAdd
, 0);
1011 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRename
, 0);
1012 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRemove
, 0);
1014 panel
->colorListListMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1015 WMSetPopUpButtonPullsDown(panel
->colorListListMenuBtn
, 1);
1016 WMSetPopUpButtonText(panel
->colorListListMenuBtn
, _("List"));
1017 WMSetPopUpButtonAction(panel
->colorListListMenuBtn
, colorListListMenuCallback
, panel
);
1018 WMResizeWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2, 20);
1019 WMMoveWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2 + 8, PHEIGHT
- 130);
1021 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("New..."));
1022 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Rename..."));
1023 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Remove"));
1025 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuAdd
, 0);
1026 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRename
, 0);
1027 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRemove
, 0);
1029 WMRealizeWidget(panel
->win
);
1030 WMMapSubwidgets(panel
->win
);
1032 WMMapSubwidgets(panel
->wheelFrm
);
1033 WMMapSubwidgets(panel
->slidersFrm
);
1034 WMMapSubwidgets(panel
->grayFrm
);
1035 WMMapSubwidgets(panel
->rgbFrm
);
1036 WMMapSubwidgets(panel
->cmykFrm
);
1037 WMMapSubwidgets(panel
->hsbFrm
);
1038 WMMapSubwidgets(panel
->customPaletteFrm
);
1039 WMMapSubwidgets(panel
->customPaletteContentFrm
);
1040 WMMapSubwidgets(panel
->colorListFrm
);
1042 /* Pixmap to indicate selection positions
1043 * wheelframe MUST be mapped.
1045 panel
->selectionImg
= XCreatePixmap(scrPtr
->display
, WMWidgetXID(panel
->win
), 4, 4, scrPtr
->depth
);
1046 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, bgc
, 0, 0, 4, 4);
1047 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, wgc
, 1, 1, 2, 2);
1049 readConfiguration(panel
);
1055 WMColorPanel
*WMGetColorPanel(WMScreen
* scrPtr
)
1057 WMColorPanel
*panel
;
1059 if (scrPtr
->sharedColorPanel
)
1060 return scrPtr
->sharedColorPanel
;
1062 panel
= makeColorPanel(scrPtr
, "colorPanel");
1064 scrPtr
->sharedColorPanel
= panel
;
1069 void WMFreeColorPanel(WMColorPanel
* panel
)
1071 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1073 if (panel
== scr
->sharedColorPanel
) {
1074 scr
->sharedColorPanel
= NULL
;
1080 WMRemoveNotificationObserver(panel
);
1081 WMUnmapWidget(panel
->win
);
1084 WMReleaseFont(panel
->font8
);
1085 WMReleaseFont(panel
->font12
);
1088 wheelDestroyMatrix(panel
->wheelMtrx
);
1089 if (panel
->wheelImg
)
1090 XFreePixmap(scr
->display
, panel
->wheelImg
);
1091 if (panel
->selectionImg
)
1092 XFreePixmap(scr
->display
, panel
->selectionImg
);
1093 if (panel
->selectionBackImg
)
1094 XFreePixmap(scr
->display
, panel
->selectionBackImg
);
1095 RReleaseImage(panel
->customPaletteImg
);
1098 if (panel
->lastBrowseDir
)
1099 wfree(panel
->lastBrowseDir
);
1100 if (panel
->configurationPath
)
1101 wfree(panel
->configurationPath
);
1103 WMDestroyWidget(panel
->win
);
1108 void WMCloseColorPanel(WMColorPanel
* panel
)
1110 WMFreeColorPanel(panel
);
1113 void WMShowColorPanel(WMColorPanel
* panel
)
1115 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1116 WMColor
*white
= WMWhiteColor(scr
);
1118 if (panel
->color
.set
== cpNone
)
1119 WMSetColorPanelColor(panel
, white
);
1120 WMReleaseColor(white
);
1122 if (panel
->mode
!= WMWheelModeColorPanel
)
1123 WMPerformButtonClick(panel
->wheelBtn
);
1125 WMMapWidget(panel
->win
);
1128 static void closeWindowCallback(WMWidget
* w
, void *data
)
1130 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
1132 WMCloseColorPanel(panel
);
1135 static void readConfiguration(W_ColorPanel
* panel
)
1137 /* XXX Doesn't take care of "invalid" files */
1141 struct stat stat_buf
;
1144 if (stat(panel
->configurationPath
, &stat_buf
) != 0) {
1145 if (mkdir(panel
->configurationPath
, S_IRWXU
| S_IRGRP
| S_IROTH
| S_IXGRP
| S_IXOTH
) != 0) {
1146 werror(_("Color Panel: Could not create directory %s needed"
1147 " to store configurations"), panel
->configurationPath
);
1148 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1149 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1150 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1151 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1153 _("Could not create ColorPanel configuration directory"),
1154 _("OK"), NULL
, NULL
);
1159 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1160 wwarning("%s: %s", _("Color Panel: Could not find file"), panel
->configurationPath
);
1164 while ((dp
= readdir(dPtr
)) != NULL
) {
1165 unsigned int perm_mask
;
1166 char *path
= wstrconcat(panel
->configurationPath
,
1169 if (dp
->d_name
[0] != '.') {
1170 item
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
1171 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1173 perm_mask
= (access(path
, R_OK
) == 0);
1174 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
, item
, perm_mask
);
1181 static void readXColors(W_ColorPanel
* panel
)
1186 for (entry
= rgbColors
; entry
->name
!= NULL
; entry
++) {
1187 item
= WMAddListItem(panel
->colorListContentLst
, entry
->name
);
1188 item
->clientData
= (void *)&(entry
->color
);
1192 void WMSetColorPanelPickerMode(WMColorPanel
* panel
, WMColorPanelMode mode
)
1194 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1196 if (mode
!= WMWheelModeColorPanel
) {
1197 WMUnmapWidget(panel
->wheelFrm
);
1198 if (panel
->selectionBackImg
) {
1199 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1200 panel
->selectionBackImg
= None
;
1203 if (mode
!= WMGrayModeColorPanel
)
1204 WMUnmapWidget(panel
->grayFrm
);
1205 if (mode
!= WMRGBModeColorPanel
)
1206 WMUnmapWidget(panel
->rgbFrm
);
1207 if (mode
!= WMCMYKModeColorPanel
)
1208 WMUnmapWidget(panel
->cmykFrm
);
1209 if (mode
!= WMHSBModeColorPanel
)
1210 WMUnmapWidget(panel
->hsbFrm
);
1211 if (mode
!= WMCustomPaletteModeColorPanel
) {
1212 WMUnmapWidget(panel
->customPaletteFrm
);
1213 if (panel
->selectionBackImg
) {
1214 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1215 panel
->selectionBackImg
= None
;
1218 if (mode
!= WMColorListModeColorPanel
)
1219 WMUnmapWidget(panel
->colorListFrm
);
1220 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1221 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1222 WMUnmapWidget(panel
->slidersFrm
);
1224 panel
->slidersmode
= mode
;
1226 if (mode
== WMWheelModeColorPanel
) {
1227 WMMapWidget(panel
->wheelFrm
);
1228 WMSetButtonSelected(panel
->wheelBtn
, True
);
1229 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1233 } else if (mode
== WMGrayModeColorPanel
) {
1234 WMMapWidget(panel
->slidersFrm
);
1235 WMSetButtonSelected(panel
->slidersBtn
, True
);
1236 WMMapWidget(panel
->grayFrm
);
1237 WMSetButtonSelected(panel
->grayBtn
, True
);
1238 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1239 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1241 } else if (mode
== WMRGBModeColorPanel
) {
1242 WMMapWidget(panel
->slidersFrm
);
1243 WMSetButtonSelected(panel
->slidersBtn
, True
);
1244 WMMapWidget(panel
->rgbFrm
);
1245 WMSetButtonSelected(panel
->rgbBtn
, True
);
1246 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1247 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1249 } else if (mode
== WMCMYKModeColorPanel
) {
1250 WMMapWidget(panel
->slidersFrm
);
1251 WMSetButtonSelected(panel
->slidersBtn
, True
);
1252 WMMapWidget(panel
->cmykFrm
);
1253 WMSetButtonSelected(panel
->cmykBtn
, True
);
1254 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1255 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1257 } else if (mode
== WMHSBModeColorPanel
) {
1258 WMMapWidget(panel
->slidersFrm
);
1259 WMSetButtonSelected(panel
->slidersBtn
, True
);
1260 WMMapWidget(panel
->hsbFrm
);
1261 WMSetButtonSelected(panel
->hsbBtn
, True
);
1262 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1263 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1265 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1266 WMMapWidget(panel
->customPaletteFrm
);
1267 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1268 customSetPalette(panel
);
1269 } else if (mode
== WMColorListModeColorPanel
) {
1270 WMMapWidget(panel
->colorListFrm
);
1271 WMSetButtonSelected(panel
->colorListBtn
, True
);
1277 WMColor
*WMGetColorPanelColor(WMColorPanel
* panel
)
1279 return WMGetColorWellColor(panel
->colorWell
);
1282 void WMSetColorPanelColor(WMColorPanel
* panel
, WMColor
* color
)
1284 WMSetColorWellColor(panel
->colorWell
, color
);
1286 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1287 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1288 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1289 panel
->color
.set
= cpRGB
;
1291 if (panel
->mode
== panel
->lastChanged
)
1292 panel
->lastChanged
= 0;
1294 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1297 static void updateSwatch(WMColorPanel
* panel
, CPColor color
)
1299 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1302 if (color
.set
!= cpRGB
)
1303 convertCPColor(&color
);
1305 panel
->color
= color
;
1307 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8, color
.rgb
.green
<< 8, color
.rgb
.blue
<< 8, True
);
1309 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1310 WMReleaseColor(wellcolor
);
1312 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1314 (*panel
->action
) (panel
, panel
->clientData
);
1316 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
, NULL
);
1320 static void modeButtonCallback(WMWidget
* w
, void *data
)
1322 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1324 if (w
== panel
->wheelBtn
)
1325 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1326 else if (w
== panel
->slidersBtn
)
1327 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1328 else if (w
== panel
->customPaletteBtn
)
1329 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1330 else if (w
== panel
->colorListBtn
)
1331 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1332 else if (w
== panel
->grayBtn
)
1333 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1334 else if (w
== panel
->rgbBtn
)
1335 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1336 else if (w
== panel
->cmykBtn
)
1337 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1338 else if (w
== panel
->hsbBtn
)
1339 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1342 /****************** Magnifying Cursor Functions *******************/
1344 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
)
1346 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1347 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1348 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1350 if (!(image
&& image
->data
)) {
1351 /* The image in panel->magnifyGlass->image does not exist yet.
1352 * Grab one from the screen (not beyond) and use it from now on.
1354 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1355 x
- Cursor_x_hot
, y
- Cursor_y_hot
, w
, h
, AllPlanes
, ZPixmap
)))
1356 wwarning(_("Color Panel: X failed request"));
1361 /* Coordinate correction for back pixmap
1362 * if magnifying glass is at screen-borders
1365 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1366 * Hatched area is beyond screen border.
1368 * |<-Cursor_x_hot->|
1369 * ________________|_____
1370 * |/ / / / / / /| | |
1371 * | / / / / / / |(x,y) |
1372 * |/_/_/_/_/_/_/|________|
1373 * |<----x0----->|<--w0-->|
1377 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1379 * Hatched area is beyond screen border
1381 * |<-Cursor_x_hot->|
1382 * ________________|_______________
1383 * | | | / / / / / /|
1384 * | (x,y)|/ / / / / / |
1385 * |___________________|_/_/_/_/_/_/|
1386 * |<-------w0-------->| |
1387 * |<---------------w--|----------->|
1392 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1393 x0
= Cursor_x_hot
- x
;
1397 if (displayWidth
- 1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1398 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1401 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1402 y0
= Cursor_y_hot
- y
;
1406 if (displayHeight
- 1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1407 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1409 /* end of coordinate correction */
1411 /* Grab an image from the screen, clipped if necessary,
1412 * and put it in the existing panel->magnifyGlass->image
1413 * with the corresponding clipping offset.
1415 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1416 x
- Cursor_x_hot
+ x0
, y
- Cursor_y_hot
+ y0
, w0
, h0
, AllPlanes
, ZPixmap
, image
, x0
, y0
))
1417 wwarning(_("Color Panel: X failed request"));
1422 static void magnifyGetImageStored(WMColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
)
1424 /* (x1, y1) = topleft corner of existing rectangle
1425 * (x2, y2) = topleft corner of new position
1428 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1429 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1431 const int dx
= abs(x2
- x1
), dy
= abs(y2
- y1
);
1433 const int x_min
= Cursor_x_hot
,
1434 y_min
= Cursor_y_hot
,
1435 x_max
= DisplayWidth(scr
->display
, scr
->screen
) - 1 -
1436 (Cursor_mask_width
- Cursor_x_hot
),
1437 y_max
= DisplayHeight(scr
->display
, scr
->screen
) - 1 - (Cursor_mask_height
- Cursor_y_hot
);
1439 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1440 return; /* No movement */
1452 width
= Cursor_mask_width
- dx
;
1453 height
= Cursor_mask_height
- dy
;
1455 /* If the traversed distance is larger than the size of the magnifying
1456 * glass contents, there is no need to do dirty rectangles. A whole new
1457 * rectangle can be grabbed (unless that rectangle falls partially
1459 * Destroying the image and setting it to NULL will achieve that later on.
1461 * Of course, grabbing an XImage beyond the borders of the screen will
1462 * cause trouble, this is considdered a special case. Part of the screen
1463 * is grabbed, but there is no need for dirty rectangles.
1465 if ((width
<= 0) || (height
<= 0)) {
1466 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1467 if (panel
->magnifyGlass
->image
)
1468 XDestroyImage(panel
->magnifyGlass
->image
);
1469 panel
->magnifyGlass
->image
= NULL
;
1472 if (panel
->magnifyGlass
->image
) {
1473 /* Get dirty rectangle from panel->magnifyGlass->image */
1474 panel
->magnifyGlass
->dirtyRect
=
1475 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1476 if (!panel
->magnifyGlass
->dirtyRect
) {
1477 wwarning(_("Color Panel: X failed request"));
1478 return; /* X returned a NULL from XSubImage */
1483 /* Get image from screen */
1484 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
, Cursor_mask_width
, Cursor_mask_height
);
1485 if (image
) { /* Only reassign if a *new* image was grabbed */
1486 panel
->magnifyGlass
->image
= image
;
1490 /* Copy previously stored rectangle on covered part of image */
1491 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1494 /* "width" and "height" are used as coordinates here,
1495 * and run from [0...width-1] and [0...height-1] respectively.
1499 old_height
= height
;
1501 for (; width
>= 0; width
--)
1502 for (height
= old_height
; height
>= 0; height
--)
1503 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1504 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1505 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1506 panel
->magnifyGlass
->dirtyRect
= NULL
;
1512 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
)
1514 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1519 unsigned long color
;
1521 if (!panel
->magnifyGlass
->image
)
1524 if (!panel
->magnifyGlass
->magPix
)
1528 * Copy an area of only 5x5 pixels from the center of the image.
1530 for (u
= 0; u
< 5; u
++) {
1531 for (v
= 0; v
< 5; v
++) {
1532 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1534 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1536 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1537 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1539 /* The center square must eventually be centered around the
1540 * hotspot. The image needs shifting to achieve this. The amount of
1541 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1544 * ^------- center of center square == Cursor_x_hot
1546 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1548 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1549 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1554 return panel
->magnifyGlass
->magPix
;
1556 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
, Cursor_mask_height
, scr
->depth
);
1560 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1561 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1563 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1564 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1565 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1566 /* (2,2) puts center pixel on center of glass */
1573 static WMView
*magnifyCreateView(W_ColorPanel
* panel
)
1575 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1578 magView
= W_CreateTopView(scr
);
1582 magView
->self
= panel
->win
;
1583 magView
->flags
.topLevel
= 1;
1584 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1585 magView
->attribs
.override_redirect
= True
;
1586 magView
->attribs
.save_under
= True
;
1588 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1590 W_RealizeView(magView
);
1595 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
)
1597 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1598 Pixmap magPixmap
, magPixmap2
;
1600 XColor fgColor
= { 0, 0, 0, 0, DoRed
| DoGreen
| DoBlue
, 0 };
1601 XColor bgColor
= { 0, 0xbf00, 0xa000, 0x5000, DoRed
| DoGreen
| DoBlue
, 0 };
1603 /* Cursor creation stuff */
1604 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1605 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1606 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1607 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1609 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1610 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1612 XFreePixmap(scr
->display
, magPixmap
);
1613 XFreePixmap(scr
->display
, magPixmap2
);
1615 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1617 /* Set up Pointer */
1618 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1619 PointerMotionMask
| ButtonPressMask
,
1620 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1625 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
)
1627 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1630 Pixmap pixmap
, clip_mask
;
1632 Window root_return
, child_return
;
1634 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1635 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1637 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1638 5 * 5 - 1, 5 * 5 - 1, scr
->depth
);
1640 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
, &x
, &y
, &u
, &v
, &mask
);
1642 panel
->magnifyGlass
->image
= NULL
;
1644 /* Clipmask to make magnified view-contents circular */
1646 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1647 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1649 /* Clip circle in glass cursor */
1650 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1651 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1654 XFreePixmap(scr
->display
, clip_mask
);
1656 /* Draw initial magnifying glass contents */
1657 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1659 pixmap
= magnifyCreatePixmap(panel
);
1660 XSetWindowBackgroundPixmap(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1661 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1662 XFlush(scr
->display
);
1665 XFreePixmap(scr
->display
, pixmap
);
1674 static void magnifyPutCursor(WMWidget
* w
, void *data
)
1676 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1677 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1681 WMPoint initialPosition
;
1683 /* Destroy wheelBackImg, so it'll update properly */
1684 if (panel
->selectionBackImg
) {
1685 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1686 panel
->selectionBackImg
= None
;
1689 /* Create magnifying glass */
1690 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1691 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1692 if (!panel
->magnifyGlass
->view
)
1695 initialPosition
= magnifyInitialize(panel
);
1696 panel
->magnifyGlass
->x
= initialPosition
.x
;
1697 panel
->magnifyGlass
->y
= initialPosition
.y
;
1699 W_MoveView(panel
->magnifyGlass
->view
,
1700 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1701 W_MapView(panel
->magnifyGlass
->view
);
1703 magCursor
= magnifyGrabPointer(panel
);
1705 while (panel
->magnifyGlass
->image
) {
1706 WMNextEvent(scr
->display
, &event
);
1708 /* Pack motion events */
1709 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1712 switch (event
.type
) {
1714 XDestroyImage(panel
->magnifyGlass
->image
);
1715 panel
->magnifyGlass
->image
= NULL
;
1717 if (event
.xbutton
.button
== Button1
) {
1718 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1719 panel
->color
.set
= cpRGB
;
1720 updateSwatch(panel
, panel
->color
);
1722 switch (panel
->mode
) {
1723 case WMWheelModeColorPanel
:
1728 case WMGrayModeColorPanel
:
1731 case WMRGBModeColorPanel
:
1734 case WMCMYKModeColorPanel
:
1737 case WMHSBModeColorPanel
:
1743 panel
->lastChanged
= panel
->mode
;
1745 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1749 while (XPending(event
.xmotion
.display
)) {
1751 XPeekEvent(event
.xmotion
.display
, &ev
);
1752 if (ev
.type
== MotionNotify
)
1753 XNextEvent(event
.xmotion
.display
, &event
);
1758 /* Get a "dirty rectangle" */
1759 magnifyGetImageStored(panel
,
1760 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1761 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1763 /* Update coordinates */
1764 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1765 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1768 W_MoveView(panel
->magnifyGlass
->view
,
1769 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1771 /* Put new image (with magn.) in view */
1772 pixmap
= magnifyCreatePixmap(panel
);
1773 if (pixmap
!= None
) {
1774 /* Change the window background */
1775 XSetWindowBackgroundPixmap(scr
->display
,
1776 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1777 /* Force an Expose (handled by X) */
1778 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1779 /* Synchronize the event queue, so the Expose is handled NOW */
1780 XFlush(scr
->display
);
1782 XFreePixmap(scr
->display
, pixmap
);
1787 /* Try XQueryPointer for this !!! It returns windows that the pointer
1788 * is over. Note: We found this solving the invisible donkey cap bug
1790 #if 0 /* As it is impossible to make this work in all cases,
1791 * we consider it confusing. Therefore we disabled it.
1793 case FocusOut
: /* fall through */
1796 * Color Panel window (panel->win) lost or received focus.
1797 * We need to update the pixmap in the magnifying glass.
1799 * BUG Doesn't work with focus switches between two windows
1800 * if none of them is the color panel.
1802 XUngrabPointer(scr
->display
, CurrentTime
);
1803 W_UnmapView(panel
->magnifyGlass
->view
);
1805 magnifyInitialize(panel
);
1807 W_MapView(panel
->magnifyGlass
->view
);
1808 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
,
1809 True
, PointerMotionMask
| ButtonPressMask
,
1810 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1814 WMHandleEvent(&event
);
1819 XUngrabPointer(scr
->display
, CurrentTime
);
1820 XFreeCursor(scr
->display
, magCursor
);
1822 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1823 panel
->magnifyGlass
->magPix
= None
;
1825 W_UnmapView(panel
->magnifyGlass
->view
);
1826 W_DestroyView(panel
->magnifyGlass
->view
);
1827 panel
->magnifyGlass
->view
= NULL
;
1829 wfree(panel
->magnifyGlass
);
1832 /****************** ColorWheel Functions ************************/
1834 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
)
1836 wheelMatrix
*matrix
= NULL
;
1839 assert((width
> 0) && (height
> 0));
1841 matrix
= wmalloc(sizeof(wheelMatrix
));
1842 matrix
->width
= width
;
1843 matrix
->height
= height
;
1845 for (i
= 0; i
< 3; i
++) {
1846 matrix
->data
[i
] = wmalloc(width
* height
* sizeof(unsigned char));
1852 static void wheelDestroyMatrix(wheelMatrix
* matrix
)
1859 for (i
= 0; i
< 3; i
++) {
1860 if (matrix
->data
[i
])
1861 wfree(matrix
->data
[i
]);
1866 static void wheelInitMatrix(W_ColorPanel
* panel
)
1870 unsigned char *rp
, *gp
, *bp
;
1876 const int cw_halfsize
= (colorWheelSize
+ 4) / 2,
1877 cw_sqsize
= (colorWheelSize
+ 4) * (colorWheelSize
+ 4), uchar_shift
= getShift(sizeof(unsigned char));
1879 if (!panel
->wheelMtrx
)
1882 cpColor
.hsv
.value
= 255;
1883 cpColor
.set
= cpHSV
;
1886 ofs
[1] = -(colorWheelSize
+ 4);
1888 /* offsets are counterclockwise (in triangles).
1891 * _______________________________________
1892 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
1893 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
1894 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
1895 * o | | | | | | | | | | | | | | | | | | | | | [3]
1899 * |\ /| <-- triangles
1905 for (y
= 0; y
< cw_halfsize
; y
++) {
1906 for (x
= y
; x
< (colorWheelSize
+ 4 - y
); x
++) {
1907 /* (xcor, ycor) is (x,y) relative to center of matrix */
1908 xcor
= 2 * x
- 4 - colorWheelSize
;
1909 ycor
= 2 * y
- 4 - colorWheelSize
;
1911 /* RColor.saturation is unsigned char and will wrap after 255 */
1912 sat
= rint(255.0 * sqrt(xcor
* xcor
+ ycor
* ycor
) / colorWheelSize
);
1914 cpColor
.hsv
.saturation
= (unsigned char)sat
;
1916 ofs
[0]++; /* top quarter of matrix */
1917 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
1918 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
1919 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
1923 dhue
[0] = rint(atan((double)ycor
/ (double)xcor
) *
1924 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
1928 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
1929 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
1930 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
1931 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
1933 for (i
= 0; i
< 4; i
++) {
1934 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1935 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1936 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1938 cpColor
.hsv
.hue
= dhue
[i
];
1939 convertCPColor(&cpColor
);
1941 *rp
= (unsigned char)(cpColor
.rgb
.red
);
1942 *gp
= (unsigned char)(cpColor
.rgb
.green
);
1943 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
1946 for (i
= 0; i
< 4; i
++) {
1947 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1948 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1949 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1951 *rp
= (unsigned char)0;
1952 *gp
= (unsigned char)0;
1953 *bp
= (unsigned char)0;
1958 ofs
[0] += 2 * y
+ 1;
1959 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2 * y
);
1963 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
)
1968 for (i
= 0; i
< 256; i
++) {
1969 /* We divide by 128 in advance, and check whether that number divides
1970 * by 2 properly. If not, we add one to round the number correctly
1972 v
= (i
* maxvalue
) >> 7;
1973 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) + (v
& 0x01));
1977 static void wheelRender(W_ColorPanel
* panel
)
1979 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1984 unsigned long ofs
= 0;
1985 /*unsigned char shift = getShift(sizeof(unsigned char)); */
1987 image
= RCreateImage(colorWheelSize
+ 4, colorWheelSize
+ 4, True
);
1989 wwarning(_("Color Panel: Could not allocate memory"));
1995 /* TODO Make this transparent istead of gray */
1996 gray
.red
= gray
.blue
= 0xae;
1999 for (y
= 0; y
< colorWheelSize
+ 4; y
++) {
2000 for (x
= 0; x
< colorWheelSize
+ 4; x
++) {
2001 if (wheelInsideColorWheel(panel
, ofs
)) {
2003 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]]);
2005 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]]);
2007 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]]);
2010 *(ptr
++) = (unsigned char)(gray
.red
);
2011 *(ptr
++) = (unsigned char)(gray
.green
);
2012 *(ptr
++) = (unsigned char)(gray
.blue
);
2019 if (panel
->wheelImg
)
2020 XFreePixmap(scr
->display
, panel
->wheelImg
);
2022 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2023 RReleaseImage(image
);
2025 /* Check if backimage exists. If it doesn't, allocate and fill it */
2026 if (!panel
->selectionBackImg
) {
2027 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2028 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2029 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2030 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2031 /* -2 is hot spot correction */
2035 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
)
2037 return ((panel
->wheelMtrx
->data
[0][ofs
] != 0) &&
2038 (panel
->wheelMtrx
->data
[1][ofs
] != 0) && (panel
->wheelMtrx
->data
[2][ofs
] != 0));
2041 static void wheelPaint(W_ColorPanel
* panel
)
2043 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2045 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->wheelView
->window
,
2046 scr
->copyGC
, 0, 0, colorWheelSize
+ 4, colorWheelSize
+ 4, 0, 0);
2048 /* Draw selection image */
2049 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2050 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2053 static void wheelHandleEvents(XEvent
* event
, void *data
)
2055 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2057 switch (event
->type
) {
2059 if (event
->xexpose
.count
!= 0) /* TODO Improve */
2066 static void wheelHandleActionEvents(XEvent
* event
, void *data
)
2068 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2070 switch (event
->type
) {
2072 if (getPickerPart(panel
, event
->xbutton
.x
, event
->xbutton
.y
) == COLORWHEEL_PART
) {
2074 panel
->lastChanged
= WMWheelModeColorPanel
;
2075 panel
->flags
.dragging
= 1;
2077 wheelPositionSelection(panel
, event
->xbutton
.x
, event
->xbutton
.y
);
2082 panel
->flags
.dragging
= 0;
2083 if (!panel
->flags
.continuous
) {
2085 (*panel
->action
) (panel
, panel
->clientData
);
2090 if (panel
->flags
.dragging
) {
2091 if (getPickerPart(panel
, event
->xmotion
.x
, event
->xmotion
.y
) == COLORWHEEL_PART
) {
2092 wheelPositionSelection(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2094 wheelPositionSelectionOutBounds(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2100 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
)
2108 if (panel
->mode
== WMWheelModeColorPanel
) {
2109 if ((lx
>= 2) && (lx
<= 2 + colorWheelSize
) && (ly
>= 2) && (ly
<= 2 + colorWheelSize
)) {
2111 ofs
= ly
* panel
->wheelMtrx
->width
+ lx
;
2113 if (wheelInsideColorWheel(panel
, ofs
))
2114 return COLORWHEEL_PART
;
2118 if (panel
->mode
== WMCustomPaletteModeColorPanel
) {
2119 if ((lx
>= 2) && (lx
< customPaletteWidth
- 2) && (ly
>= 2) && (ly
< customPaletteHeight
- 2)) {
2120 return CUSTOMPALETTE_PART
;
2127 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
)
2131 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2133 value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2135 wheelCalculateValues(panel
, value
);
2137 if (panel
->color
.set
== cpRGB
) {
2138 convertCPColor(&panel
->color
);
2139 panel
->color
.set
= cpHSV
;
2142 panel
->color
.hsv
.value
= value
;
2146 wheelUpdateSelection(panel
);
2149 static void wheelUpdateSelection(W_ColorPanel
* panel
)
2151 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2153 updateSwatch(panel
, panel
->color
);
2154 panel
->lastChanged
= WMWheelModeColorPanel
;
2156 /* Redraw color selector (and make a backup of the part it will cover) */
2157 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2158 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2159 /* "-2" is correction for hotspot location */
2160 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2161 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2165 static void wheelUndrawSelection(W_ColorPanel
* panel
)
2167 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2169 XCopyArea(scr
->display
, panel
->selectionBackImg
, panel
->wheelView
->window
,
2170 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2174 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2176 unsigned long ofs
= (y
* panel
->wheelMtrx
->width
) + x
;
2178 panel
->color
.rgb
.red
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]];
2180 panel
->color
.rgb
.green
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]];
2182 panel
->color
.rgb
.blue
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]];
2183 panel
->color
.set
= cpRGB
;
2185 wheelUndrawSelection(panel
);
2190 wheelUpdateSelection(panel
);
2191 wheelUpdateBrightnessGradientFromLocation(panel
);
2194 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2200 xcor
= x
* 2 - colorWheelSize
- 4;
2201 ycor
= y
* 2 - colorWheelSize
- 4;
2203 panel
->color
.hsv
.saturation
= 255;
2204 panel
->color
.hsv
.value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2207 hue
= rint(atan(-(double)ycor
/ (double)xcor
) * (180.0 / M_PI
));
2218 if ((xcor
> 0) && (ycor
> 0))
2221 panel
->color
.hsv
.hue
= hue
;
2222 panel
->color
.set
= cpHSV
;
2223 convertCPColor(&panel
->color
);
2225 wheelUndrawSelection(panel
);
2227 panel
->colx
= 2 + rint((colorWheelSize
* (1.0 + cos(panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2228 /* "+2" because of "colorWheelSize + 4" */
2229 panel
->coly
= 2 + rint((colorWheelSize
* (1.0 + sin(-panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2231 wheelUpdateSelection(panel
);
2232 cpColor
= panel
->color
;
2233 wheelUpdateBrightnessGradient(panel
, cpColor
);
2236 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
)
2241 ofs
= panel
->coly
* panel
->wheelMtrx
->width
+ panel
->colx
;
2243 from
.rgb
.red
= panel
->wheelMtrx
->data
[0][ofs
];
2244 from
.rgb
.green
= panel
->wheelMtrx
->data
[1][ofs
];
2245 from
.rgb
.blue
= panel
->wheelMtrx
->data
[2][ofs
];
2248 wheelUpdateBrightnessGradient(panel
, from
);
2251 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
)
2255 WMPixmap
*sliderPxmp
;
2257 to
.red
= to
.green
= to
.blue
= 0;
2259 if (topColor
.set
== cpHSV
)
2260 convertCPColor(&topColor
);
2262 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2263 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
), sliderImg
, 0);
2264 RReleaseImage(sliderImg
);
2265 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2266 WMReleasePixmap(sliderPxmp
);
2269 /****************** Grayscale Panel Functions ***************/
2271 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
)
2276 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2278 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2280 sprintf(tmp
, "%d", value
);
2282 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2283 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55 * value
);
2284 cpColor
.set
= cpRGB
;
2286 updateSwatch(panel
, cpColor
);
2287 panel
->lastChanged
= WMGrayModeColorPanel
;
2290 static void grayPresetButtonCallback(WMWidget
* w
, void *data
)
2296 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2299 if (w
== panel
->grayPresetBtn
[i
])
2304 value
= rint((100.0 * i
) / 6.0);
2305 sprintf(tmp
, "%d", value
);
2307 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2308 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * i
) / 6.0);
2309 cpColor
.set
= cpRGB
;
2311 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0 * i
) / 6.0));
2313 updateSwatch(panel
, cpColor
);
2314 panel
->lastChanged
= WMGrayModeColorPanel
;
2317 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
)
2322 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2324 value
= atoi(WMGetTextFieldText(panel
->grayBrightnessT
));
2330 sprintf(tmp
, "%d", value
);
2331 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2332 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2334 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * value
) / 100.0);
2335 cpColor
.set
= cpRGB
;
2337 updateSwatch(panel
, cpColor
);
2338 panel
->lastChanged
= WMGrayModeColorPanel
;
2341 /******************* RGB Panel Functions *****************/
2343 static void rgbSliderCallback(WMWidget
* w
, void *data
)
2348 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2350 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2351 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2352 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2354 sprintf(tmp
, "%d", value
[0]);
2355 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2356 sprintf(tmp
, "%d", value
[1]);
2357 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2358 sprintf(tmp
, "%d", value
[2]);
2359 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2361 cpColor
.rgb
.red
= value
[0];
2362 cpColor
.rgb
.green
= value
[1];
2363 cpColor
.rgb
.blue
= value
[2];
2364 cpColor
.set
= cpRGB
;
2366 updateSwatch(panel
, cpColor
);
2367 panel
->lastChanged
= WMRGBModeColorPanel
;
2370 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2376 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2378 value
[0] = atoi(WMGetTextFieldText(panel
->rgbRedT
));
2379 value
[1] = atoi(WMGetTextFieldText(panel
->rgbGreenT
));
2380 value
[2] = atoi(WMGetTextFieldText(panel
->rgbBlueT
));
2382 for (n
= 0; n
< 3; n
++) {
2389 sprintf(tmp
, "%d", value
[0]);
2390 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2391 sprintf(tmp
, "%d", value
[1]);
2392 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2393 sprintf(tmp
, "%d", value
[2]);
2394 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2396 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2397 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2398 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2400 cpColor
.rgb
.red
= value
[0];
2401 cpColor
.rgb
.green
= value
[1];
2402 cpColor
.rgb
.blue
= value
[2];
2403 cpColor
.set
= cpRGB
;
2405 updateSwatch(panel
, cpColor
);
2406 panel
->lastChanged
= WMRGBModeColorPanel
;
2409 /******************* CMYK Panel Functions *****************/
2411 static void cmykSliderCallback(WMWidget
* w
, void *data
)
2416 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2419 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2420 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2421 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2422 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2424 sprintf(tmp
, "%d", value
[0]);
2425 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2426 sprintf(tmp
, "%d", value
[1]);
2427 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2428 sprintf(tmp
, "%d", value
[2]);
2429 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2430 sprintf(tmp
, "%d", value
[3]);
2431 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2433 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2434 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2435 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2436 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2437 cpColor
.set
= cpRGB
;
2439 updateSwatch(panel
, cpColor
);
2440 panel
->lastChanged
= WMCMYKModeColorPanel
;
2443 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
)
2450 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2452 value
[0] = atoi(WMGetTextFieldText(panel
->cmykCyanT
));
2453 value
[1] = atoi(WMGetTextFieldText(panel
->cmykMagentaT
));
2454 value
[2] = atoi(WMGetTextFieldText(panel
->cmykYellowT
));
2455 value
[3] = atoi(WMGetTextFieldText(panel
->cmykBlackT
));
2457 for (n
= 0; n
< 4; n
++) {
2464 sprintf(tmp
, "%d", value
[0]);
2465 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2467 sprintf(tmp
, "%d", value
[1]);
2468 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2470 sprintf(tmp
, "%d", value
[2]);
2471 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2473 sprintf(tmp
, "%d", value
[3]);
2474 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2476 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2477 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2478 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2479 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2481 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2482 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2483 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2484 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2485 cpColor
.set
= cpRGB
;
2487 updateSwatch(panel
, cpColor
);
2488 panel
->lastChanged
= WMCMYKModeColorPanel
;
2491 /********************** HSB Panel Functions ***********************/
2493 static void hsbSliderCallback(WMWidget
* w
, void *data
)
2498 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2500 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2501 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2502 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2504 sprintf(tmp
, "%d", value
[0]);
2505 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2506 sprintf(tmp
, "%d", value
[1]);
2507 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2508 sprintf(tmp
, "%d", value
[2]);
2509 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2511 cpColor
.hsv
.hue
= value
[0];
2512 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2513 cpColor
.hsv
.value
= value
[2] * 2.55;
2514 cpColor
.set
= cpHSV
;
2516 convertCPColor(&cpColor
);
2518 panel
->lastChanged
= WMHSBModeColorPanel
;
2519 updateSwatch(panel
, cpColor
);
2521 if (w
!= panel
->hsbBrightnessS
)
2522 hsbUpdateBrightnessGradient(panel
);
2523 if (w
!= panel
->hsbSaturationS
)
2524 hsbUpdateSaturationGradient(panel
);
2525 if (w
!= panel
->hsbHueS
)
2526 hsbUpdateHueGradient(panel
);
2529 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2535 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2537 value
[0] = atoi(WMGetTextFieldText(panel
->hsbHueT
));
2538 value
[1] = atoi(WMGetTextFieldText(panel
->hsbSaturationT
));
2539 value
[2] = atoi(WMGetTextFieldText(panel
->hsbBrightnessT
));
2546 for (n
= 1; n
< 3; n
++) {
2553 sprintf(tmp
, "%d", value
[0]);
2554 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2555 sprintf(tmp
, "%d", value
[1]);
2556 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2557 sprintf(tmp
, "%d", value
[2]);
2558 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2560 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2561 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2562 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2564 cpColor
.hsv
.hue
= value
[0];
2565 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2566 cpColor
.hsv
.value
= value
[2] * 2.55;
2567 cpColor
.set
= cpHSV
;
2569 convertCPColor(&cpColor
);
2571 panel
->lastChanged
= WMHSBModeColorPanel
;
2572 updateSwatch(panel
, cpColor
);
2574 hsbUpdateBrightnessGradient(panel
);
2575 hsbUpdateSaturationGradient(panel
);
2576 hsbUpdateHueGradient(panel
);
2579 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
)
2581 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2585 WMPixmap
*sliderPxmp
;
2587 from
.red
= from
.green
= from
.blue
= 0;
2588 to
.hsv
= panel
->color
.hsv
;
2592 convertCPColor(&to
);
2594 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2595 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2596 RReleaseImage(sliderImg
);
2599 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2600 panel
->font12
, 2, 0, 100, WALeft
, scr
->white
,
2601 False
, _("Brightness"), strlen(_("Brightness")));
2603 wwarning(_("Color Panel: Could not allocate memory"));
2605 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2606 WMReleasePixmap(sliderPxmp
);
2609 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
)
2611 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2615 WMPixmap
*sliderPxmp
;
2617 from
.hsv
= panel
->color
.hsv
;
2618 from
.hsv
.saturation
= 0;
2620 convertCPColor(&from
);
2622 to
.hsv
= panel
->color
.hsv
;
2623 to
.hsv
.saturation
= 255;
2625 convertCPColor(&to
);
2627 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
), RGRD_HORIZONTAL
);
2628 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2629 RReleaseImage(sliderImg
);
2632 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2633 panel
->font12
, 2, 0, 100, WALeft
,
2634 from
.hsv
.value
< 128 ? scr
->white
: scr
->black
, False
,
2635 _("Saturation"), strlen(_("Saturation")));
2637 wwarning(_("Color Panel: Could not allocate memory"));
2639 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2640 WMReleasePixmap(sliderPxmp
);
2643 static void hsbUpdateHueGradient(W_ColorPanel
* panel
)
2645 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2646 RColor
**colors
= NULL
;
2649 WMPixmap
*sliderPxmp
;
2652 hsvcolor
= panel
->color
.hsv
;
2654 colors
= wmalloc(sizeof(RColor
*) * (8));
2655 for (i
= 0; i
< 7; i
++) {
2656 hsvcolor
.hue
= (360 * i
) / 6;
2657 colors
[i
] = wmalloc(sizeof(RColor
));
2658 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2662 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2663 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2664 RReleaseImage(sliderImg
);
2667 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2668 panel
->font12
, 2, 0, 100, WALeft
,
2669 hsvcolor
.value
< 128 ? scr
->white
: scr
->black
, False
, _("Hue"), strlen(_("Hue")));
2671 wwarning(_("Color Panel: Could not allocate memory"));
2673 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2674 WMReleasePixmap(sliderPxmp
);
2676 for (i
= 0; i
< 7; i
++)
2682 /*************** Custom Palette Functions ****************/
2684 static void customRenderSpectrum(W_ColorPanel
* panel
)
2691 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, False
);
2693 ptr
= spectrum
->data
;
2695 for (y
= 0; y
< SPECTRUM_HEIGHT
; y
++) {
2696 cpColor
.hsv
.hue
= y
;
2697 cpColor
.hsv
.saturation
= 0;
2698 cpColor
.hsv
.value
= 255;
2699 cpColor
.set
= cpHSV
;
2701 for (x
= 0; x
< SPECTRUM_WIDTH
; x
++) {
2702 convertCPColor(&cpColor
);
2704 *(ptr
++) = (unsigned char)cpColor
.rgb
.red
;
2705 *(ptr
++) = (unsigned char)cpColor
.rgb
.green
;
2706 *(ptr
++) = (unsigned char)cpColor
.rgb
.blue
;
2708 if (x
< (SPECTRUM_WIDTH
/ 2))
2709 cpColor
.hsv
.saturation
++;
2711 if (x
> (SPECTRUM_WIDTH
/ 2))
2712 cpColor
.hsv
.value
--;
2715 if (panel
->customPaletteImg
) {
2716 RReleaseImage(panel
->customPaletteImg
);
2717 panel
->customPaletteImg
= NULL
;
2719 panel
->customPaletteImg
= spectrum
;
2722 static void customSetPalette(W_ColorPanel
* panel
)
2724 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2728 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
, customPaletteHeight
, scr
->depth
);
2729 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
, customPaletteHeight
);
2730 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2731 RReleaseImage(scaledImg
);
2733 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2734 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2736 /* Check backimage exists. If it doesn't, allocate and fill it */
2737 if (!panel
->selectionBackImg
) {
2738 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2739 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2742 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2743 panel
->palx
- 2, panel
->paly
- 2, 4, 4, 0, 0);
2744 XCopyArea(scr
->display
, panel
->selectionImg
,
2745 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2746 panel
->palx
- 2, panel
->paly
- 2);
2747 XFreePixmap(scr
->display
, image
);
2749 panel
->palXRatio
= (double)(panel
->customPaletteImg
->width
) / (double)(customPaletteWidth
);
2750 panel
->palYRatio
= (double)(panel
->customPaletteImg
->height
) / (double)(customPaletteHeight
);
2752 WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2755 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2757 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2760 /* undraw selection */
2761 XCopyArea(scr
->display
, panel
->selectionBackImg
,
2762 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2763 panel
->palx
- 2, panel
->paly
- 2);
2768 ofs
= (rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) * panel
->customPaletteImg
->width
) * 3;
2770 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[ofs
];
2771 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[ofs
+ 1];
2772 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[ofs
+ 2];
2773 panel
->color
.set
= cpRGB
;
2775 updateSwatch(panel
, panel
->color
);
2776 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
2778 /* Redraw color selector (and make a backup of the part it will cover) */
2779 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 */
2780 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4, panel
->palx
- 2, panel
->paly
- 2); /* see above */
2783 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2789 if (x
>= customPaletteWidth
)
2790 x
= customPaletteWidth
- 2;
2791 if (y
>= customPaletteHeight
)
2792 y
= customPaletteHeight
- 2;
2794 customPalettePositionSelection(panel
, x
, y
);
2797 static void customPaletteHandleEvents(XEvent
* event
, void *data
)
2799 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2801 switch (event
->type
) {
2803 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
2805 customSetPalette(panel
);
2810 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
)
2812 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2815 switch (event
->type
) {
2817 x
= event
->xbutton
.x
;
2818 y
= event
->xbutton
.y
;
2820 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2821 panel
->flags
.dragging
= 1;
2822 customPalettePositionSelection(panel
, x
, y
);
2827 panel
->flags
.dragging
= 0;
2828 if (!panel
->flags
.continuous
) {
2830 (*panel
->action
) (panel
, panel
->clientData
);
2835 x
= event
->xmotion
.x
;
2836 y
= event
->xmotion
.y
;
2838 if (panel
->flags
.dragging
) {
2839 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2840 customPalettePositionSelection(panel
, x
, y
);
2842 customPalettePositionSelectionOutBounds(panel
, x
, y
);
2848 static void customPaletteMenuCallback(WMWidget
* w
, void *data
)
2850 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2851 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
2854 case CPmenuNewFromFile
:
2855 customPaletteMenuNewFromFile(panel
);
2858 customPaletteMenuRename(panel
);
2861 customPaletteMenuRemove(panel
);
2865 case CPmenuNewFromClipboard
:
2870 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
)
2872 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2873 WMOpenPanel
*browseP
;
2875 char *filename
= NULL
;
2879 RImage
*tmpImg
= NULL
;
2881 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
, "\0") == 0))
2882 spath
= wexpandpath(wgethomedir());
2884 spath
= wexpandpath(panel
->lastBrowseDir
);
2886 browseP
= WMGetOpenPanel(scr
);
2887 WMSetFilePanelCanChooseDirectories(browseP
, 0);
2888 WMSetFilePanelCanChooseFiles(browseP
, 1);
2890 /* Get a filename */
2891 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
2892 _("Open Palette"), RSupportedFileFormats())) {
2893 filepath
= WMGetFilePanelFileName(browseP
);
2895 /* Get seperation position between path and filename */
2896 i
= strrchr(filepath
, '/') - filepath
+ 1;
2897 if (i
> strlen(filepath
))
2898 i
= strlen(filepath
);
2900 /* Store last browsed path */
2901 if (panel
->lastBrowseDir
)
2902 wfree(panel
->lastBrowseDir
);
2903 panel
->lastBrowseDir
= wmalloc((i
+ 1) * sizeof(char));
2904 strncpy(panel
->lastBrowseDir
, filepath
, i
);
2905 panel
->lastBrowseDir
[i
] = '\0';
2907 /* Get filename from path */
2908 filename
= wstrdup(filepath
+ i
);
2910 /* Check for duplicate files, and rename it if there are any */
2911 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2912 while (access(tmp
, F_OK
) == 0) {
2917 newName
= generateNewFilename(filename
);
2921 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2925 /* Copy image to $(gnustepdir)/Library/Colors/ &
2926 * Add filename to history menu */
2927 if (wcopy_file(panel
->configurationPath
, filepath
, filename
) == 0) {
2929 /* filepath is a "local" path now the file has been copied */
2931 filepath
= wstrconcat(panel
->configurationPath
, filename
);
2933 /* load the image & add menu entries */
2934 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
2936 if (panel
->customPaletteImg
)
2937 RReleaseImage(panel
->customPaletteImg
);
2938 panel
->customPaletteImg
= tmpImg
;
2940 customSetPalette(panel
);
2941 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
2943 panel
->currentPalette
=
2944 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1;
2946 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
2947 panel
->currentPalette
);
2950 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2952 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
2953 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2954 _("Invalid file format !"), _("OK"), NULL
, NULL
);
2956 werror(_("can't remove file %s"), tmp
);
2957 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2958 _("Couldn't remove file from Configuration Directory !"),
2959 _("OK"), NULL
, NULL
);
2966 WMFreeFilePanel(browseP
);
2971 static void customPaletteMenuRename(W_ColorPanel
* panel
)
2973 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2974 char *toName
= NULL
;
2976 char *toPath
, *fromPath
;
2980 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2981 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
2983 toName
= WMRunInputPanel(scr
, panel
->win
, _("Rename"), _("Rename palette to:"),
2984 fromName
, _("OK"), _("Cancel"));
2988 /* As some people do certain stupid things... */
2989 if (strcmp(toName
, fromName
) == 0) {
2994 /* For normal people */
2995 fromPath
= wstrconcat(panel
->configurationPath
, fromName
);
2996 toPath
= wstrconcat(panel
->configurationPath
, toName
);
2998 if (access(toPath
, F_OK
) == 0) {
2999 /* Careful, this palette exists already */
3000 if (WMRunAlertPanel(scr
, panel
->win
, _("Warning"),
3001 _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"),
3003 /* "No" = 0, "Yes" = 1 */
3004 int items
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
3008 /* Remove from History list too */
3010 while ((index
< items
)
3012 (strcmp(WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, index
), toName
)
3016 if (index
< items
) {
3017 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, index
);
3031 if (rename(fromPath
, toPath
) != 0)
3032 werror(_("Couldn't rename palette %s to %s"), fromName
, toName
);
3034 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3035 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
, toName
);
3037 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3045 static void customPaletteMenuRemove(W_ColorPanel
* panel
)
3047 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3053 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3055 tmp
= wstrconcat(_("This will permanently remove the palette "),
3056 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3057 text
= wstrconcat(tmp
, _(".\n\nAre you sure you want to remove this palette ?"));
3060 choice
= WMRunAlertPanel(scr
, panel
->win
, _("Remove"), text
, _("Yes"), _("No"), NULL
);
3061 /* returns 0 (= "Yes") or 1 (="No") */
3066 tmp
= wstrconcat(panel
->configurationPath
,
3067 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3069 if (remove(tmp
) == 0) {
3070 /* item-1 always exists */
3071 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3073 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
, panel
);
3074 customSetPalette(panel
);
3076 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3079 werror(_("Couldn't remove palette %s"), tmp
);
3086 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
)
3088 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3089 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3093 unsigned char perm_mask
;
3095 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3096 if (item
== panel
->currentPalette
)
3100 customRenderSpectrum(panel
);
3102 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, False
);
3103 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, False
);
3105 /* Load file from configpath */
3106 filename
= wstrconcat(panel
->configurationPath
,
3107 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3109 /* If the file corresponding to the item does not exist,
3110 * remove it from the history list and select the next one.
3112 perm_mask
= (access(filename
, F_OK
) == 0);
3114 /* File does not exist */
3116 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3117 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3118 customPaletteHistoryCallback(w
, data
);
3123 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3125 if (panel
->customPaletteImg
) {
3126 RReleaseImage(panel
->customPaletteImg
);
3127 panel
->customPaletteImg
= NULL
;
3129 panel
->customPaletteImg
= tmp
;
3132 /* If the image is not writable, don't allow removing/renaming */
3133 perm_mask
= (access(filename
, W_OK
) == 0);
3134 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, perm_mask
);
3135 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, perm_mask
);
3139 customSetPalette(panel
);
3141 panel
->currentPalette
= item
;
3144 /************************* ColorList Panel Functions **********************/
3146 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
)
3148 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3149 Display
*dpy
= WMScreenDisplay(scr
);
3150 WMView
*view
= W_VIEW(lPtr
);
3151 RColor
*color
= (RColor
*) WMGetListItem(lPtr
, index
)->clientData
;
3152 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3153 int width
, height
, x
, y
;
3156 width
= rect
->size
.width
;
3157 height
= rect
->size
.height
;
3161 if (state
& WLDSSelected
)
3162 XFillRectangle(dpy
, d
, WMColorGC(scr
->white
), x
, y
, width
, height
);
3164 XFillRectangle(dpy
, d
, WMColorGC(view
->backColor
), x
, y
, width
, height
);
3166 fillColor
= WMCreateRGBColor(scr
, color
->red
<< 8, color
->green
<< 8, color
->blue
<< 8, True
);
3168 XFillRectangle(dpy
, d
, WMColorGC(fillColor
), x
, y
, 15, height
);
3169 WMReleaseColor(fillColor
);
3171 WMDrawString(scr
, d
, scr
->black
, panel
->font12
, x
+ 18, y
, text
, strlen(text
));
3174 static void colorListSelect(WMWidget
* w
, void *data
)
3176 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3179 cpColor
.rgb
= *((RColor
*) WMGetListSelectedItem(w
)->clientData
);
3180 cpColor
.set
= cpRGB
;
3182 panel
->lastChanged
= WMColorListModeColorPanel
;
3183 updateSwatch(panel
, cpColor
);
3186 static void colorListColorMenuCallback(WMWidget
* w
, void *data
)
3188 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3189 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3201 static void colorListListMenuCallback(WMWidget
* w
, void *data
)
3203 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3204 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3208 /* New Color List */
3209 colorListListMenuNew(panel
);
3218 static void colorListListMenuNew(W_ColorPanel
* panel
)
3223 /*************** Panel Initialisation Functions *****************/
3225 static void wheelInit(W_ColorPanel
* panel
)
3229 if (panel
->color
.set
!= cpHSV
)
3230 convertCPColor(&panel
->color
);
3232 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3234 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3235 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3236 cos(panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3237 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3238 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3239 sin(-panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3241 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3243 cpColor
= panel
->color
;
3244 cpColor
.hsv
.value
= 255;
3245 cpColor
.set
= cpHSV
;
3246 wheelUpdateBrightnessGradient(panel
, cpColor
);
3249 static void grayInit(W_ColorPanel
* panel
)
3254 if (panel
->color
.set
!= cpHSV
)
3255 convertCPColor(&panel
->color
);
3257 value
= rint(panel
->color
.hsv
.value
/ 2.55);
3258 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3260 sprintf(tmp
, "%d", value
);
3261 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3264 static void rgbInit(W_ColorPanel
* panel
)
3268 if (panel
->color
.set
!= cpRGB
)
3269 convertCPColor(&panel
->color
);
3271 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3272 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3273 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3275 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3276 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3277 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3278 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3279 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3280 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3283 static void cmykInit(W_ColorPanel
* panel
)
3288 if (panel
->color
.set
!= cpRGB
)
3289 convertCPColor(&panel
->color
);
3291 value
[0] = rint((255 - panel
->color
.rgb
.red
) / 2.55);
3292 value
[1] = rint((255 - panel
->color
.rgb
.green
) / 2.55);
3293 value
[2] = rint((255 - panel
->color
.rgb
.blue
) / 2.55);
3295 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3296 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3297 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3298 WMSetSliderValue(panel
->cmykBlackS
, 0);
3300 sprintf(tmp
, "%d", value
[0]);
3301 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3302 sprintf(tmp
, "%d", value
[1]);
3303 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3304 sprintf(tmp
, "%d", value
[2]);
3305 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3306 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3309 static void hsbInit(W_ColorPanel
* panel
)
3314 if (panel
->color
.set
!= cpHSV
)
3315 convertCPColor(&panel
->color
);
3317 value
[0] = panel
->color
.hsv
.hue
;
3318 value
[1] = rint(panel
->color
.hsv
.saturation
/ 2.55);
3319 value
[2] = rint(panel
->color
.hsv
.value
/ 2.55);
3321 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
3322 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
3323 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
3325 sprintf(tmp
, "%d", value
[0]);
3326 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3327 sprintf(tmp
, "%d", value
[1]);
3328 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3329 sprintf(tmp
, "%d", value
[2]);
3330 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3332 hsbUpdateBrightnessGradient(panel
);
3333 hsbUpdateSaturationGradient(panel
);
3334 hsbUpdateHueGradient(panel
);
3337 /************************** Common utility functions ************************/
3339 static char *generateNewFilename(const char *curName
)
3351 if (((ptr
= strrchr(ptr
, '{')) == 0) || sscanf(ptr
, "{%i}%c", &n
, &c
) != 1)
3352 return wstrconcat(curName
, " {1}");
3354 baseLen
= ptr
- curName
- 1;
3356 newName
= wmalloc(baseLen
+ 16);
3357 strncpy(newName
, curName
, baseLen
);
3359 snprintf(&newName
[baseLen
], 16, " {%i}", n
+ 1);
3364 static void convertCPColor(CPColor
* color
)
3366 unsigned short old_hue
= 0;
3368 switch (color
->set
) {
3370 wwarning(_("Color Panel: Color unspecified"));
3373 old_hue
= color
->hsv
.hue
;
3374 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3376 /* In black the hue is undefined, and may change by conversion
3377 * Same for white. */
3378 if (((color
->rgb
.red
== 0) &&
3379 (color
->rgb
.green
== 0) &&
3380 (color
->rgb
.blue
== 0)) ||
3381 ((color
->rgb
.red
== 0) && (color
->rgb
.green
== 0) && (color
->rgb
.blue
== 255))
3383 color
->hsv
.hue
= old_hue
;
3386 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3391 #define ABS_SHIFT(val, shift) \
3392 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3394 static RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
)
3397 XColor
*xcolor
= NULL
;
3399 xcolor
= wmalloc(sizeof(XColor
));
3400 xcolor
->pixel
= value
;
3401 XQueryColor(scr
->display
, scr
->rcontext
->cmap
, xcolor
);
3403 color
.red
= xcolor
->red
>> 8;
3404 color
.green
= xcolor
->green
>> 8;
3405 color
.blue
= xcolor
->blue
>> 8;
3413 static unsigned char getShift(unsigned char value
)
3415 unsigned char i
= -1;
3428 #ifdef SHAPE_WAS_DEFINED
3429 #undef SHAPE_WAS_DEFINED