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 /* Parameter not used, but tell the compiler that it is ok */
1135 WMCloseColorPanel(panel
);
1138 static void readConfiguration(W_ColorPanel
* panel
)
1140 /* XXX Doesn't take care of "invalid" files */
1144 struct stat stat_buf
;
1147 if (stat(panel
->configurationPath
, &stat_buf
) != 0) {
1148 if (mkdir(panel
->configurationPath
, S_IRWXU
| S_IRGRP
| S_IROTH
| S_IXGRP
| S_IXOTH
) != 0) {
1149 werror(_("Color Panel: Could not create directory %s needed"
1150 " to store configurations"), panel
->configurationPath
);
1151 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1152 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1153 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1154 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1156 _("Could not create ColorPanel configuration directory"),
1157 _("OK"), NULL
, NULL
);
1162 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1163 wwarning("%s: %s", _("Color Panel: Could not find file"), panel
->configurationPath
);
1167 while ((dp
= readdir(dPtr
)) != NULL
) {
1168 unsigned int perm_mask
;
1169 char *path
= wstrconcat(panel
->configurationPath
,
1172 if (dp
->d_name
[0] != '.') {
1173 item
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
1174 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1176 perm_mask
= (access(path
, R_OK
) == 0);
1177 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
, item
, perm_mask
);
1184 static void readXColors(W_ColorPanel
* panel
)
1189 for (entry
= rgbColors
; entry
->name
!= NULL
; entry
++) {
1190 item
= WMAddListItem(panel
->colorListContentLst
, entry
->name
);
1191 item
->clientData
= (void *)&(entry
->color
);
1195 void WMSetColorPanelPickerMode(WMColorPanel
* panel
, WMColorPanelMode mode
)
1197 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1199 if (mode
!= WMWheelModeColorPanel
) {
1200 WMUnmapWidget(panel
->wheelFrm
);
1201 if (panel
->selectionBackImg
) {
1202 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1203 panel
->selectionBackImg
= None
;
1206 if (mode
!= WMGrayModeColorPanel
)
1207 WMUnmapWidget(panel
->grayFrm
);
1208 if (mode
!= WMRGBModeColorPanel
)
1209 WMUnmapWidget(panel
->rgbFrm
);
1210 if (mode
!= WMCMYKModeColorPanel
)
1211 WMUnmapWidget(panel
->cmykFrm
);
1212 if (mode
!= WMHSBModeColorPanel
)
1213 WMUnmapWidget(panel
->hsbFrm
);
1214 if (mode
!= WMCustomPaletteModeColorPanel
) {
1215 WMUnmapWidget(panel
->customPaletteFrm
);
1216 if (panel
->selectionBackImg
) {
1217 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1218 panel
->selectionBackImg
= None
;
1221 if (mode
!= WMColorListModeColorPanel
)
1222 WMUnmapWidget(panel
->colorListFrm
);
1223 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1224 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1225 WMUnmapWidget(panel
->slidersFrm
);
1227 panel
->slidersmode
= mode
;
1229 if (mode
== WMWheelModeColorPanel
) {
1230 WMMapWidget(panel
->wheelFrm
);
1231 WMSetButtonSelected(panel
->wheelBtn
, True
);
1232 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1236 } else if (mode
== WMGrayModeColorPanel
) {
1237 WMMapWidget(panel
->slidersFrm
);
1238 WMSetButtonSelected(panel
->slidersBtn
, True
);
1239 WMMapWidget(panel
->grayFrm
);
1240 WMSetButtonSelected(panel
->grayBtn
, True
);
1241 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1242 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1244 } else if (mode
== WMRGBModeColorPanel
) {
1245 WMMapWidget(panel
->slidersFrm
);
1246 WMSetButtonSelected(panel
->slidersBtn
, True
);
1247 WMMapWidget(panel
->rgbFrm
);
1248 WMSetButtonSelected(panel
->rgbBtn
, True
);
1249 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1250 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1252 } else if (mode
== WMCMYKModeColorPanel
) {
1253 WMMapWidget(panel
->slidersFrm
);
1254 WMSetButtonSelected(panel
->slidersBtn
, True
);
1255 WMMapWidget(panel
->cmykFrm
);
1256 WMSetButtonSelected(panel
->cmykBtn
, True
);
1257 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1258 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1260 } else if (mode
== WMHSBModeColorPanel
) {
1261 WMMapWidget(panel
->slidersFrm
);
1262 WMSetButtonSelected(panel
->slidersBtn
, True
);
1263 WMMapWidget(panel
->hsbFrm
);
1264 WMSetButtonSelected(panel
->hsbBtn
, True
);
1265 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1266 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1268 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1269 WMMapWidget(panel
->customPaletteFrm
);
1270 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1271 customSetPalette(panel
);
1272 } else if (mode
== WMColorListModeColorPanel
) {
1273 WMMapWidget(panel
->colorListFrm
);
1274 WMSetButtonSelected(panel
->colorListBtn
, True
);
1280 WMColor
*WMGetColorPanelColor(WMColorPanel
* panel
)
1282 return WMGetColorWellColor(panel
->colorWell
);
1285 void WMSetColorPanelColor(WMColorPanel
* panel
, WMColor
* color
)
1287 WMSetColorWellColor(panel
->colorWell
, color
);
1289 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1290 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1291 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1292 panel
->color
.set
= cpRGB
;
1294 if (panel
->mode
== panel
->lastChanged
)
1295 panel
->lastChanged
= 0;
1297 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1300 static void updateSwatch(WMColorPanel
* panel
, CPColor color
)
1302 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1305 if (color
.set
!= cpRGB
)
1306 convertCPColor(&color
);
1308 panel
->color
= color
;
1310 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8, color
.rgb
.green
<< 8, color
.rgb
.blue
<< 8, True
);
1312 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1313 WMReleaseColor(wellcolor
);
1315 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1317 (*panel
->action
) (panel
, panel
->clientData
);
1319 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
, NULL
);
1323 static void modeButtonCallback(WMWidget
* w
, void *data
)
1325 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1327 if (w
== panel
->wheelBtn
)
1328 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1329 else if (w
== panel
->slidersBtn
)
1330 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1331 else if (w
== panel
->customPaletteBtn
)
1332 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1333 else if (w
== panel
->colorListBtn
)
1334 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1335 else if (w
== panel
->grayBtn
)
1336 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1337 else if (w
== panel
->rgbBtn
)
1338 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1339 else if (w
== panel
->cmykBtn
)
1340 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1341 else if (w
== panel
->hsbBtn
)
1342 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1345 /****************** Magnifying Cursor Functions *******************/
1347 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
)
1349 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1350 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1351 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1353 if (!(image
&& image
->data
)) {
1354 /* The image in panel->magnifyGlass->image does not exist yet.
1355 * Grab one from the screen (not beyond) and use it from now on.
1357 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1358 x
- Cursor_x_hot
, y
- Cursor_y_hot
, w
, h
, AllPlanes
, ZPixmap
)))
1359 wwarning(_("Color Panel: X failed request"));
1364 /* Coordinate correction for back pixmap
1365 * if magnifying glass is at screen-borders
1368 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1369 * Hatched area is beyond screen border.
1371 * |<-Cursor_x_hot->|
1372 * ________________|_____
1373 * |/ / / / / / /| | |
1374 * | / / / / / / |(x,y) |
1375 * |/_/_/_/_/_/_/|________|
1376 * |<----x0----->|<--w0-->|
1380 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1382 * Hatched area is beyond screen border
1384 * |<-Cursor_x_hot->|
1385 * ________________|_______________
1386 * | | | / / / / / /|
1387 * | (x,y)|/ / / / / / |
1388 * |___________________|_/_/_/_/_/_/|
1389 * |<-------w0-------->| |
1390 * |<---------------w--|----------->|
1395 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1396 x0
= Cursor_x_hot
- x
;
1400 if (displayWidth
- 1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1401 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1404 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1405 y0
= Cursor_y_hot
- y
;
1409 if (displayHeight
- 1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1410 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1412 /* end of coordinate correction */
1414 /* Grab an image from the screen, clipped if necessary,
1415 * and put it in the existing panel->magnifyGlass->image
1416 * with the corresponding clipping offset.
1418 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1419 x
- Cursor_x_hot
+ x0
, y
- Cursor_y_hot
+ y0
, w0
, h0
, AllPlanes
, ZPixmap
, image
, x0
, y0
))
1420 wwarning(_("Color Panel: X failed request"));
1425 static void magnifyGetImageStored(WMColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
)
1427 /* (x1, y1) = topleft corner of existing rectangle
1428 * (x2, y2) = topleft corner of new position
1431 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1432 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1434 const int dx
= abs(x2
- x1
), dy
= abs(y2
- y1
);
1436 const int x_min
= Cursor_x_hot
,
1437 y_min
= Cursor_y_hot
,
1438 x_max
= DisplayWidth(scr
->display
, scr
->screen
) - 1 -
1439 (Cursor_mask_width
- Cursor_x_hot
),
1440 y_max
= DisplayHeight(scr
->display
, scr
->screen
) - 1 - (Cursor_mask_height
- Cursor_y_hot
);
1442 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1443 return; /* No movement */
1455 width
= Cursor_mask_width
- dx
;
1456 height
= Cursor_mask_height
- dy
;
1458 /* If the traversed distance is larger than the size of the magnifying
1459 * glass contents, there is no need to do dirty rectangles. A whole new
1460 * rectangle can be grabbed (unless that rectangle falls partially
1462 * Destroying the image and setting it to NULL will achieve that later on.
1464 * Of course, grabbing an XImage beyond the borders of the screen will
1465 * cause trouble, this is considdered a special case. Part of the screen
1466 * is grabbed, but there is no need for dirty rectangles.
1468 if ((width
<= 0) || (height
<= 0)) {
1469 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1470 if (panel
->magnifyGlass
->image
)
1471 XDestroyImage(panel
->magnifyGlass
->image
);
1472 panel
->magnifyGlass
->image
= NULL
;
1475 if (panel
->magnifyGlass
->image
) {
1476 /* Get dirty rectangle from panel->magnifyGlass->image */
1477 panel
->magnifyGlass
->dirtyRect
=
1478 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1479 if (!panel
->magnifyGlass
->dirtyRect
) {
1480 wwarning(_("Color Panel: X failed request"));
1481 return; /* X returned a NULL from XSubImage */
1486 /* Get image from screen */
1487 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
, Cursor_mask_width
, Cursor_mask_height
);
1488 if (image
) { /* Only reassign if a *new* image was grabbed */
1489 panel
->magnifyGlass
->image
= image
;
1493 /* Copy previously stored rectangle on covered part of image */
1494 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1497 /* "width" and "height" are used as coordinates here,
1498 * and run from [0...width-1] and [0...height-1] respectively.
1502 old_height
= height
;
1504 for (; width
>= 0; width
--)
1505 for (height
= old_height
; height
>= 0; height
--)
1506 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1507 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1508 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1509 panel
->magnifyGlass
->dirtyRect
= NULL
;
1515 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
)
1517 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1522 unsigned long color
;
1524 if (!panel
->magnifyGlass
->image
)
1527 if (!panel
->magnifyGlass
->magPix
)
1531 * Copy an area of only 5x5 pixels from the center of the image.
1533 for (u
= 0; u
< 5; u
++) {
1534 for (v
= 0; v
< 5; v
++) {
1535 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1537 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1539 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1540 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1542 /* The center square must eventually be centered around the
1543 * hotspot. The image needs shifting to achieve this. The amount of
1544 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1547 * ^------- center of center square == Cursor_x_hot
1549 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1551 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1552 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1557 return panel
->magnifyGlass
->magPix
;
1559 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
, Cursor_mask_height
, scr
->depth
);
1563 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1564 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1566 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1567 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1568 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1569 /* (2,2) puts center pixel on center of glass */
1576 static WMView
*magnifyCreateView(W_ColorPanel
* panel
)
1578 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1581 magView
= W_CreateTopView(scr
);
1585 magView
->self
= panel
->win
;
1586 magView
->flags
.topLevel
= 1;
1587 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1588 magView
->attribs
.override_redirect
= True
;
1589 magView
->attribs
.save_under
= True
;
1591 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1593 W_RealizeView(magView
);
1598 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
)
1600 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1601 Pixmap magPixmap
, magPixmap2
;
1603 XColor fgColor
= { 0, 0, 0, 0, DoRed
| DoGreen
| DoBlue
, 0 };
1604 XColor bgColor
= { 0, 0xbf00, 0xa000, 0x5000, DoRed
| DoGreen
| DoBlue
, 0 };
1606 /* Cursor creation stuff */
1607 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1608 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1609 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1610 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1612 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1613 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1615 XFreePixmap(scr
->display
, magPixmap
);
1616 XFreePixmap(scr
->display
, magPixmap2
);
1618 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1620 /* Set up Pointer */
1621 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1622 PointerMotionMask
| ButtonPressMask
,
1623 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1628 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
)
1630 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1633 Pixmap pixmap
, clip_mask
;
1635 Window root_return
, child_return
;
1637 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1638 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1640 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1641 5 * 5 - 1, 5 * 5 - 1, scr
->depth
);
1643 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
, &x
, &y
, &u
, &v
, &mask
);
1645 panel
->magnifyGlass
->image
= NULL
;
1647 /* Clipmask to make magnified view-contents circular */
1649 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1650 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1652 /* Clip circle in glass cursor */
1653 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1654 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1657 XFreePixmap(scr
->display
, clip_mask
);
1659 /* Draw initial magnifying glass contents */
1660 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1662 pixmap
= magnifyCreatePixmap(panel
);
1663 XSetWindowBackgroundPixmap(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1664 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1665 XFlush(scr
->display
);
1668 XFreePixmap(scr
->display
, pixmap
);
1677 static void magnifyPutCursor(WMWidget
* w
, void *data
)
1679 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1680 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1684 WMPoint initialPosition
;
1686 /* Parameter not used, but tell the compiler that it is ok */
1689 /* Destroy wheelBackImg, so it'll update properly */
1690 if (panel
->selectionBackImg
) {
1691 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1692 panel
->selectionBackImg
= None
;
1695 /* Create magnifying glass */
1696 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1697 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1698 if (!panel
->magnifyGlass
->view
)
1701 initialPosition
= magnifyInitialize(panel
);
1702 panel
->magnifyGlass
->x
= initialPosition
.x
;
1703 panel
->magnifyGlass
->y
= initialPosition
.y
;
1705 W_MoveView(panel
->magnifyGlass
->view
,
1706 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1707 W_MapView(panel
->magnifyGlass
->view
);
1709 magCursor
= magnifyGrabPointer(panel
);
1711 while (panel
->magnifyGlass
->image
) {
1712 WMNextEvent(scr
->display
, &event
);
1714 /* Pack motion events */
1715 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1718 switch (event
.type
) {
1720 XDestroyImage(panel
->magnifyGlass
->image
);
1721 panel
->magnifyGlass
->image
= NULL
;
1723 if (event
.xbutton
.button
== Button1
) {
1724 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1725 panel
->color
.set
= cpRGB
;
1726 updateSwatch(panel
, panel
->color
);
1728 switch (panel
->mode
) {
1729 case WMWheelModeColorPanel
:
1734 case WMGrayModeColorPanel
:
1737 case WMRGBModeColorPanel
:
1740 case WMCMYKModeColorPanel
:
1743 case WMHSBModeColorPanel
:
1749 panel
->lastChanged
= panel
->mode
;
1751 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1755 while (XPending(event
.xmotion
.display
)) {
1757 XPeekEvent(event
.xmotion
.display
, &ev
);
1758 if (ev
.type
== MotionNotify
)
1759 XNextEvent(event
.xmotion
.display
, &event
);
1764 /* Get a "dirty rectangle" */
1765 magnifyGetImageStored(panel
,
1766 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1767 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1769 /* Update coordinates */
1770 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1771 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1774 W_MoveView(panel
->magnifyGlass
->view
,
1775 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1777 /* Put new image (with magn.) in view */
1778 pixmap
= magnifyCreatePixmap(panel
);
1779 if (pixmap
!= None
) {
1780 /* Change the window background */
1781 XSetWindowBackgroundPixmap(scr
->display
,
1782 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1783 /* Force an Expose (handled by X) */
1784 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1785 /* Synchronize the event queue, so the Expose is handled NOW */
1786 XFlush(scr
->display
);
1788 XFreePixmap(scr
->display
, pixmap
);
1793 /* Try XQueryPointer for this !!! It returns windows that the pointer
1794 * is over. Note: We found this solving the invisible donkey cap bug
1796 #if 0 /* As it is impossible to make this work in all cases,
1797 * we consider it confusing. Therefore we disabled it.
1799 case FocusOut
: /* fall through */
1802 * Color Panel window (panel->win) lost or received focus.
1803 * We need to update the pixmap in the magnifying glass.
1805 * BUG Doesn't work with focus switches between two windows
1806 * if none of them is the color panel.
1808 XUngrabPointer(scr
->display
, CurrentTime
);
1809 W_UnmapView(panel
->magnifyGlass
->view
);
1811 magnifyInitialize(panel
);
1813 W_MapView(panel
->magnifyGlass
->view
);
1814 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
,
1815 True
, PointerMotionMask
| ButtonPressMask
,
1816 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1820 WMHandleEvent(&event
);
1825 XUngrabPointer(scr
->display
, CurrentTime
);
1826 XFreeCursor(scr
->display
, magCursor
);
1828 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1829 panel
->magnifyGlass
->magPix
= None
;
1831 W_UnmapView(panel
->magnifyGlass
->view
);
1832 W_DestroyView(panel
->magnifyGlass
->view
);
1833 panel
->magnifyGlass
->view
= NULL
;
1835 wfree(panel
->magnifyGlass
);
1838 /****************** ColorWheel Functions ************************/
1840 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
)
1842 wheelMatrix
*matrix
= NULL
;
1845 assert((width
> 0) && (height
> 0));
1847 matrix
= wmalloc(sizeof(wheelMatrix
));
1848 matrix
->width
= width
;
1849 matrix
->height
= height
;
1851 for (i
= 0; i
< 3; i
++) {
1852 matrix
->data
[i
] = wmalloc(width
* height
* sizeof(unsigned char));
1858 static void wheelDestroyMatrix(wheelMatrix
* matrix
)
1865 for (i
= 0; i
< 3; i
++) {
1866 if (matrix
->data
[i
])
1867 wfree(matrix
->data
[i
]);
1872 static void wheelInitMatrix(W_ColorPanel
* panel
)
1876 unsigned char *rp
, *gp
, *bp
;
1882 const int cw_halfsize
= (colorWheelSize
+ 4) / 2,
1883 cw_sqsize
= (colorWheelSize
+ 4) * (colorWheelSize
+ 4), uchar_shift
= getShift(sizeof(unsigned char));
1885 if (!panel
->wheelMtrx
)
1888 cpColor
.hsv
.value
= 255;
1889 cpColor
.set
= cpHSV
;
1892 ofs
[1] = -(colorWheelSize
+ 4);
1894 /* offsets are counterclockwise (in triangles).
1897 * _______________________________________
1898 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
1899 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
1900 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
1901 * o | | | | | | | | | | | | | | | | | | | | | [3]
1905 * |\ /| <-- triangles
1911 for (y
= 0; y
< cw_halfsize
; y
++) {
1912 for (x
= y
; x
< (colorWheelSize
+ 4 - y
); x
++) {
1913 /* (xcor, ycor) is (x,y) relative to center of matrix */
1914 xcor
= 2 * x
- 4 - colorWheelSize
;
1915 ycor
= 2 * y
- 4 - colorWheelSize
;
1917 /* RColor.saturation is unsigned char and will wrap after 255 */
1918 sat
= rint(255.0 * sqrt(xcor
* xcor
+ ycor
* ycor
) / colorWheelSize
);
1920 cpColor
.hsv
.saturation
= (unsigned char)sat
;
1922 ofs
[0]++; /* top quarter of matrix */
1923 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
1924 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
1925 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
1929 dhue
[0] = rint(atan((double)ycor
/ (double)xcor
) *
1930 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
1934 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
1935 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
1936 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
1937 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
1939 for (i
= 0; i
< 4; i
++) {
1940 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1941 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1942 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1944 cpColor
.hsv
.hue
= dhue
[i
];
1945 convertCPColor(&cpColor
);
1947 *rp
= (unsigned char)(cpColor
.rgb
.red
);
1948 *gp
= (unsigned char)(cpColor
.rgb
.green
);
1949 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
1952 for (i
= 0; i
< 4; i
++) {
1953 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1954 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1955 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1957 *rp
= (unsigned char)0;
1958 *gp
= (unsigned char)0;
1959 *bp
= (unsigned char)0;
1964 ofs
[0] += 2 * y
+ 1;
1965 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2 * y
);
1969 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
)
1974 for (i
= 0; i
< 256; i
++) {
1975 /* We divide by 128 in advance, and check whether that number divides
1976 * by 2 properly. If not, we add one to round the number correctly
1978 v
= (i
* maxvalue
) >> 7;
1979 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) + (v
& 0x01));
1983 static void wheelRender(W_ColorPanel
* panel
)
1985 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1990 unsigned long ofs
= 0;
1991 /*unsigned char shift = getShift(sizeof(unsigned char)); */
1993 image
= RCreateImage(colorWheelSize
+ 4, colorWheelSize
+ 4, True
);
1995 wwarning(_("Color Panel: Could not allocate memory"));
2001 /* TODO Make this transparent istead of gray */
2002 gray
.red
= gray
.blue
= 0xae;
2005 for (y
= 0; y
< colorWheelSize
+ 4; y
++) {
2006 for (x
= 0; x
< colorWheelSize
+ 4; x
++) {
2007 if (wheelInsideColorWheel(panel
, ofs
)) {
2009 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]]);
2011 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]]);
2013 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]]);
2016 *(ptr
++) = (unsigned char)(gray
.red
);
2017 *(ptr
++) = (unsigned char)(gray
.green
);
2018 *(ptr
++) = (unsigned char)(gray
.blue
);
2025 if (panel
->wheelImg
)
2026 XFreePixmap(scr
->display
, panel
->wheelImg
);
2028 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2029 RReleaseImage(image
);
2031 /* Check if backimage exists. If it doesn't, allocate and fill it */
2032 if (!panel
->selectionBackImg
) {
2033 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2034 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2035 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2036 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2037 /* -2 is hot spot correction */
2041 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
)
2043 return ((panel
->wheelMtrx
->data
[0][ofs
] != 0) &&
2044 (panel
->wheelMtrx
->data
[1][ofs
] != 0) && (panel
->wheelMtrx
->data
[2][ofs
] != 0));
2047 static void wheelPaint(W_ColorPanel
* panel
)
2049 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2051 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->wheelView
->window
,
2052 scr
->copyGC
, 0, 0, colorWheelSize
+ 4, colorWheelSize
+ 4, 0, 0);
2054 /* Draw selection image */
2055 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2056 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2059 static void wheelHandleEvents(XEvent
* event
, void *data
)
2061 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2063 switch (event
->type
) {
2065 if (event
->xexpose
.count
!= 0) /* TODO Improve */
2072 static void wheelHandleActionEvents(XEvent
* event
, void *data
)
2074 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2076 switch (event
->type
) {
2078 if (getPickerPart(panel
, event
->xbutton
.x
, event
->xbutton
.y
) == COLORWHEEL_PART
) {
2080 panel
->lastChanged
= WMWheelModeColorPanel
;
2081 panel
->flags
.dragging
= 1;
2083 wheelPositionSelection(panel
, event
->xbutton
.x
, event
->xbutton
.y
);
2088 panel
->flags
.dragging
= 0;
2089 if (!panel
->flags
.continuous
) {
2091 (*panel
->action
) (panel
, panel
->clientData
);
2096 if (panel
->flags
.dragging
) {
2097 if (getPickerPart(panel
, event
->xmotion
.x
, event
->xmotion
.y
) == COLORWHEEL_PART
) {
2098 wheelPositionSelection(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2100 wheelPositionSelectionOutBounds(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2106 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
)
2114 if (panel
->mode
== WMWheelModeColorPanel
) {
2115 if ((lx
>= 2) && (lx
<= 2 + colorWheelSize
) && (ly
>= 2) && (ly
<= 2 + colorWheelSize
)) {
2117 ofs
= ly
* panel
->wheelMtrx
->width
+ lx
;
2119 if (wheelInsideColorWheel(panel
, ofs
))
2120 return COLORWHEEL_PART
;
2124 if (panel
->mode
== WMCustomPaletteModeColorPanel
) {
2125 if ((lx
>= 2) && (lx
< customPaletteWidth
- 2) && (ly
>= 2) && (ly
< customPaletteHeight
- 2)) {
2126 return CUSTOMPALETTE_PART
;
2133 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
)
2137 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2139 /* Parameter not used, but tell the compiler that it is ok */
2142 value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2144 wheelCalculateValues(panel
, value
);
2146 if (panel
->color
.set
== cpRGB
) {
2147 convertCPColor(&panel
->color
);
2148 panel
->color
.set
= cpHSV
;
2151 panel
->color
.hsv
.value
= value
;
2155 wheelUpdateSelection(panel
);
2158 static void wheelUpdateSelection(W_ColorPanel
* panel
)
2160 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2162 updateSwatch(panel
, panel
->color
);
2163 panel
->lastChanged
= WMWheelModeColorPanel
;
2165 /* Redraw color selector (and make a backup of the part it will cover) */
2166 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2167 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2168 /* "-2" is correction for hotspot location */
2169 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2170 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2174 static void wheelUndrawSelection(W_ColorPanel
* panel
)
2176 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2178 XCopyArea(scr
->display
, panel
->selectionBackImg
, panel
->wheelView
->window
,
2179 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2183 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2185 unsigned long ofs
= (y
* panel
->wheelMtrx
->width
) + x
;
2187 panel
->color
.rgb
.red
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]];
2189 panel
->color
.rgb
.green
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]];
2191 panel
->color
.rgb
.blue
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]];
2192 panel
->color
.set
= cpRGB
;
2194 wheelUndrawSelection(panel
);
2199 wheelUpdateSelection(panel
);
2200 wheelUpdateBrightnessGradientFromLocation(panel
);
2203 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2209 xcor
= x
* 2 - colorWheelSize
- 4;
2210 ycor
= y
* 2 - colorWheelSize
- 4;
2212 panel
->color
.hsv
.saturation
= 255;
2213 panel
->color
.hsv
.value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2216 hue
= rint(atan(-(double)ycor
/ (double)xcor
) * (180.0 / M_PI
));
2227 if ((xcor
> 0) && (ycor
> 0))
2230 panel
->color
.hsv
.hue
= hue
;
2231 panel
->color
.set
= cpHSV
;
2232 convertCPColor(&panel
->color
);
2234 wheelUndrawSelection(panel
);
2236 panel
->colx
= 2 + rint((colorWheelSize
* (1.0 + cos(panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2237 /* "+2" because of "colorWheelSize + 4" */
2238 panel
->coly
= 2 + rint((colorWheelSize
* (1.0 + sin(-panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2240 wheelUpdateSelection(panel
);
2241 cpColor
= panel
->color
;
2242 wheelUpdateBrightnessGradient(panel
, cpColor
);
2245 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
)
2250 ofs
= panel
->coly
* panel
->wheelMtrx
->width
+ panel
->colx
;
2252 from
.rgb
.red
= panel
->wheelMtrx
->data
[0][ofs
];
2253 from
.rgb
.green
= panel
->wheelMtrx
->data
[1][ofs
];
2254 from
.rgb
.blue
= panel
->wheelMtrx
->data
[2][ofs
];
2257 wheelUpdateBrightnessGradient(panel
, from
);
2260 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
)
2264 WMPixmap
*sliderPxmp
;
2266 to
.red
= to
.green
= to
.blue
= 0;
2268 if (topColor
.set
== cpHSV
)
2269 convertCPColor(&topColor
);
2271 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2272 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
), sliderImg
, 0);
2273 RReleaseImage(sliderImg
);
2274 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2275 WMReleasePixmap(sliderPxmp
);
2278 /****************** Grayscale Panel Functions ***************/
2280 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
)
2285 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2287 /* Parameter not used, but tell the compiler that it is ok */
2290 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2292 sprintf(tmp
, "%d", value
);
2294 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2295 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55 * value
);
2296 cpColor
.set
= cpRGB
;
2298 updateSwatch(panel
, cpColor
);
2299 panel
->lastChanged
= WMGrayModeColorPanel
;
2302 static void grayPresetButtonCallback(WMWidget
* w
, void *data
)
2308 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2311 if (w
== panel
->grayPresetBtn
[i
])
2316 value
= rint((100.0 * i
) / 6.0);
2317 sprintf(tmp
, "%d", value
);
2319 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2320 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * i
) / 6.0);
2321 cpColor
.set
= cpRGB
;
2323 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0 * i
) / 6.0));
2325 updateSwatch(panel
, cpColor
);
2326 panel
->lastChanged
= WMGrayModeColorPanel
;
2329 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
)
2334 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2336 /* Parameter not used, but tell the compiler that it is ok */
2337 (void) notification
;
2339 value
= atoi(WMGetTextFieldText(panel
->grayBrightnessT
));
2345 sprintf(tmp
, "%d", value
);
2346 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2347 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2349 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * value
) / 100.0);
2350 cpColor
.set
= cpRGB
;
2352 updateSwatch(panel
, cpColor
);
2353 panel
->lastChanged
= WMGrayModeColorPanel
;
2356 /******************* RGB Panel Functions *****************/
2358 static void rgbSliderCallback(WMWidget
* w
, void *data
)
2363 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2365 /* Parameter not used, but tell the compiler that it is ok */
2368 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2369 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2370 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2372 sprintf(tmp
, "%d", value
[0]);
2373 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2374 sprintf(tmp
, "%d", value
[1]);
2375 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2376 sprintf(tmp
, "%d", value
[2]);
2377 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2379 cpColor
.rgb
.red
= value
[0];
2380 cpColor
.rgb
.green
= value
[1];
2381 cpColor
.rgb
.blue
= value
[2];
2382 cpColor
.set
= cpRGB
;
2384 updateSwatch(panel
, cpColor
);
2385 panel
->lastChanged
= WMRGBModeColorPanel
;
2388 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2394 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2396 /* Parameter not used, but tell the compiler that it is ok */
2397 (void) notification
;
2399 value
[0] = atoi(WMGetTextFieldText(panel
->rgbRedT
));
2400 value
[1] = atoi(WMGetTextFieldText(panel
->rgbGreenT
));
2401 value
[2] = atoi(WMGetTextFieldText(panel
->rgbBlueT
));
2403 for (n
= 0; n
< 3; n
++) {
2410 sprintf(tmp
, "%d", value
[0]);
2411 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2412 sprintf(tmp
, "%d", value
[1]);
2413 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2414 sprintf(tmp
, "%d", value
[2]);
2415 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2417 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2418 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2419 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2421 cpColor
.rgb
.red
= value
[0];
2422 cpColor
.rgb
.green
= value
[1];
2423 cpColor
.rgb
.blue
= value
[2];
2424 cpColor
.set
= cpRGB
;
2426 updateSwatch(panel
, cpColor
);
2427 panel
->lastChanged
= WMRGBModeColorPanel
;
2430 /******************* CMYK Panel Functions *****************/
2432 static void cmykSliderCallback(WMWidget
* w
, void *data
)
2437 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2440 /* Parameter not used, but tell the compiler that it is ok */
2443 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2444 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2445 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2446 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2448 sprintf(tmp
, "%d", value
[0]);
2449 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2450 sprintf(tmp
, "%d", value
[1]);
2451 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2452 sprintf(tmp
, "%d", value
[2]);
2453 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2454 sprintf(tmp
, "%d", value
[3]);
2455 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2457 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2458 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2459 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2460 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2461 cpColor
.set
= cpRGB
;
2463 updateSwatch(panel
, cpColor
);
2464 panel
->lastChanged
= WMCMYKModeColorPanel
;
2467 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
)
2474 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2476 /* Parameter not used, but tell the compiler that it is ok */
2477 (void) notification
;
2479 value
[0] = atoi(WMGetTextFieldText(panel
->cmykCyanT
));
2480 value
[1] = atoi(WMGetTextFieldText(panel
->cmykMagentaT
));
2481 value
[2] = atoi(WMGetTextFieldText(panel
->cmykYellowT
));
2482 value
[3] = atoi(WMGetTextFieldText(panel
->cmykBlackT
));
2484 for (n
= 0; n
< 4; n
++) {
2491 sprintf(tmp
, "%d", value
[0]);
2492 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2494 sprintf(tmp
, "%d", value
[1]);
2495 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2497 sprintf(tmp
, "%d", value
[2]);
2498 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2500 sprintf(tmp
, "%d", value
[3]);
2501 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2503 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2504 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2505 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2506 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2508 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2509 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2510 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2511 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2512 cpColor
.set
= cpRGB
;
2514 updateSwatch(panel
, cpColor
);
2515 panel
->lastChanged
= WMCMYKModeColorPanel
;
2518 /********************** HSB Panel Functions ***********************/
2520 static void hsbSliderCallback(WMWidget
* w
, void *data
)
2525 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2527 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2528 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2529 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2531 sprintf(tmp
, "%d", value
[0]);
2532 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2533 sprintf(tmp
, "%d", value
[1]);
2534 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2535 sprintf(tmp
, "%d", value
[2]);
2536 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2538 cpColor
.hsv
.hue
= value
[0];
2539 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2540 cpColor
.hsv
.value
= value
[2] * 2.55;
2541 cpColor
.set
= cpHSV
;
2543 convertCPColor(&cpColor
);
2545 panel
->lastChanged
= WMHSBModeColorPanel
;
2546 updateSwatch(panel
, cpColor
);
2548 if (w
!= panel
->hsbBrightnessS
)
2549 hsbUpdateBrightnessGradient(panel
);
2550 if (w
!= panel
->hsbSaturationS
)
2551 hsbUpdateSaturationGradient(panel
);
2552 if (w
!= panel
->hsbHueS
)
2553 hsbUpdateHueGradient(panel
);
2556 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2562 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2564 /* Parameter not used, but tell the compiler that it is ok */
2565 (void) notification
;
2567 value
[0] = atoi(WMGetTextFieldText(panel
->hsbHueT
));
2568 value
[1] = atoi(WMGetTextFieldText(panel
->hsbSaturationT
));
2569 value
[2] = atoi(WMGetTextFieldText(panel
->hsbBrightnessT
));
2576 for (n
= 1; n
< 3; n
++) {
2583 sprintf(tmp
, "%d", value
[0]);
2584 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2585 sprintf(tmp
, "%d", value
[1]);
2586 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2587 sprintf(tmp
, "%d", value
[2]);
2588 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2590 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2591 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2592 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2594 cpColor
.hsv
.hue
= value
[0];
2595 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2596 cpColor
.hsv
.value
= value
[2] * 2.55;
2597 cpColor
.set
= cpHSV
;
2599 convertCPColor(&cpColor
);
2601 panel
->lastChanged
= WMHSBModeColorPanel
;
2602 updateSwatch(panel
, cpColor
);
2604 hsbUpdateBrightnessGradient(panel
);
2605 hsbUpdateSaturationGradient(panel
);
2606 hsbUpdateHueGradient(panel
);
2609 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
)
2611 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2615 WMPixmap
*sliderPxmp
;
2617 from
.red
= from
.green
= from
.blue
= 0;
2618 to
.hsv
= panel
->color
.hsv
;
2622 convertCPColor(&to
);
2624 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2625 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2626 RReleaseImage(sliderImg
);
2629 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2630 panel
->font12
, 2, 0, 100, WALeft
, scr
->white
,
2631 False
, _("Brightness"), strlen(_("Brightness")));
2633 wwarning(_("Color Panel: Could not allocate memory"));
2635 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2636 WMReleasePixmap(sliderPxmp
);
2639 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
)
2641 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2645 WMPixmap
*sliderPxmp
;
2647 from
.hsv
= panel
->color
.hsv
;
2648 from
.hsv
.saturation
= 0;
2650 convertCPColor(&from
);
2652 to
.hsv
= panel
->color
.hsv
;
2653 to
.hsv
.saturation
= 255;
2655 convertCPColor(&to
);
2657 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
), RGRD_HORIZONTAL
);
2658 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2659 RReleaseImage(sliderImg
);
2662 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2663 panel
->font12
, 2, 0, 100, WALeft
,
2664 from
.hsv
.value
< 128 ? scr
->white
: scr
->black
, False
,
2665 _("Saturation"), strlen(_("Saturation")));
2667 wwarning(_("Color Panel: Could not allocate memory"));
2669 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2670 WMReleasePixmap(sliderPxmp
);
2673 static void hsbUpdateHueGradient(W_ColorPanel
* panel
)
2675 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2676 RColor
**colors
= NULL
;
2679 WMPixmap
*sliderPxmp
;
2682 hsvcolor
= panel
->color
.hsv
;
2684 colors
= wmalloc(sizeof(RColor
*) * (8));
2685 for (i
= 0; i
< 7; i
++) {
2686 hsvcolor
.hue
= (360 * i
) / 6;
2687 colors
[i
] = wmalloc(sizeof(RColor
));
2688 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2692 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2693 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2694 RReleaseImage(sliderImg
);
2697 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2698 panel
->font12
, 2, 0, 100, WALeft
,
2699 hsvcolor
.value
< 128 ? scr
->white
: scr
->black
, False
, _("Hue"), strlen(_("Hue")));
2701 wwarning(_("Color Panel: Could not allocate memory"));
2703 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2704 WMReleasePixmap(sliderPxmp
);
2706 for (i
= 0; i
< 7; i
++)
2712 /*************** Custom Palette Functions ****************/
2714 static void customRenderSpectrum(W_ColorPanel
* panel
)
2721 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, False
);
2723 ptr
= spectrum
->data
;
2725 for (y
= 0; y
< SPECTRUM_HEIGHT
; y
++) {
2726 cpColor
.hsv
.hue
= y
;
2727 cpColor
.hsv
.saturation
= 0;
2728 cpColor
.hsv
.value
= 255;
2729 cpColor
.set
= cpHSV
;
2731 for (x
= 0; x
< SPECTRUM_WIDTH
; x
++) {
2732 convertCPColor(&cpColor
);
2734 *(ptr
++) = (unsigned char)cpColor
.rgb
.red
;
2735 *(ptr
++) = (unsigned char)cpColor
.rgb
.green
;
2736 *(ptr
++) = (unsigned char)cpColor
.rgb
.blue
;
2738 if (x
< (SPECTRUM_WIDTH
/ 2))
2739 cpColor
.hsv
.saturation
++;
2741 if (x
> (SPECTRUM_WIDTH
/ 2))
2742 cpColor
.hsv
.value
--;
2745 if (panel
->customPaletteImg
) {
2746 RReleaseImage(panel
->customPaletteImg
);
2747 panel
->customPaletteImg
= NULL
;
2749 panel
->customPaletteImg
= spectrum
;
2752 static void customSetPalette(W_ColorPanel
* panel
)
2754 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2758 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
, customPaletteHeight
, scr
->depth
);
2759 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
, customPaletteHeight
);
2760 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2761 RReleaseImage(scaledImg
);
2763 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2764 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2766 /* Check backimage exists. If it doesn't, allocate and fill it */
2767 if (!panel
->selectionBackImg
) {
2768 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2769 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2772 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2773 panel
->palx
- 2, panel
->paly
- 2, 4, 4, 0, 0);
2774 XCopyArea(scr
->display
, panel
->selectionImg
,
2775 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2776 panel
->palx
- 2, panel
->paly
- 2);
2777 XFreePixmap(scr
->display
, image
);
2779 panel
->palXRatio
= (double)(panel
->customPaletteImg
->width
) / (double)(customPaletteWidth
);
2780 panel
->palYRatio
= (double)(panel
->customPaletteImg
->height
) / (double)(customPaletteHeight
);
2782 WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2785 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2787 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2790 /* undraw selection */
2791 XCopyArea(scr
->display
, panel
->selectionBackImg
,
2792 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2793 panel
->palx
- 2, panel
->paly
- 2);
2798 ofs
= (rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) * panel
->customPaletteImg
->width
) * 3;
2800 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[ofs
];
2801 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[ofs
+ 1];
2802 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[ofs
+ 2];
2803 panel
->color
.set
= cpRGB
;
2805 updateSwatch(panel
, panel
->color
);
2806 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
2808 /* Redraw color selector (and make a backup of the part it will cover) */
2809 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 */
2810 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4, panel
->palx
- 2, panel
->paly
- 2); /* see above */
2813 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2819 if (x
>= customPaletteWidth
)
2820 x
= customPaletteWidth
- 2;
2821 if (y
>= customPaletteHeight
)
2822 y
= customPaletteHeight
- 2;
2824 customPalettePositionSelection(panel
, x
, y
);
2827 static void customPaletteHandleEvents(XEvent
* event
, void *data
)
2829 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2831 switch (event
->type
) {
2833 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
2835 customSetPalette(panel
);
2840 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
)
2842 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2845 switch (event
->type
) {
2847 x
= event
->xbutton
.x
;
2848 y
= event
->xbutton
.y
;
2850 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2851 panel
->flags
.dragging
= 1;
2852 customPalettePositionSelection(panel
, x
, y
);
2857 panel
->flags
.dragging
= 0;
2858 if (!panel
->flags
.continuous
) {
2860 (*panel
->action
) (panel
, panel
->clientData
);
2865 x
= event
->xmotion
.x
;
2866 y
= event
->xmotion
.y
;
2868 if (panel
->flags
.dragging
) {
2869 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2870 customPalettePositionSelection(panel
, x
, y
);
2872 customPalettePositionSelectionOutBounds(panel
, x
, y
);
2878 static void customPaletteMenuCallback(WMWidget
* w
, void *data
)
2880 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2881 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
2883 /* Parameter not used, but tell the compiler that it is ok */
2887 case CPmenuNewFromFile
:
2888 customPaletteMenuNewFromFile(panel
);
2891 customPaletteMenuRename(panel
);
2894 customPaletteMenuRemove(panel
);
2898 case CPmenuNewFromClipboard
:
2903 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
)
2905 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2906 WMOpenPanel
*browseP
;
2908 char *filename
= NULL
;
2912 RImage
*tmpImg
= NULL
;
2914 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
, "\0") == 0))
2915 spath
= wexpandpath(wgethomedir());
2917 spath
= wexpandpath(panel
->lastBrowseDir
);
2919 browseP
= WMGetOpenPanel(scr
);
2920 WMSetFilePanelCanChooseDirectories(browseP
, 0);
2921 WMSetFilePanelCanChooseFiles(browseP
, 1);
2923 /* Get a filename */
2924 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
2925 _("Open Palette"), RSupportedFileFormats())) {
2926 filepath
= WMGetFilePanelFileName(browseP
);
2928 /* Get seperation position between path and filename */
2929 i
= strrchr(filepath
, '/') - filepath
+ 1;
2930 if (i
> strlen(filepath
))
2931 i
= strlen(filepath
);
2933 /* Store last browsed path */
2934 if (panel
->lastBrowseDir
)
2935 wfree(panel
->lastBrowseDir
);
2936 panel
->lastBrowseDir
= wmalloc((i
+ 1) * sizeof(char));
2937 strncpy(panel
->lastBrowseDir
, filepath
, i
);
2938 panel
->lastBrowseDir
[i
] = '\0';
2940 /* Get filename from path */
2941 filename
= wstrdup(filepath
+ i
);
2943 /* Check for duplicate files, and rename it if there are any */
2944 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2945 while (access(tmp
, F_OK
) == 0) {
2950 newName
= generateNewFilename(filename
);
2954 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2958 /* Copy image to $(gnustepdir)/Library/Colors/ &
2959 * Add filename to history menu */
2960 if (wcopy_file(panel
->configurationPath
, filepath
, filename
) == 0) {
2962 /* filepath is a "local" path now the file has been copied */
2964 filepath
= wstrconcat(panel
->configurationPath
, filename
);
2966 /* load the image & add menu entries */
2967 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
2969 if (panel
->customPaletteImg
)
2970 RReleaseImage(panel
->customPaletteImg
);
2971 panel
->customPaletteImg
= tmpImg
;
2973 customSetPalette(panel
);
2974 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
2976 panel
->currentPalette
=
2977 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1;
2979 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
2980 panel
->currentPalette
);
2983 tmp
= wstrconcat(panel
->configurationPath
, filename
);
2985 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
2986 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2987 _("Invalid file format !"), _("OK"), NULL
, NULL
);
2989 werror(_("can't remove file %s"), tmp
);
2990 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
2991 _("Couldn't remove file from Configuration Directory !"),
2992 _("OK"), NULL
, NULL
);
2999 WMFreeFilePanel(browseP
);
3004 static void customPaletteMenuRename(W_ColorPanel
* panel
)
3006 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3007 char *toName
= NULL
;
3009 char *toPath
, *fromPath
;
3013 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3014 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3016 toName
= WMRunInputPanel(scr
, panel
->win
, _("Rename"), _("Rename palette to:"),
3017 fromName
, _("OK"), _("Cancel"));
3021 /* As some people do certain stupid things... */
3022 if (strcmp(toName
, fromName
) == 0) {
3027 /* For normal people */
3028 fromPath
= wstrconcat(panel
->configurationPath
, fromName
);
3029 toPath
= wstrconcat(panel
->configurationPath
, toName
);
3031 if (access(toPath
, F_OK
) == 0) {
3032 /* Careful, this palette exists already */
3033 if (WMRunAlertPanel(scr
, panel
->win
, _("Warning"),
3034 _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"),
3036 /* "No" = 0, "Yes" = 1 */
3037 int items
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
3041 /* Remove from History list too */
3043 while ((index
< items
)
3045 (strcmp(WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, index
), toName
)
3049 if (index
< items
) {
3050 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, index
);
3064 if (rename(fromPath
, toPath
) != 0)
3065 werror(_("Couldn't rename palette %s to %s"), fromName
, toName
);
3067 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3068 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
, toName
);
3070 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3078 static void customPaletteMenuRemove(W_ColorPanel
* panel
)
3080 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3086 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3088 tmp
= wstrconcat(_("This will permanently remove the palette "),
3089 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3090 text
= wstrconcat(tmp
, _(".\n\nAre you sure you want to remove this palette ?"));
3093 choice
= WMRunAlertPanel(scr
, panel
->win
, _("Remove"), text
, _("Yes"), _("No"), NULL
);
3094 /* returns 0 (= "Yes") or 1 (="No") */
3099 tmp
= wstrconcat(panel
->configurationPath
,
3100 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3102 if (remove(tmp
) == 0) {
3103 /* item-1 always exists */
3104 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3106 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
, panel
);
3107 customSetPalette(panel
);
3109 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3112 werror(_("Couldn't remove palette %s"), tmp
);
3119 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
)
3121 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3122 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3126 unsigned char perm_mask
;
3128 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3129 if (item
== panel
->currentPalette
)
3133 customRenderSpectrum(panel
);
3135 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, False
);
3136 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, False
);
3138 /* Load file from configpath */
3139 filename
= wstrconcat(panel
->configurationPath
,
3140 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3142 /* If the file corresponding to the item does not exist,
3143 * remove it from the history list and select the next one.
3145 perm_mask
= (access(filename
, F_OK
) == 0);
3147 /* File does not exist */
3149 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3150 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3151 customPaletteHistoryCallback(w
, data
);
3156 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3158 if (panel
->customPaletteImg
) {
3159 RReleaseImage(panel
->customPaletteImg
);
3160 panel
->customPaletteImg
= NULL
;
3162 panel
->customPaletteImg
= tmp
;
3165 /* If the image is not writable, don't allow removing/renaming */
3166 perm_mask
= (access(filename
, W_OK
) == 0);
3167 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, perm_mask
);
3168 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, perm_mask
);
3172 customSetPalette(panel
);
3174 panel
->currentPalette
= item
;
3177 /************************* ColorList Panel Functions **********************/
3179 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
)
3181 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3182 Display
*dpy
= WMScreenDisplay(scr
);
3183 WMView
*view
= W_VIEW(lPtr
);
3184 RColor
*color
= (RColor
*) WMGetListItem(lPtr
, index
)->clientData
;
3185 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3186 int width
, height
, x
, y
;
3189 width
= rect
->size
.width
;
3190 height
= rect
->size
.height
;
3194 if (state
& WLDSSelected
)
3195 XFillRectangle(dpy
, d
, WMColorGC(scr
->white
), x
, y
, width
, height
);
3197 XFillRectangle(dpy
, d
, WMColorGC(view
->backColor
), x
, y
, width
, height
);
3199 fillColor
= WMCreateRGBColor(scr
, color
->red
<< 8, color
->green
<< 8, color
->blue
<< 8, True
);
3201 XFillRectangle(dpy
, d
, WMColorGC(fillColor
), x
, y
, 15, height
);
3202 WMReleaseColor(fillColor
);
3204 WMDrawString(scr
, d
, scr
->black
, panel
->font12
, x
+ 18, y
, text
, strlen(text
));
3207 static void colorListSelect(WMWidget
* w
, void *data
)
3209 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3212 cpColor
.rgb
= *((RColor
*) WMGetListSelectedItem(w
)->clientData
);
3213 cpColor
.set
= cpRGB
;
3215 panel
->lastChanged
= WMColorListModeColorPanel
;
3216 updateSwatch(panel
, cpColor
);
3219 static void colorListColorMenuCallback(WMWidget
* w
, void *data
)
3221 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3222 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3224 /* Parameter not used, but tell the compiler that it is ok */
3237 static void colorListListMenuCallback(WMWidget
* w
, void *data
)
3239 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3240 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3242 /* Parameter not used, but tell the compiler that it is ok */
3247 /* New Color List */
3248 colorListListMenuNew(panel
);
3257 static void colorListListMenuNew(W_ColorPanel
* panel
)
3262 /*************** Panel Initialisation Functions *****************/
3264 static void wheelInit(W_ColorPanel
* panel
)
3268 if (panel
->color
.set
!= cpHSV
)
3269 convertCPColor(&panel
->color
);
3271 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3273 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3274 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3275 cos(panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3276 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3277 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3278 sin(-panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3280 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3282 cpColor
= panel
->color
;
3283 cpColor
.hsv
.value
= 255;
3284 cpColor
.set
= cpHSV
;
3285 wheelUpdateBrightnessGradient(panel
, cpColor
);
3288 static void grayInit(W_ColorPanel
* panel
)
3293 if (panel
->color
.set
!= cpHSV
)
3294 convertCPColor(&panel
->color
);
3296 value
= rint(panel
->color
.hsv
.value
/ 2.55);
3297 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3299 sprintf(tmp
, "%d", value
);
3300 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3303 static void rgbInit(W_ColorPanel
* panel
)
3307 if (panel
->color
.set
!= cpRGB
)
3308 convertCPColor(&panel
->color
);
3310 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3311 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3312 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3314 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3315 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3316 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3317 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3318 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3319 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3322 static void cmykInit(W_ColorPanel
* panel
)
3327 if (panel
->color
.set
!= cpRGB
)
3328 convertCPColor(&panel
->color
);
3330 value
[0] = rint((255 - panel
->color
.rgb
.red
) / 2.55);
3331 value
[1] = rint((255 - panel
->color
.rgb
.green
) / 2.55);
3332 value
[2] = rint((255 - panel
->color
.rgb
.blue
) / 2.55);
3334 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3335 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3336 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3337 WMSetSliderValue(panel
->cmykBlackS
, 0);
3339 sprintf(tmp
, "%d", value
[0]);
3340 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3341 sprintf(tmp
, "%d", value
[1]);
3342 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3343 sprintf(tmp
, "%d", value
[2]);
3344 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3345 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3348 static void hsbInit(W_ColorPanel
* panel
)
3353 if (panel
->color
.set
!= cpHSV
)
3354 convertCPColor(&panel
->color
);
3356 value
[0] = panel
->color
.hsv
.hue
;
3357 value
[1] = rint(panel
->color
.hsv
.saturation
/ 2.55);
3358 value
[2] = rint(panel
->color
.hsv
.value
/ 2.55);
3360 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
3361 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
3362 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
3364 sprintf(tmp
, "%d", value
[0]);
3365 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3366 sprintf(tmp
, "%d", value
[1]);
3367 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3368 sprintf(tmp
, "%d", value
[2]);
3369 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3371 hsbUpdateBrightnessGradient(panel
);
3372 hsbUpdateSaturationGradient(panel
);
3373 hsbUpdateHueGradient(panel
);
3376 /************************** Common utility functions ************************/
3378 static char *generateNewFilename(const char *curName
)
3390 if (((ptr
= strrchr(ptr
, '{')) == 0) || sscanf(ptr
, "{%i}%c", &n
, &c
) != 1)
3391 return wstrconcat(curName
, " {1}");
3393 baseLen
= ptr
- curName
- 1;
3395 newName
= wmalloc(baseLen
+ 16);
3396 strncpy(newName
, curName
, baseLen
);
3398 snprintf(&newName
[baseLen
], 16, " {%i}", n
+ 1);
3403 static void convertCPColor(CPColor
* color
)
3405 unsigned short old_hue
= 0;
3407 switch (color
->set
) {
3409 wwarning(_("Color Panel: Color unspecified"));
3412 old_hue
= color
->hsv
.hue
;
3413 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3415 /* In black the hue is undefined, and may change by conversion
3416 * Same for white. */
3417 if (((color
->rgb
.red
== 0) &&
3418 (color
->rgb
.green
== 0) &&
3419 (color
->rgb
.blue
== 0)) ||
3420 ((color
->rgb
.red
== 0) && (color
->rgb
.green
== 0) && (color
->rgb
.blue
== 255))
3422 color
->hsv
.hue
= old_hue
;
3425 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3430 #define ABS_SHIFT(val, shift) \
3431 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3433 static RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
)
3436 XColor
*xcolor
= NULL
;
3438 xcolor
= wmalloc(sizeof(XColor
));
3439 xcolor
->pixel
= value
;
3440 XQueryColor(scr
->display
, scr
->rcontext
->cmap
, xcolor
);
3442 color
.red
= xcolor
->red
>> 8;
3443 color
.green
= xcolor
->green
>> 8;
3444 color
.blue
= xcolor
->blue
>> 8;
3452 static unsigned char getShift(unsigned char value
)
3454 unsigned char i
= -1;
3467 #ifdef SHAPE_WAS_DEFINED
3468 #undef SHAPE_WAS_DEFINED