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 ;-)
19 * - Look at further optimization of colorWheel matrix calculation.
20 * It appears to be rather symmetric in angles of 60 degrees,
21 * while it is optimized in angles of 90 degrees.
22 * - Custom color-lists and custom colors in custom color-lists.
27 #include "../src/config.h"
33 #include <sys/types.h>
38 /* BUG There's something fishy with shaped windows */
41 #define SHAPE_WAS_DEFINED
48 #include <X11/extensions/shape.h>
53 # define PATH_MAX 1024
57 char *WMColorPanelColorChangedNotification
= "WMColorPanelColorChangedNotification";
62 #define NO_MEMORY_ERR "Color Panel: Could not allocate memory"
63 #define NO_FILE_ERR "Color Panel: Could not find file"
64 #define X_ERR "Color Panel: X failed request"
68 * Bitmaps for magnifying glass cursor
72 #define Cursor_x_hot 11
73 #define Cursor_y_hot 11
74 #define Cursor_width 32
75 #define Cursor_height 32
76 static unsigned char Cursor_bits
[] = {
77 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
78 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
79 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
80 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
81 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
82 0x00,0x08,0x00,0x50,0x00,0x10,0x00,0x88,0x00,0x20,0x00,0x5c,0x01,0xc0,0x81,
83 0x3b,0x02,0x00,0x7e,0x70,0x05,0x00,0x00,0xe0,0x08,0x00,0x00,0xc0,0x15,0x00,
84 0x00,0x80,0x23,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x5c,
85 0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x70};
87 /* Cursor shape-mask */
88 #define Cursor_shape_width 32
89 #define Cursor_shape_height 32
90 static unsigned char Cursor_shape_bits
[] = {
91 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
92 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
93 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
94 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
95 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
96 0x00,0x08,0x00,0x70,0x00,0x10,0x00,0xf8,0x00,0x20,0x00,0xfc,0x01,0xc0,0x81,
97 0xfb,0x03,0x00,0x7e,0xf0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x1f,0x00,
98 0x00,0x80,0x3f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfc,
99 0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70};
101 /* Clip-mask for magnified pixels */
102 #define Cursor_mask_width 24
103 #define Cursor_mask_height 24
104 static unsigned char Cursor_mask_bits
[] = {
105 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07,
106 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
107 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
108 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f,
109 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f,
110 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00};
113 typedef struct MovingView
{
114 WMView
*view
; /* The view this is all about */
115 XImage
*image
; /* What's under the view */
116 XImage
*dirtyRect
; /* Storage of overlapped image area */
117 Pixmap magPix
; /* Magnified part of pixmap */
118 RColor color
; /* Color of a pixel in the image */
119 int x
, y
; /* Position of view */
122 typedef struct CPColor
{
123 RColor rgb
; /* The RGB values of the color */
124 RHSVColor hsv
; /* The HSV values of the color */
125 enum { /* Which one was last set ? */
133 typedef struct WheelMatrix
{
134 unsigned int width
, height
; /* Size of the colorwheel */
135 unsigned char *data
[3]; /* Wheel data (R,G,B) */
136 unsigned char values
[256]; /* Precalculated values R,G & B = 0-255 */
139 typedef struct W_ColorPanel
{
147 WMColorWell
*colorWell
;
148 WMButton
*magnifyBtn
;
150 WMButton
*slidersBtn
;
151 WMButton
*customPaletteBtn
;
152 WMButton
*colorListBtn
;
154 /* Magnifying Glass */
155 MovingView
*magnifyGlass
;
157 /* ColorWheel Panel */
159 WMSlider
*wheelBrightnessS
;
164 WMFrame
*seperatorFrm
;
169 /* Gray Scale Panel */
173 WMSlider
*grayBrightnessS
;
174 WMTextField
*grayBrightnessT
;
175 WMButton
*grayPresetBtn
[7];
184 WMTextField
*rgbRedT
;
185 WMTextField
*rgbGreenT
;
186 WMTextField
*rgbBlueT
;
193 WMSlider
*cmykMagentaS
;
194 WMSlider
*cmykYellowS
;
195 WMSlider
*cmykBlackS
;
196 WMTextField
*cmykCyanT
;
197 WMTextField
*cmykMagentaT
;
198 WMTextField
*cmykYellowT
;
199 WMTextField
*cmykBlackT
;
204 WMSlider
*hsbSaturationS
;
205 WMSlider
*hsbBrightnessS
;
206 WMTextField
*hsbHueT
;
207 WMTextField
*hsbSaturationT
;
208 WMTextField
*hsbBrightnessT
;
210 /* Custom Palette Panel*/
211 WMFrame
*customPaletteFrm
;
212 WMPopUpButton
*customPaletteHistoryBtn
;
213 WMFrame
*customPaletteContentFrm
;
214 WMPopUpButton
*customPaletteMenuBtn
;
215 WMView
*customPaletteContentView
;
217 /* Color List Panel */
218 WMFrame
*colorListFrm
;
219 WMPopUpButton
*colorListHistoryBtn
;
220 WMList
*colorListContentLst
;
221 WMPopUpButton
*colorListColorMenuBtn
;
222 WMPopUpButton
*colorListListMenuBtn
;
224 /* Look-Up Tables and Images */
225 wheelMatrix
*wheelMtrx
;
228 Pixmap selectionBackImg
;
229 RImage
*customPaletteImg
;
232 /* Common Data Fields */
233 CPColor color
; /* Current color */
234 WMColorPanelMode mode
; /* Current color selection mode */
235 WMColorPanelMode slidersmode
; /* Current color sel. mode sliders panel */
236 WMColorPanelMode lastChanged
; /* Panel that last changed the color */
237 int colx
, coly
; /* (x,y) of sel.-marker in WheelMode */
238 int palx
, paly
; /* (x,y) of sel.-marker in
240 double palXRatio
, palYRatio
; /* Ratios in x & y between
244 char *configurationPath
;
247 unsigned int continuous
:1;
248 unsigned int dragging
:1;
257 CPmenuNewFromClipboard
258 } customPaletteMenuItem
;
269 #define colorWheelSize 150
270 #define customPaletteWidth 182
271 #define customPaletteHeight 106
272 #define knobThickness 8
274 #define SPECTRUM_WIDTH 511
275 #define SPECTRUM_HEIGHT 360
277 #define COLORWHEEL_PART 1
278 #define CUSTOMPALETTE_PART 2
282 #define RGBTXT "/usr/X11R6/lib/X11/rgb.txt"
285 #define MAX_LENGTH 1024
289 #define M_PI 3.14159265358979323846
293 static int fetchFile(char* toPath
, char *imageSrcFile
,
294 char *imageDestFileName
);
295 char *generateNewFilename(char *curName
);
296 void convertCPColor(CPColor
*color
);
297 RColor
ulongToRColor(WMScreen
*scr
, unsigned long value
);
298 unsigned char getShift(unsigned char value
);
300 static void modeButtonCallback(WMWidget
*w
, void *data
);
301 static int getPickerPart(W_ColorPanel
*panel
, int x
, int y
);
302 static void readConfiguration(W_ColorPanel
*panel
);
303 static void readXColors(W_ColorPanel
*panel
);
305 static void closeWindowCallback(WMWidget
*w
, void *data
);
307 static Cursor
magnifyGrabPointer(W_ColorPanel
*panel
);
308 static WMPoint
magnifyInitialize(W_ColorPanel
*panel
);
309 static void magnifyPutCursor(WMWidget
*w
, void *data
);
310 static Pixmap
magnifyCreatePixmap(WMColorPanel
*panel
);
311 static void magnifyGetImageStored(W_ColorPanel
*panel
, int x1
, int y1
,
313 static XImage
* magnifyGetImage(WMScreen
*scr
, XImage
*image
, int x
, int y
,
316 static wheelMatrix
* wheelCreateMatrix(unsigned int width
, unsigned int height
);
317 static void wheelDestroyMatrix(wheelMatrix
*matrix
);
318 static void wheelInitMatrix(W_ColorPanel
*panel
);
319 static void wheelCalculateValues(W_ColorPanel
*panel
, int maxvalue
);
320 static void wheelRender(W_ColorPanel
*panel
);
321 static Bool
wheelInsideColorWheel(W_ColorPanel
*panel
, unsigned long ofs
);
322 static void wheelPaint(W_ColorPanel
*panel
);
324 static void wheelHandleEvents(XEvent
*event
, void *data
);
325 static void wheelHandleActionEvents(XEvent
*event
, void *data
);
326 static void wheelBrightnessSliderCallback(WMWidget
*w
, void *data
);
327 static void wheelUpdateSelection(W_ColorPanel
*panel
);
328 static void wheelUndrawSelection(W_ColorPanel
*panel
);
330 static void wheelPositionSelection(W_ColorPanel
*panel
, int x
, int y
);
331 static void wheelPositionSelectionOutBounds(W_ColorPanel
*panel
, int x
, int y
);
332 static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel
*panel
);
333 static void wheelUpdateBrightnessGradient(W_ColorPanel
*panel
, CPColor topColor
);
335 static void grayBrightnessSliderCallback(WMWidget
*w
, void *data
);
336 static void grayPresetButtonCallback(WMWidget
*w
, void *data
);
337 static void grayBrightnessTextFieldCallback(void *observerData
,
338 WMNotification
*notification
);
340 static void rgbSliderCallback(WMWidget
*w
, void *data
);
341 static void rgbTextFieldCallback(void *observerData
,
342 WMNotification
*notification
);
344 static void cmykSliderCallback(WMWidget
*w
, void *data
);
345 static void cmykTextFieldCallback(void *observerData
,
346 WMNotification
*notification
);
348 static void hsbSliderCallback(WMWidget
*w
, void *data
);
349 static void hsbTextFieldCallback(void *observerData
,
350 WMNotification
*notification
);
351 static void hsbUpdateBrightnessGradient(W_ColorPanel
*panel
);
352 static void hsbUpdateSaturationGradient(W_ColorPanel
*panel
);
353 static void hsbUpdateHueGradient(W_ColorPanel
*panel
);
355 static void customRenderSpectrum(W_ColorPanel
*panel
);
356 static void customSetPalette(W_ColorPanel
*panel
);
357 static void customPaletteHandleEvents(XEvent
*event
, void *data
);
358 static void customPaletteHandleActionEvents(XEvent
*event
, void *data
);
359 static void customPalettePositionSelection(W_ColorPanel
*panel
, int x
, int y
);
360 static void customPalettePositionSelectionOutBounds(W_ColorPanel
*panel
,
362 static void customPaletteMenuCallback(WMWidget
*w
, void *data
);
363 static void customPaletteHistoryCallback(WMWidget
*w
, void *data
);
365 static void customPaletteMenuNewFromFile(W_ColorPanel
*panel
);
366 static void customPaletteMenuRename(W_ColorPanel
*panel
);
367 static void customPaletteMenuRemove(W_ColorPanel
*panel
);
369 static void colorListPaintItem(WMList
*lPtr
, int index
, Drawable d
, char *text
,
370 int state
, WMRect
*rect
);
371 static void colorListSelect(WMWidget
*w
, void *data
);
372 static void colorListColorMenuCallback(WMWidget
*w
, void *data
);
373 static void colorListListMenuCallback(WMWidget
*w
, void *data
);
374 static void colorListListMenuNew(W_ColorPanel
*panel
);
376 static void wheelInit(W_ColorPanel
*panel
);
377 static void grayInit(W_ColorPanel
*panel
);
378 static void rgbInit(W_ColorPanel
*panel
);
379 static void cmykInit(W_ColorPanel
*panel
);
380 static void hsbInit(W_ColorPanel
*panel
);
385 WMSetColorPanelAction(WMColorPanel
*panel
, WMAction2
*action
, void *data
)
387 panel
->action
= action
;
388 panel
->clientData
= data
;
392 makeColorPanel(WMScreen
*scrPtr
, char *name
)
399 WMColor
*textcolor
, *graybuttoncolor
;
401 GC bgc
= WMColorGC(scrPtr
->black
);
402 GC wgc
= WMColorGC(scrPtr
->white
);
405 panel
= wmalloc(sizeof(WMColorPanel
));
406 memset(panel
, 0, sizeof(WMColorPanel
));
408 panel
->color
.rgb
.red
= 0;
409 panel
->color
.rgb
.green
= 0;
410 panel
->color
.rgb
.blue
= 0;
411 panel
->color
.hsv
.hue
= 0;
412 panel
->color
.hsv
.saturation
= 0;
413 panel
->color
.hsv
.value
= 0;
414 panel
->color
.set
= cpNone
; /* Color has not been set yet */
416 panel
->font8
= WMSystemFontOfSize(scrPtr
, 8);
417 panel
->font12
= WMSystemFontOfSize(scrPtr
, 12);
419 panel
->win
= WMCreateWindowWithStyle(scrPtr
, name
,
420 WMTitledWindowMask
| WMClosableWindowMask
| WMResizableWindowMask
);
421 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
422 WMSetWindowTitle(panel
->win
, "Colors");
423 WMSetWindowCloseAction(panel
->win
, closeWindowCallback
, panel
);
426 /* Set Default ColorPanel Mode(s) */
427 panel
->mode
= WMWheelModeColorPanel
;
428 panel
->lastChanged
= 0;
429 panel
->slidersmode
= WMRGBModeColorPanel
;
430 panel
->configurationPath
= wstrconcat(wusergnusteppath(),
433 /* Some General Purpose Widgets */
434 panel
->colorWell
= WMCreateColorWell(panel
->win
);
435 WMResizeWidget(panel
->colorWell
, 134, 36);
436 WSetColorWellBordered(panel
->colorWell
, False
);
437 WMMoveWidget(panel
->colorWell
, 56, 4);
439 panel
->magnifyBtn
= WMCreateCustomButton(panel
->win
,
440 WBBStateLightMask
|WBBStateChangeMask
);
441 WMResizeWidget(panel
->magnifyBtn
, 46, 36);
442 WMMoveWidget(panel
->magnifyBtn
, 6,4);
443 WMSetButtonAction(panel
->magnifyBtn
, magnifyPutCursor
, panel
);
444 WMSetButtonImagePosition(panel
->magnifyBtn
, WIPImageOnly
);
445 WMSetButtonImage(panel
->magnifyBtn
, scrPtr
->magnifyIcon
);
447 panel
->wheelBtn
= WMCreateCustomButton(panel
->win
,
448 WBBStateLightMask
|WBBStateChangeMask
);
449 WMResizeWidget(panel
->wheelBtn
, 46, 32);
450 WMMoveWidget(panel
->wheelBtn
, 6, 44);
451 WMSetButtonAction(panel
->wheelBtn
, modeButtonCallback
, panel
);
452 WMSetButtonImagePosition(panel
->wheelBtn
, WIPImageOnly
);
453 WMSetButtonImage(panel
->wheelBtn
, scrPtr
->wheelIcon
);
455 panel
->slidersBtn
= WMCreateCustomButton(panel
->win
,
456 WBBStateLightMask
|WBBStateChangeMask
);
457 WMResizeWidget(panel
->slidersBtn
, 46, 32);
458 WMMoveWidget(panel
->slidersBtn
, 52, 44);
459 WMSetButtonAction(panel
->slidersBtn
, modeButtonCallback
, panel
);
460 WMSetButtonImagePosition(panel
->slidersBtn
, WIPImageOnly
);
461 WMSetButtonImage(panel
->slidersBtn
, scrPtr
->rgbIcon
);
463 panel
->customPaletteBtn
= WMCreateCustomButton(panel
->win
,
464 WBBStateLightMask
|WBBStateChangeMask
);
465 WMResizeWidget(panel
->customPaletteBtn
, 46, 32);
466 WMMoveWidget(panel
->customPaletteBtn
, 98, 44);
467 WMSetButtonAction(panel
->customPaletteBtn
, modeButtonCallback
, panel
);
468 WMSetButtonImagePosition(panel
->customPaletteBtn
, WIPImageOnly
);
469 WMSetButtonImage(panel
->customPaletteBtn
, scrPtr
->customPaletteIcon
);
471 panel
->colorListBtn
= WMCreateCustomButton(panel
->win
,
472 WBBStateLightMask
|WBBStateChangeMask
);
473 WMResizeWidget(panel
->colorListBtn
, 46, 32);
474 WMMoveWidget(panel
->colorListBtn
, 144, 44);
475 WMSetButtonAction(panel
->colorListBtn
, modeButtonCallback
, panel
);
476 WMSetButtonImagePosition(panel
->colorListBtn
, WIPImageOnly
);
477 WMSetButtonImage(panel
->colorListBtn
, scrPtr
->colorListIcon
);
479 /* Let's Group some of them together */
480 WMGroupButtons(panel
->wheelBtn
, panel
->slidersBtn
);
481 WMGroupButtons(panel
->wheelBtn
, panel
->customPaletteBtn
);
482 WMGroupButtons(panel
->wheelBtn
, panel
->colorListBtn
);
484 /* Widgets for the ColorWheel Panel */
485 panel
->wheelFrm
= WMCreateFrame(panel
->win
);
486 WMSetFrameRelief(panel
->wheelFrm
, WRFlat
);
487 WMResizeWidget(panel
->wheelFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
488 WMMoveWidget(panel
->wheelFrm
, 5, 80);
490 panel
->wheelView
= W_CreateView(W_VIEW(panel
->wheelFrm
));
491 /* XXX Can we create a view ? */
492 W_ResizeView(panel
->wheelView
, colorWheelSize
+4, colorWheelSize
+4);
493 W_MoveView(panel
->wheelView
, 0, 0);
495 /* Create an event handler to handle expose/click events in ColorWheel */
496 WMCreateEventHandler(panel
->wheelView
,
497 ButtonPressMask
|ButtonReleaseMask
|EnterWindowMask
|
498 LeaveWindowMask
|ButtonMotionMask
, wheelHandleActionEvents
, panel
);
500 WMCreateEventHandler(panel
->wheelView
, ExposureMask
, wheelHandleEvents
,
503 panel
->wheelBrightnessS
= WMCreateSlider(panel
->wheelFrm
);
504 WMResizeWidget(panel
->wheelBrightnessS
, 16, 153);
505 WMMoveWidget(panel
->wheelBrightnessS
, 5+colorWheelSize
+14, 1);
506 WMSetSliderMinValue(panel
->wheelBrightnessS
, 0);
507 WMSetSliderMaxValue(panel
->wheelBrightnessS
, 255);
508 WMSetSliderAction(panel
->wheelBrightnessS
, wheelBrightnessSliderCallback
,
510 WMSetSliderKnobThickness(panel
->wheelBrightnessS
, knobThickness
);
512 panel
->wheelMtrx
= wheelCreateMatrix(colorWheelSize
+4, colorWheelSize
+4);
513 wheelInitMatrix(panel
);
516 /* Widgets for the Slider Panels */
517 panel
->slidersFrm
= WMCreateFrame(panel
->win
);
518 WMSetFrameRelief(panel
->slidersFrm
, WRFlat
);
519 WMResizeWidget(panel
->slidersFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
520 WMMoveWidget(panel
->slidersFrm
, 4, 80);
522 panel
->seperatorFrm
= WMCreateFrame(panel
->slidersFrm
);
523 WMSetFrameRelief(panel
->seperatorFrm
, WRPushed
);
524 WMResizeWidget(panel
->seperatorFrm
, PWIDTH
- 8, 2);
525 WMMoveWidget(panel
->seperatorFrm
, 0, 1);
527 panel
->grayBtn
= WMCreateCustomButton(panel
->slidersFrm
,
528 WBBStateLightMask
|WBBStateChangeMask
);
529 WMResizeWidget(panel
->grayBtn
, 46, 24);
530 WMMoveWidget(panel
->grayBtn
, 1, 8);
531 WMSetButtonAction(panel
->grayBtn
, modeButtonCallback
, panel
);
532 WMSetButtonImagePosition(panel
->grayBtn
, WIPImageOnly
);
533 WMSetButtonImage(panel
->grayBtn
, scrPtr
->grayIcon
);
535 panel
->rgbBtn
= WMCreateCustomButton(panel
->slidersFrm
,
536 WBBStateLightMask
|WBBStateChangeMask
);
537 WMResizeWidget(panel
->rgbBtn
, 46, 24);
538 WMMoveWidget(panel
->rgbBtn
, 47, 8);
539 WMSetButtonAction(panel
->rgbBtn
, modeButtonCallback
, panel
);
540 WMSetButtonImagePosition(panel
->rgbBtn
, WIPImageOnly
);
541 WMSetButtonImage(panel
->rgbBtn
, scrPtr
->rgbIcon
);
543 panel
->cmykBtn
= WMCreateCustomButton(panel
->slidersFrm
,
544 WBBStateLightMask
|WBBStateChangeMask
);
545 WMResizeWidget(panel
->cmykBtn
, 46, 24);
546 WMMoveWidget(panel
->cmykBtn
, 93, 8);
547 WMSetButtonAction(panel
->cmykBtn
, modeButtonCallback
, panel
);
548 WMSetButtonImagePosition(panel
->cmykBtn
, WIPImageOnly
);
549 WMSetButtonImage(panel
->cmykBtn
, scrPtr
->cmykIcon
);
551 panel
->hsbBtn
= WMCreateCustomButton(panel
->slidersFrm
,
552 WBBStateLightMask
|WBBStateChangeMask
);
553 WMResizeWidget(panel
->hsbBtn
, 46, 24);
554 WMMoveWidget(panel
->hsbBtn
, 139, 8);
555 WMSetButtonAction(panel
->hsbBtn
, modeButtonCallback
, panel
);
556 WMSetButtonImagePosition(panel
->hsbBtn
, WIPImageOnly
);
557 WMSetButtonImage(panel
->hsbBtn
, scrPtr
->hsbIcon
);
559 /* Let's Group the Slider Panel Buttons Together */
560 WMGroupButtons(panel
->grayBtn
, panel
->rgbBtn
);
561 WMGroupButtons(panel
->grayBtn
, panel
->cmykBtn
);
562 WMGroupButtons(panel
->grayBtn
, panel
->hsbBtn
);
564 textcolor
= WMDarkGrayColor(scrPtr
);
566 /* Widgets for GrayScale Panel */
567 panel
->grayFrm
= WMCreateFrame(panel
->slidersFrm
);
568 WMSetFrameRelief(panel
->grayFrm
, WRFlat
);
569 WMResizeWidget(panel
->grayFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
570 WMMoveWidget(panel
->grayFrm
, 0, 34);
572 panel
->grayMinL
= WMCreateLabel(panel
->grayFrm
);
573 WMResizeWidget(panel
->grayMinL
, 20, 10);
574 WMMoveWidget(panel
->grayMinL
, 2, 2);
575 WMSetLabelText(panel
->grayMinL
, "0");
576 WMSetLabelTextAlignment(panel
->grayMinL
, WALeft
);
577 WMSetLabelTextColor(panel
->grayMinL
, textcolor
);
578 WMSetLabelFont(panel
->grayMinL
, panel
->font8
);
580 panel
->grayMaxL
= WMCreateLabel(panel
->grayFrm
);
581 WMResizeWidget(panel
->grayMaxL
, 40, 10);
582 WMMoveWidget(panel
->grayMaxL
, 104, 2);
583 WMSetLabelText(panel
->grayMaxL
, "100");
584 WMSetLabelTextAlignment(panel
->grayMaxL
, WARight
);
585 WMSetLabelTextColor(panel
->grayMaxL
, textcolor
);
586 WMSetLabelFont(panel
->grayMaxL
, panel
->font8
);
588 panel
->grayBrightnessS
= WMCreateSlider(panel
->grayFrm
);
589 WMResizeWidget(panel
->grayBrightnessS
, 141, 16);
590 WMMoveWidget(panel
->grayBrightnessS
, 2, 14);
591 WMSetSliderMinValue(panel
->grayBrightnessS
, 0);
592 WMSetSliderMaxValue(panel
->grayBrightnessS
, 100);
593 WMSetSliderKnobThickness(panel
->grayBrightnessS
, knobThickness
);
594 WMSetSliderAction(panel
->grayBrightnessS
, grayBrightnessSliderCallback
,
605 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
606 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
607 RReleaseImage(image
);
610 W_PaintText(W_VIEW(panel
->grayBrightnessS
), pixmap
->pixmap
,
611 panel
->font12
, 2, 0, 100, WALeft
, WMColorGC(scrPtr
->white
),
612 False
, "Brightness", strlen("Brightness"));
614 wwarning(NO_MEMORY_ERR
);
616 WMSetSliderImage(panel
->grayBrightnessS
, pixmap
);
617 WMReleasePixmap(pixmap
);
619 panel
->grayBrightnessT
= WMCreateTextField(panel
->grayFrm
);
620 WMResizeWidget(panel
->grayBrightnessT
, 40, 18);
621 WMMoveWidget(panel
->grayBrightnessT
, 146, 13);
622 WMSetTextFieldAlignment(panel
->grayBrightnessT
, WALeft
);
623 WMAddNotificationObserver(grayBrightnessTextFieldCallback
, panel
,
624 WMTextDidEndEditingNotification
, panel
->grayBrightnessT
);
626 for (i
=0; i
< 7; i
++) {
627 pixmap
= WMCreatePixmap(scrPtr
, 13, 13, scrPtr
->depth
, False
);
629 graybuttoncolor
= WMCreateRGBColor(scrPtr
, (255/6)*i
<< 8,
630 (255/6)*i
<< 8, (255/6)*i
<< 8, True
);
631 WMPaintColorSwatch(graybuttoncolor
, pixmap
->pixmap
, 0, 0, 15, 15);
632 WMReleaseColor(graybuttoncolor
);
634 panel
->grayPresetBtn
[i
] = WMCreateCommandButton(panel
->grayFrm
);
635 WMResizeWidget(panel
->grayPresetBtn
[i
], 20, 24);
636 WMMoveWidget(panel
->grayPresetBtn
[i
], 2+(i
*20), 34);
637 WMSetButtonAction(panel
->grayPresetBtn
[i
],
638 grayPresetButtonCallback
, panel
);
639 WMSetButtonImage(panel
->grayPresetBtn
[i
], pixmap
);
640 WMSetButtonImagePosition(panel
->grayPresetBtn
[i
], WIPImageOnly
);
641 WMReleasePixmap(pixmap
);
645 /* End of GrayScale Panel */
647 /* Widgets for RGB Panel */
648 panel
->rgbFrm
= WMCreateFrame(panel
->slidersFrm
);
649 WMSetFrameRelief(panel
->rgbFrm
, WRFlat
);
650 WMResizeWidget(panel
->rgbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
651 WMMoveWidget(panel
->rgbFrm
, 0, 34);
653 panel
->rgbMinL
= WMCreateLabel(panel
->rgbFrm
);
654 WMResizeWidget(panel
->rgbMinL
, 20, 10);
655 WMMoveWidget(panel
->rgbMinL
, 2, 2);
656 WMSetLabelText(panel
->rgbMinL
, "0");
657 WMSetLabelTextAlignment(panel
->rgbMinL
, WALeft
);
658 WMSetLabelTextColor(panel
->rgbMinL
, textcolor
);
659 WMSetLabelFont(panel
->rgbMinL
, panel
->font8
);
661 panel
->rgbMaxL
= WMCreateLabel(panel
->rgbFrm
);
662 WMResizeWidget(panel
->rgbMaxL
, 40, 10);
663 WMMoveWidget(panel
->rgbMaxL
, 104, 2);
664 WMSetLabelText(panel
->rgbMaxL
, "255");
665 WMSetLabelTextAlignment(panel
->rgbMaxL
, WARight
);
666 WMSetLabelTextColor(panel
->rgbMaxL
, textcolor
);
667 WMSetLabelFont(panel
->rgbMaxL
, panel
->font8
);
669 panel
->rgbRedS
= WMCreateSlider(panel
->rgbFrm
);
670 WMResizeWidget(panel
->rgbRedS
, 141, 16);
671 WMMoveWidget(panel
->rgbRedS
, 2, 14);
672 WMSetSliderMinValue(panel
->rgbRedS
, 0);
673 WMSetSliderMaxValue(panel
->rgbRedS
, 255);
674 WMSetSliderKnobThickness(panel
->rgbRedS
, knobThickness
);
675 WMSetSliderAction(panel
->rgbRedS
, rgbSliderCallback
, panel
);
681 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
682 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
683 RReleaseImage(image
);
686 W_PaintText(W_VIEW(panel
->rgbRedS
), pixmap
->pixmap
, panel
->font12
,
687 2, 0, 100, WALeft
, WMColorGC(scrPtr
->white
), False
, "Red",
690 wwarning(NO_MEMORY_ERR
);
692 WMSetSliderImage(panel
->rgbRedS
, pixmap
);
693 WMReleasePixmap(pixmap
);
695 panel
->rgbRedT
= WMCreateTextField(panel
->rgbFrm
);
696 WMResizeWidget(panel
->rgbRedT
, 40, 18);
697 WMMoveWidget(panel
->rgbRedT
, 146, 13);
698 WMSetTextFieldAlignment(panel
->rgbRedT
, WALeft
);
699 WMAddNotificationObserver(rgbTextFieldCallback
, panel
,
700 WMTextDidEndEditingNotification
, panel
->rgbRedT
);
702 panel
->rgbGreenS
= WMCreateSlider(panel
->rgbFrm
);
703 WMResizeWidget(panel
->rgbGreenS
, 141, 16);
704 WMMoveWidget(panel
->rgbGreenS
, 2, 36);
705 WMSetSliderMinValue(panel
->rgbGreenS
, 0);
706 WMSetSliderMaxValue(panel
->rgbGreenS
, 255);
707 WMSetSliderKnobThickness(panel
->rgbGreenS
, knobThickness
);
708 WMSetSliderAction(panel
->rgbGreenS
, rgbSliderCallback
, panel
);
714 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
715 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
716 RReleaseImage(image
);
719 W_PaintText(W_VIEW(panel
->rgbGreenS
), pixmap
->pixmap
, panel
->font12
,
720 2, 0, 100, WALeft
, WMColorGC(scrPtr
->white
), False
, "Green",
723 wwarning(NO_MEMORY_ERR
);
725 WMSetSliderImage(panel
->rgbGreenS
, pixmap
);
726 WMReleasePixmap(pixmap
);
728 panel
->rgbGreenT
= WMCreateTextField(panel
->rgbFrm
);
729 WMResizeWidget(panel
->rgbGreenT
, 40, 18);
730 WMMoveWidget(panel
->rgbGreenT
, 146, 35);
731 WMSetTextFieldAlignment(panel
->rgbGreenT
, WALeft
);
732 WMAddNotificationObserver(rgbTextFieldCallback
, panel
,
733 WMTextDidEndEditingNotification
, panel
->rgbGreenT
);
736 panel
->rgbBlueS
= WMCreateSlider(panel
->rgbFrm
);
737 WMResizeWidget(panel
->rgbBlueS
, 141, 16);
738 WMMoveWidget(panel
->rgbBlueS
, 2, 58);
739 WMSetSliderMinValue(panel
->rgbBlueS
, 0);
740 WMSetSliderMaxValue(panel
->rgbBlueS
, 255);
741 WMSetSliderKnobThickness(panel
->rgbBlueS
, knobThickness
);
742 WMSetSliderAction(panel
->rgbBlueS
, rgbSliderCallback
, panel
);
748 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
749 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
750 RReleaseImage(image
);
753 W_PaintText(W_VIEW(panel
->rgbBlueS
), pixmap
->pixmap
, panel
->font12
,
754 2, 0, 100, WALeft
, WMColorGC(scrPtr
->white
), False
, "Blue",
757 wwarning(NO_MEMORY_ERR
);
759 WMSetSliderImage(panel
->rgbBlueS
, pixmap
);
760 WMReleasePixmap(pixmap
);
762 panel
->rgbBlueT
= WMCreateTextField(panel
->rgbFrm
);
763 WMResizeWidget(panel
->rgbBlueT
, 40, 18);
764 WMMoveWidget(panel
->rgbBlueT
, 146, 57);
765 WMSetTextFieldAlignment(panel
->rgbBlueT
, WALeft
);
766 WMAddNotificationObserver(rgbTextFieldCallback
, panel
,
767 WMTextDidEndEditingNotification
, panel
->rgbBlueT
);
768 /* End of RGB Panel */
770 /* Widgets for CMYK Panel */
771 panel
->cmykFrm
= WMCreateFrame(panel
->slidersFrm
);
772 WMSetFrameRelief(panel
->cmykFrm
, WRFlat
);
773 WMResizeWidget(panel
->cmykFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
774 WMMoveWidget(panel
->cmykFrm
, 0, 34);
776 panel
->cmykMinL
= WMCreateLabel(panel
->cmykFrm
);
777 WMResizeWidget(panel
->cmykMinL
, 20, 10);
778 WMMoveWidget(panel
->cmykMinL
, 2, 2);
779 WMSetLabelText(panel
->cmykMinL
, "0");
780 WMSetLabelTextAlignment(panel
->cmykMinL
, WALeft
);
781 WMSetLabelTextColor(panel
->cmykMinL
, textcolor
);
782 WMSetLabelFont(panel
->cmykMinL
, panel
->font8
);
784 panel
->cmykMaxL
= WMCreateLabel(panel
->cmykFrm
);
785 WMResizeWidget(panel
->cmykMaxL
, 40, 10);
786 WMMoveWidget(panel
->cmykMaxL
, 104, 2);
787 WMSetLabelText(panel
->cmykMaxL
, "100");
788 WMSetLabelTextAlignment(panel
->cmykMaxL
, WARight
);
789 WMSetLabelTextColor(panel
->cmykMaxL
, textcolor
);
790 WMSetLabelFont(panel
->cmykMaxL
, panel
->font8
);
792 panel
->cmykCyanS
= WMCreateSlider(panel
->cmykFrm
);
793 WMResizeWidget(panel
->cmykCyanS
, 141, 16);
794 WMMoveWidget(panel
->cmykCyanS
, 2, 14);
795 WMSetSliderMinValue(panel
->cmykCyanS
, 0);
796 WMSetSliderMaxValue(panel
->cmykCyanS
, 100);
797 WMSetSliderKnobThickness(panel
->cmykCyanS
, knobThickness
);
798 WMSetSliderAction(panel
->cmykCyanS
, cmykSliderCallback
, panel
);
808 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
809 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
810 RReleaseImage(image
);
813 W_PaintText(W_VIEW(panel
->cmykCyanS
), pixmap
->pixmap
, panel
->font12
,
814 2, 0, 100, WALeft
, WMColorGC(scrPtr
->black
), False
, "Cyan",
817 wwarning(NO_MEMORY_ERR
);
819 WMSetSliderImage(panel
->cmykCyanS
, pixmap
);
820 WMReleasePixmap(pixmap
);
822 panel
->cmykCyanT
= WMCreateTextField(panel
->cmykFrm
);
823 WMResizeWidget(panel
->cmykCyanT
, 40, 18);
824 WMMoveWidget(panel
->cmykCyanT
, 146, 13);
825 WMSetTextFieldAlignment(panel
->cmykCyanT
, WALeft
);
826 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
827 WMTextDidEndEditingNotification
, panel
->cmykCyanT
);
830 panel
->cmykMagentaS
= WMCreateSlider(panel
->cmykFrm
);
831 WMResizeWidget(panel
->cmykMagentaS
, 141, 16);
832 WMMoveWidget(panel
->cmykMagentaS
, 2, 36);
833 WMSetSliderMinValue(panel
->cmykMagentaS
, 0);
834 WMSetSliderMaxValue(panel
->cmykMagentaS
, 100);
835 WMSetSliderKnobThickness(panel
->cmykMagentaS
, knobThickness
);
836 WMSetSliderAction(panel
->cmykMagentaS
, cmykSliderCallback
, panel
);
842 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
843 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
844 RReleaseImage(image
);
847 W_PaintText(W_VIEW(panel
->cmykMagentaS
), pixmap
->pixmap
, panel
->font12
,
848 2, 0, 100, WALeft
, WMColorGC(scrPtr
->black
), False
, "Magenta",
851 wwarning(NO_MEMORY_ERR
);
853 WMSetSliderImage(panel
->cmykMagentaS
, pixmap
);
854 WMReleasePixmap(pixmap
);
856 panel
->cmykMagentaT
= WMCreateTextField(panel
->cmykFrm
);
857 WMResizeWidget(panel
->cmykMagentaT
, 40, 18);
858 WMMoveWidget(panel
->cmykMagentaT
, 146, 35);
859 WMSetTextFieldAlignment(panel
->cmykMagentaT
, WALeft
);
860 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
861 WMTextDidEndEditingNotification
, panel
->cmykMagentaT
);
864 panel
->cmykYellowS
= WMCreateSlider(panel
->cmykFrm
);
865 WMResizeWidget(panel
->cmykYellowS
, 141, 16);
866 WMMoveWidget(panel
->cmykYellowS
, 2, 58);
867 WMSetSliderMinValue(panel
->cmykYellowS
, 0);
868 WMSetSliderMaxValue(panel
->cmykYellowS
, 100);
869 WMSetSliderKnobThickness(panel
->cmykYellowS
, knobThickness
);
870 WMSetSliderAction(panel
->cmykYellowS
, cmykSliderCallback
, panel
);
876 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
877 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
878 RReleaseImage(image
);
881 W_PaintText(W_VIEW(panel
->cmykYellowS
), pixmap
->pixmap
, panel
->font12
,
882 2, 0, 100, WALeft
, WMColorGC(scrPtr
->black
), False
, "Yellow",
885 wwarning(NO_MEMORY_ERR
);
887 WMSetSliderImage(panel
->cmykYellowS
, pixmap
);
888 WMReleasePixmap(pixmap
);
890 panel
->cmykYellowT
= WMCreateTextField(panel
->cmykFrm
);
891 WMResizeWidget(panel
->cmykYellowT
, 40, 18);
892 WMMoveWidget(panel
->cmykYellowT
, 146, 57);
893 WMSetTextFieldAlignment(panel
->cmykYellowT
, WALeft
);
894 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
895 WMTextDidEndEditingNotification
, panel
->cmykYellowT
);
898 panel
->cmykBlackS
= WMCreateSlider(panel
->cmykFrm
);
899 WMResizeWidget(panel
->cmykBlackS
, 141, 16);
900 WMMoveWidget(panel
->cmykBlackS
, 2, 80);
901 WMSetSliderMinValue(panel
->cmykBlackS
, 0);
902 WMSetSliderMaxValue(panel
->cmykBlackS
, 100);
903 WMSetSliderValue(panel
->cmykBlackS
, 0);
904 WMSetSliderKnobThickness(panel
->cmykBlackS
, knobThickness
);
905 WMSetSliderAction(panel
->cmykBlackS
, cmykSliderCallback
, panel
);
911 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
912 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
913 RReleaseImage(image
);
916 W_PaintText(W_VIEW(panel
->cmykBlackS
), pixmap
->pixmap
, panel
->font12
,
917 2, 0, 100, WALeft
, WMColorGC(scrPtr
->black
), False
, "Black",
920 wwarning(NO_MEMORY_ERR
);
922 WMSetSliderImage(panel
->cmykBlackS
, pixmap
);
923 WMReleasePixmap(pixmap
);
925 panel
->cmykBlackT
= WMCreateTextField(panel
->cmykFrm
);
926 WMResizeWidget(panel
->cmykBlackT
, 40, 18);
927 WMMoveWidget(panel
->cmykBlackT
, 146, 79);
928 WMSetTextFieldAlignment(panel
->cmykBlackT
, WALeft
);
929 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
930 WMTextDidEndEditingNotification
, panel
->cmykBlackT
);
931 /* End of CMYK Panel */
933 /* Widgets for HSB Panel */
934 panel
->hsbFrm
= WMCreateFrame(panel
->slidersFrm
);
935 WMSetFrameRelief(panel
->hsbFrm
, WRFlat
);
936 WMResizeWidget(panel
->hsbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
937 WMMoveWidget(panel
->hsbFrm
, 0, 34);
939 panel
->hsbHueS
= WMCreateSlider(panel
->hsbFrm
);
940 WMResizeWidget(panel
->hsbHueS
, 141, 16);
941 WMMoveWidget(panel
->hsbHueS
, 2, 14);
942 WMSetSliderMinValue(panel
->hsbHueS
, 0);
943 WMSetSliderMaxValue(panel
->hsbHueS
, 359);
944 WMSetSliderKnobThickness(panel
->hsbHueS
, knobThickness
);
945 WMSetSliderAction(panel
->hsbHueS
, hsbSliderCallback
, panel
);
947 panel
->hsbHueT
= WMCreateTextField(panel
->hsbFrm
);
948 WMResizeWidget(panel
->hsbHueT
, 40, 18);
949 WMMoveWidget(panel
->hsbHueT
, 146, 13);
950 WMSetTextFieldAlignment(panel
->hsbHueT
, WALeft
);
951 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
952 WMTextDidEndEditingNotification
, panel
->hsbHueT
);
955 panel
->hsbSaturationS
= WMCreateSlider(panel
->hsbFrm
);
956 WMResizeWidget(panel
->hsbSaturationS
, 141, 16);
957 WMMoveWidget(panel
->hsbSaturationS
, 2, 36);
958 WMSetSliderMinValue(panel
->hsbSaturationS
, 0);
959 WMSetSliderMaxValue(panel
->hsbSaturationS
, 100);
960 WMSetSliderKnobThickness(panel
->hsbSaturationS
, knobThickness
);
961 WMSetSliderAction(panel
->hsbSaturationS
, hsbSliderCallback
, panel
);
963 panel
->hsbSaturationT
= WMCreateTextField(panel
->hsbFrm
);
964 WMResizeWidget(panel
->hsbSaturationT
, 40, 18);
965 WMMoveWidget(panel
->hsbSaturationT
, 146, 35);
966 WMSetTextFieldAlignment(panel
->hsbSaturationT
, WALeft
);
967 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
968 WMTextDidEndEditingNotification
, panel
->hsbSaturationT
);
971 panel
->hsbBrightnessS
= WMCreateSlider(panel
->hsbFrm
);
972 WMResizeWidget(panel
->hsbBrightnessS
, 141, 16);
973 WMMoveWidget(panel
->hsbBrightnessS
, 2, 58);
974 WMSetSliderMinValue(panel
->hsbBrightnessS
, 0);
975 WMSetSliderMaxValue(panel
->hsbBrightnessS
, 100);
976 WMSetSliderKnobThickness(panel
->hsbBrightnessS
, knobThickness
);
977 WMSetSliderAction(panel
->hsbBrightnessS
, hsbSliderCallback
, panel
);
979 panel
->hsbBrightnessT
= WMCreateTextField(panel
->hsbFrm
);
980 WMResizeWidget(panel
->hsbBrightnessT
, 40, 18);
981 WMMoveWidget(panel
->hsbBrightnessT
, 146, 57);
982 WMSetTextFieldAlignment(panel
->hsbBrightnessT
, WALeft
);
983 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
984 WMTextDidEndEditingNotification
, panel
->hsbBrightnessT
);
985 /* End of HSB Panel */
988 WMReleaseColor(textcolor
);
990 /* Widgets for the CustomPalette Panel */
991 panel
->customPaletteFrm
= WMCreateFrame(panel
->win
);
992 WMSetFrameRelief(panel
->customPaletteFrm
, WRFlat
);
993 WMResizeWidget(panel
->customPaletteFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
994 WMMoveWidget(panel
->customPaletteFrm
, 5, 80);
996 panel
->customPaletteHistoryBtn
= WMCreatePopUpButton(
997 panel
->customPaletteFrm
);
998 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, "Spectrum");
999 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
1000 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
)-1);
1001 WMSetPopUpButtonAction(panel
->customPaletteHistoryBtn
,
1002 customPaletteHistoryCallback
, panel
);
1003 WMResizeWidget(panel
->customPaletteHistoryBtn
, PWIDTH
- 8, 20);
1004 WMMoveWidget(panel
->customPaletteHistoryBtn
, 0, 0);
1006 panel
->customPaletteContentFrm
= WMCreateFrame(panel
->customPaletteFrm
);
1007 WMSetFrameRelief(panel
->customPaletteContentFrm
, WRSunken
);
1008 WMResizeWidget(panel
->customPaletteContentFrm
, PWIDTH
- 8, PHEIGHT
- 156);
1009 WMMoveWidget(panel
->customPaletteContentFrm
, 0, 23);
1011 panel
->customPaletteContentView
= W_CreateView(
1012 W_VIEW(panel
->customPaletteContentFrm
));
1013 /* XXX Test if we can create a view */
1014 W_ResizeView(panel
->customPaletteContentView
, customPaletteWidth
,
1015 customPaletteHeight
);
1016 W_MoveView(panel
->customPaletteContentView
, 2, 2);
1018 /* Create event handler to handle expose/click events in CustomPalette */
1019 WMCreateEventHandler(panel
->customPaletteContentView
,
1020 ButtonPressMask
|ButtonReleaseMask
|EnterWindowMask
| LeaveWindowMask
|
1021 ButtonMotionMask
, customPaletteHandleActionEvents
, panel
);
1023 WMCreateEventHandler(panel
->customPaletteContentView
, ExposureMask
,
1024 customPaletteHandleEvents
, panel
);
1026 panel
->customPaletteMenuBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
1027 WMSetPopUpButtonPullsDown(panel
->customPaletteMenuBtn
, 1);
1028 WMSetPopUpButtonText(panel
->customPaletteMenuBtn
, "Palette");
1029 WMSetPopUpButtonAction(panel
->customPaletteMenuBtn
,
1030 customPaletteMenuCallback
, panel
);
1031 WMResizeWidget(panel
->customPaletteMenuBtn
, PWIDTH
- 8, 20);
1032 WMMoveWidget(panel
->customPaletteMenuBtn
, 0, PHEIGHT
- 130);
1034 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "New from File...");
1035 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "Rename...");
1036 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "Remove");
1037 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "Copy");
1038 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, "New from Clipboard");
1040 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, 0);
1041 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, 0);
1042 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuCopy
, 0);
1043 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
,
1044 CPmenuNewFromClipboard
, 0);
1046 customRenderSpectrum(panel
);
1047 panel
->currentPalette
= 0;
1048 panel
->palx
= customPaletteWidth
/2;
1049 panel
->paly
= customPaletteHeight
/2;
1052 /* Widgets for the ColorList Panel */
1053 panel
->colorListFrm
= WMCreateFrame(panel
->win
);
1054 WMSetFrameRelief(panel
->colorListFrm
, WRFlat
);
1055 WMResizeWidget(panel
->colorListFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
1056 WMMoveWidget(panel
->colorListFrm
, 5, 80);
1058 panel
->colorListHistoryBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1059 WMAddPopUpButtonItem(panel
->colorListHistoryBtn
, "X11-Colors");
1060 WMSetPopUpButtonSelectedItem(panel
->colorListHistoryBtn
,
1061 WMGetPopUpButtonNumberOfItems(panel
->colorListHistoryBtn
)-1);
1062 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
1063 * colorListHistoryCallback, panel); */
1064 WMResizeWidget(panel
->colorListHistoryBtn
, PWIDTH
- 8, 20);
1065 WMMoveWidget(panel
->colorListHistoryBtn
, 0, 0);
1067 panel
->colorListContentLst
= WMCreateList(panel
->colorListFrm
);
1068 WMSetListAction(panel
->colorListContentLst
, colorListSelect
, panel
);
1069 WMSetListUserDrawProc(panel
->colorListContentLst
, colorListPaintItem
);
1070 WMResizeWidget(panel
->colorListContentLst
, PWIDTH
- 8, PHEIGHT
- 156);
1071 WMMoveWidget(panel
->colorListContentLst
, 0, 23);
1072 WMHangData(panel
->colorListContentLst
, panel
);
1074 panel
->colorListColorMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1075 WMSetPopUpButtonPullsDown(panel
->colorListColorMenuBtn
, 1);
1076 WMSetPopUpButtonText(panel
->colorListColorMenuBtn
, "Color");
1077 WMSetPopUpButtonAction(panel
->colorListColorMenuBtn
,
1078 colorListColorMenuCallback
, panel
);
1079 WMResizeWidget(panel
->colorListColorMenuBtn
, (PWIDTH
- 16)/2, 20);
1080 WMMoveWidget(panel
->colorListColorMenuBtn
, 0, PHEIGHT
- 130);
1082 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, "Add...");
1083 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, "Rename...");
1084 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, "Remove");
1086 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuAdd
, 0);
1087 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRename
, 0);
1088 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRemove
, 0);
1090 panel
->colorListListMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1091 WMSetPopUpButtonPullsDown(panel
->colorListListMenuBtn
, 1);
1092 WMSetPopUpButtonText(panel
->colorListListMenuBtn
, "List");
1093 WMSetPopUpButtonAction(panel
->colorListListMenuBtn
,
1094 colorListListMenuCallback
, panel
);
1095 WMResizeWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16)/2, 20);
1096 WMMoveWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16)/2 + 8,
1099 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, "New...");
1100 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, "Rename...");
1101 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, "Remove");
1103 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuAdd
, 0);
1104 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRename
, 0);
1105 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRemove
, 0);
1107 WMRealizeWidget(panel
->win
);
1108 WMMapSubwidgets(panel
->win
);
1110 WMMapSubwidgets(panel
->wheelFrm
);
1111 WMMapSubwidgets(panel
->slidersFrm
);
1112 WMMapSubwidgets(panel
->grayFrm
);
1113 WMMapSubwidgets(panel
->rgbFrm
);
1114 WMMapSubwidgets(panel
->cmykFrm
);
1115 WMMapSubwidgets(panel
->hsbFrm
);
1116 WMMapSubwidgets(panel
->customPaletteFrm
);
1117 WMMapSubwidgets(panel
->customPaletteContentFrm
);
1118 WMMapSubwidgets(panel
->colorListFrm
);
1120 /* Pixmap to indicate selection positions
1121 * wheelframe MUST be mapped.
1123 panel
->selectionImg
= XCreatePixmap(scrPtr
->display
,
1124 WMWidgetXID(panel
->win
), 4, 4, scrPtr
->depth
);
1125 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, bgc
, 0, 0, 4, 4);
1126 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, wgc
, 1, 1, 2, 2);
1128 readConfiguration(panel
);
1136 WMGetColorPanel(WMScreen
*scrPtr
)
1138 WMColorPanel
*panel
;
1140 if (scrPtr
->sharedColorPanel
)
1141 return scrPtr
->sharedColorPanel
;
1143 panel
= makeColorPanel(scrPtr
, "colorPanel");
1145 scrPtr
->sharedColorPanel
= panel
;
1152 WMFreeColorPanel(WMColorPanel
*panel
)
1154 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1156 if (panel
== scr
->sharedColorPanel
) {
1157 scr
->sharedColorPanel
= NULL
;
1163 WMRemoveNotificationObserver(panel
);
1164 WMUnmapWidget(panel
->win
);
1167 WMReleaseFont(panel
->font8
);
1168 WMReleaseFont(panel
->font12
);
1171 wheelDestroyMatrix(panel
->wheelMtrx
);
1172 if (panel
->wheelImg
)
1173 XFreePixmap(scr
->display
, panel
->wheelImg
);
1174 if (panel
->selectionImg
)
1175 XFreePixmap(scr
->display
, panel
->selectionImg
);
1176 if (panel
->selectionBackImg
)
1177 XFreePixmap(scr
->display
, panel
->selectionBackImg
);
1178 RReleaseImage(panel
->customPaletteImg
);
1181 if (panel
->lastBrowseDir
)
1182 wfree(panel
->lastBrowseDir
);
1183 if (panel
->configurationPath
)
1184 wfree(panel
->configurationPath
);
1186 WMDestroyWidget(panel
->win
);
1193 WMCloseColorPanel(WMColorPanel
*panel
)
1195 WMFreeColorPanel(panel
);
1200 WMShowColorPanel(WMColorPanel
*panel
)
1202 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1203 WMColor
*white
= WMWhiteColor(scr
);
1205 if (panel
->color
.set
== cpNone
)
1206 WMSetColorPanelColor(panel
, white
);
1207 WMReleaseColor(white
);
1209 if (panel
->mode
!= WMWheelModeColorPanel
)
1210 WMPerformButtonClick(panel
->wheelBtn
);
1212 WMMapWidget(panel
->win
);
1217 closeWindowCallback(WMWidget
*w
, void *data
)
1219 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
1221 WMCloseColorPanel(panel
);
1226 readConfiguration(W_ColorPanel
*panel
)
1228 /* XXX Doesn't take care of "invalid" files */
1232 struct stat stat_buf
;
1235 if (stat(panel
->configurationPath
, &stat_buf
)!=0) {
1236 if (mkdir(panel
->configurationPath
,
1237 S_IRWXU
|S_IRGRP
|S_IROTH
|S_IXGRP
|S_IXOTH
)!=0) {
1238 wsyserror("Color Panel: Could not create directory %s needed"
1239 " to store configurations", panel
->configurationPath
);
1240 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1241 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1242 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1243 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1245 "Could not create ColorPanel configuration directory",
1251 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1252 wwarning(NO_FILE_ERR
, "%s", panel
->configurationPath
);
1256 while ((dp
= readdir(dPtr
)) != NULL
) {
1257 unsigned int perm_mask
;
1258 char *path
= wstrconcat(panel
->configurationPath
,
1261 if (dp
->d_name
[0] != '.') {
1262 item
= WMGetPopUpButtonNumberOfItems(
1263 panel
->customPaletteHistoryBtn
);
1264 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1266 perm_mask
= (access(path
, R_OK
) == 0);
1267 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
,
1272 (void)closedir(dPtr
);
1277 readXColors(W_ColorPanel
*panel
)
1279 struct stat stat_buf
;
1281 char line
[MAX_LENGTH
];
1282 int red
, green
, blue
;
1287 if (stat(RGBTXT
, &stat_buf
) != 0) {
1288 wsyserror(NO_FILE_ERR
, " %s", RGBTXT
);
1292 if ((rgbtxt
= fopen(RGBTXT
, "r"))) {
1293 while (fgets(line
, MAX_LENGTH
, rgbtxt
)) {
1294 if (sscanf(line
, "%d%d%d %[^\n]", &red
, &green
, &blue
, name
)) {
1295 color
= wmalloc(sizeof(RColor
));
1296 color
->red
= (unsigned char)red
;
1297 color
->green
= (unsigned char)green
;
1298 color
->blue
= (unsigned char)blue
;
1299 item
= WMAddListItem(panel
->colorListContentLst
, name
);
1300 item
->clientData
= (void *)color
;
1306 wsyserror(NO_FILE_ERR
, "%s", RGBTXT
);
1313 WMSetColorPanelPickerMode(WMColorPanel
*panel
, WMColorPanelMode mode
)
1315 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1317 if (mode
!= WMWheelModeColorPanel
) {
1318 WMUnmapWidget(panel
->wheelFrm
);
1319 if (panel
->selectionBackImg
) {
1320 XFreePixmap(WMWidgetScreen(panel
->win
)->display
,
1321 panel
->selectionBackImg
);
1322 panel
->selectionBackImg
= None
;
1325 if (mode
!= WMGrayModeColorPanel
)
1326 WMUnmapWidget(panel
->grayFrm
);
1327 if (mode
!= WMRGBModeColorPanel
)
1328 WMUnmapWidget(panel
->rgbFrm
);
1329 if (mode
!= WMCMYKModeColorPanel
)
1330 WMUnmapWidget(panel
->cmykFrm
);
1331 if (mode
!= WMHSBModeColorPanel
)
1332 WMUnmapWidget(panel
->hsbFrm
);
1333 if (mode
!= WMCustomPaletteModeColorPanel
) {
1334 WMUnmapWidget(panel
->customPaletteFrm
);
1335 if (panel
->selectionBackImg
) {
1336 XFreePixmap(WMWidgetScreen(panel
->win
)->display
,
1337 panel
->selectionBackImg
);
1338 panel
->selectionBackImg
= None
;
1341 if (mode
!= WMColorListModeColorPanel
)
1342 WMUnmapWidget(panel
->colorListFrm
);
1343 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1344 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1345 WMUnmapWidget(panel
->slidersFrm
);
1347 panel
->slidersmode
= mode
;
1349 if (mode
== WMWheelModeColorPanel
) {
1350 WMMapWidget(panel
->wheelFrm
);
1351 WMSetButtonSelected(panel
->wheelBtn
, True
);
1352 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1356 } else if (mode
== WMGrayModeColorPanel
) {
1357 WMMapWidget(panel
->slidersFrm
);
1358 WMSetButtonSelected(panel
->slidersBtn
, True
);
1359 WMMapWidget(panel
->grayFrm
);
1360 WMSetButtonSelected(panel
->grayBtn
, True
);
1361 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1362 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1364 } else if (mode
== WMRGBModeColorPanel
) {
1365 WMMapWidget(panel
->slidersFrm
);
1366 WMSetButtonSelected(panel
->slidersBtn
, True
);
1367 WMMapWidget(panel
->rgbFrm
);
1368 WMSetButtonSelected(panel
->rgbBtn
, True
);
1369 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1370 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1372 } else if (mode
== WMCMYKModeColorPanel
) {
1373 WMMapWidget(panel
->slidersFrm
);
1374 WMSetButtonSelected(panel
->slidersBtn
, True
);
1375 WMMapWidget(panel
->cmykFrm
);
1376 WMSetButtonSelected(panel
->cmykBtn
, True
);
1377 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1378 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1380 } else if (mode
== WMHSBModeColorPanel
) {
1381 WMMapWidget(panel
->slidersFrm
);
1382 WMSetButtonSelected(panel
->slidersBtn
, True
);
1383 WMMapWidget(panel
->hsbFrm
);
1384 WMSetButtonSelected(panel
->hsbBtn
, True
);
1385 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1386 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1388 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1389 WMMapWidget(panel
->customPaletteFrm
);
1390 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1391 customSetPalette(panel
);
1392 } else if (mode
== WMColorListModeColorPanel
) {
1393 WMMapWidget(panel
->colorListFrm
);
1394 WMSetButtonSelected(panel
->colorListBtn
, True
);
1402 WMGetColorPanelColor(WMColorPanel
*panel
)
1404 return WMGetColorWellColor(panel
->colorWell
);
1409 WMSetColorPanelColor(WMColorPanel
*panel
, WMColor
*color
)
1411 WMSetColorWellColor(panel
->colorWell
, color
);
1413 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1414 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1415 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1416 panel
->color
.set
= cpRGB
;
1418 if (panel
->mode
== panel
->lastChanged
)
1419 panel
->lastChanged
= 0;
1421 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1426 updateSwatch(WMColorPanel
*panel
, CPColor color
)
1428 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1431 if (color
.set
!= cpRGB
)
1432 convertCPColor(&color
);
1434 panel
->color
= color
;
1436 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8,
1437 color
.rgb
.green
<< 8,
1438 color
.rgb
.blue
<< 8, True
);
1440 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1441 WMReleaseColor(wellcolor
);
1443 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1445 (*panel
->action
)(panel
, panel
->clientData
);
1447 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
,
1453 modeButtonCallback(WMWidget
*w
, void *data
)
1455 W_ColorPanel
*panel
= (W_ColorPanel
*)(data
);
1457 if (w
== panel
->wheelBtn
)
1458 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1459 else if (w
== panel
->slidersBtn
)
1460 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1461 else if (w
== panel
->customPaletteBtn
)
1462 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1463 else if (w
== panel
->colorListBtn
)
1464 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1465 else if (w
== panel
->grayBtn
)
1466 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1467 else if (w
== panel
->rgbBtn
)
1468 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1469 else if (w
== panel
->cmykBtn
)
1470 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1471 else if (w
== panel
->hsbBtn
)
1472 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1476 /****************** Magnifying Cursor Functions *******************/
1479 magnifyGetImage(WMScreen
*scr
, XImage
*image
, int x
, int y
, int w
, int h
)
1481 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1482 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1483 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1485 if (!(image
&& image
->data
)) {
1486 /* The image in panel->magnifyGlass->image does not exist yet.
1487 * Grab one from the screen (not beyond) and use it from now on.
1489 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1492 w
, h
, AllPlanes
, ZPixmap
)))
1498 /* Coordinate correction for back pixmap
1499 * if magnifying glass is at screen-borders
1502 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1503 * Hatched area is beyond screen border.
1505 * |<-Cursor_x_hot->|
1506 * ________________|_____
1507 * |/ / / / / / /| | |
1508 * | / / / / / / |(x,y) |
1509 * |/_/_/_/_/_/_/|________|
1510 * |<----x0----->|<--w0-->|
1514 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1516 * Hatched area is beyond screen border
1518 * |<-Cursor_x_hot->|
1519 * ________________|_______________
1520 * | | | / / / / / /|
1521 * | (x,y)|/ / / / / / |
1522 * |___________________|_/_/_/_/_/_/|
1523 * |<-------w0-------->| |
1524 * |<---------------w--|----------->|
1529 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1530 x0
= Cursor_x_hot
- x
;
1534 if (displayWidth
-1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1535 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1538 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1539 y0
= Cursor_y_hot
- y
;
1543 if (displayHeight
-1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1544 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1546 /* end of coordinate correction */
1549 /* Grab an image from the screen, clipped if necessary,
1550 * and put it in the existing panel->magnifyGlass->image
1551 * with the corresponding clipping offset.
1553 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1554 x
- Cursor_x_hot
+ x0
,
1555 y
- Cursor_y_hot
+ y0
,
1556 w0
, h0
, AllPlanes
, ZPixmap
,
1565 magnifyGetImageStored(WMColorPanel
*panel
, int x1
, int y1
, int x2
, int y2
)
1567 /* (x1, y1) = topleft corner of existing rectangle
1568 * (x2, y2) = topleft corner of new position
1571 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1572 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1574 const int dx
= abs(x2
- x1
),
1577 const int x_min
= Cursor_x_hot
,
1578 y_min
= Cursor_y_hot
,
1579 x_max
= DisplayWidth(scr
->display
, scr
->screen
) -1 -
1580 (Cursor_mask_width
- Cursor_x_hot
),
1581 y_max
= DisplayHeight(scr
->display
, scr
->screen
) -1 -
1582 (Cursor_mask_height
- Cursor_y_hot
);
1584 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1585 return; /* No movement */
1597 width
= Cursor_mask_width
- dx
;
1598 height
= Cursor_mask_height
- dy
;
1600 /* If the traversed distance is larger than the size of the magnifying
1601 * glass contents, there is no need to do dirty rectangles. A whole new
1602 * rectangle can be grabbed (unless that rectangle falls partially
1604 * Destroying the image and setting it to NULL will achieve that later on.
1606 * Of course, grabbing an XImage beyond the borders of the screen will
1607 * cause trouble, this is considdered a special case. Part of the screen
1608 * is grabbed, but there is no need for dirty rectangles.
1610 if ((width
<= 0) || (height
<= 0)) {
1611 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1612 if (panel
->magnifyGlass
->image
)
1613 XDestroyImage(panel
->magnifyGlass
->image
);
1614 panel
->magnifyGlass
->image
= NULL
;
1617 if (panel
->magnifyGlass
->image
) {
1618 /* Get dirty rectangle from panel->magnifyGlass->image */
1619 panel
->magnifyGlass
->dirtyRect
=
1620 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1621 if (!panel
->magnifyGlass
->dirtyRect
) {
1623 return; /* X returned a NULL from XSubImage */
1628 /* Get image from screen */
1629 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
,
1630 Cursor_mask_width
, Cursor_mask_height
);
1631 if (image
) { /* Only reassign if a *new* image was grabbed */
1632 panel
->magnifyGlass
->image
= image
;
1636 /* Copy previously stored rectangle on covered part of image */
1637 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1640 /* "width" and "height" are used as coordinates here,
1641 * and run from [0...width-1] and [0...height-1] respectively.
1645 old_height
= height
;
1647 for (; width
>= 0; width
--)
1648 for (height
= old_height
; height
>= 0; height
--)
1649 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1650 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1651 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1652 panel
->magnifyGlass
->dirtyRect
= NULL
;
1660 magnifyCreatePixmap(WMColorPanel
*panel
)
1662 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1667 unsigned long color
;
1669 if (!panel
->magnifyGlass
->image
)
1672 if (!panel
->magnifyGlass
->magPix
)
1676 * Copy an area of only 5x5 pixels from the center of the image.
1678 for (u
= 0; u
< 5; u
++) {
1679 for (v
= 0; v
< 5; v
++) {
1680 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1682 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1684 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1685 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1687 /* The center square must eventually be centered around the
1688 * hotspot. The image needs shifting to achieve this. The amount of
1689 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1692 * ^------- center of center square == Cursor_x_hot
1694 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1696 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1697 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1702 return panel
->magnifyGlass
->magPix
;
1704 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
,
1705 Cursor_mask_height
, scr
->depth
);
1709 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1710 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1712 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1713 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1714 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1715 /* (2,2) puts center pixel on center of glass */
1724 magnifyCreateView(W_ColorPanel
*panel
)
1726 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1729 magView
= W_CreateTopView(scr
);
1733 magView
->self
= panel
->win
;
1734 magView
->flags
.topLevel
= 1;
1735 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1736 magView
->attribs
.override_redirect
= True
;
1737 magView
->attribs
.save_under
= True
;
1739 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1741 W_RealizeView(magView
);
1748 magnifyGrabPointer(W_ColorPanel
*panel
)
1750 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1751 Pixmap magPixmap
, magPixmap2
;
1753 XColor fgColor
= {0, 0,0,0, DoRed
|DoGreen
|DoBlue
};
1754 XColor bgColor
= {0, 0xbf00, 0xa000, 0x5000, DoRed
|DoGreen
|DoBlue
};
1756 /* Cursor creation stuff */
1757 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1758 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1759 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1760 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1762 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1763 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1765 XFreePixmap(scr
->display
, magPixmap
);
1766 XFreePixmap(scr
->display
, magPixmap2
);
1768 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1770 /* Set up Pointer */
1771 XGrabPointer (scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1772 PointerMotionMask
| ButtonPressMask
,
1773 GrabModeAsync
, GrabModeAsync
,
1774 scr
->rootWin
, magCursor
, CurrentTime
);
1781 magnifyInitialize(W_ColorPanel
*panel
)
1783 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1786 Pixmap pixmap
, clip_mask
;
1788 Window root_return
, child_return
;
1790 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1791 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1793 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1794 5*5 -1, 5*5 -1, scr
->depth
);
1796 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
,
1797 &x
, &y
, &u
, &v
, &mask
);
1799 panel
->magnifyGlass
->image
= NULL
;
1801 /* Clipmask to make magnified view-contents circular */
1803 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1804 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1806 /* Clip circle in glass cursor */
1807 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1808 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1811 XFreePixmap(scr
->display
, clip_mask
);
1813 /* Draw initial magnifying glass contents */
1814 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1816 pixmap
= magnifyCreatePixmap(panel
);
1817 XSetWindowBackgroundPixmap(scr
->display
,
1818 WMViewXID(panel
->magnifyGlass
->view
),
1820 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1821 XFlush(scr
->display
);
1824 XFreePixmap(scr
->display
, pixmap
);
1835 magnifyPutCursor(WMWidget
*w
, void *data
)
1837 W_ColorPanel
*panel
= (W_ColorPanel
*)(data
);
1838 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1842 WMPoint initialPosition
;
1844 /* Destroy wheelBackImg, so it'll update properly */
1845 if (panel
->selectionBackImg
) {
1846 XFreePixmap(WMWidgetScreen(panel
->win
)->display
,
1847 panel
->selectionBackImg
);
1848 panel
->selectionBackImg
= None
;
1851 /* Create magnifying glass */
1852 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1853 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1854 if (!panel
->magnifyGlass
->view
)
1857 initialPosition
= magnifyInitialize(panel
);
1858 panel
->magnifyGlass
->x
= initialPosition
.x
;
1859 panel
->magnifyGlass
->y
= initialPosition
.y
;
1861 W_MoveView(panel
->magnifyGlass
->view
,
1862 panel
->magnifyGlass
->x
- Cursor_x_hot
,
1863 panel
->magnifyGlass
->y
- Cursor_y_hot
);
1864 W_MapView(panel
->magnifyGlass
->view
);
1866 magCursor
= magnifyGrabPointer(panel
);
1868 while (panel
->magnifyGlass
->image
)
1870 WMNextEvent(scr
->display
, &event
);
1872 /* Pack motion events */
1873 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1879 XDestroyImage(panel
->magnifyGlass
->image
);
1880 panel
->magnifyGlass
->image
= NULL
;
1882 if (event
.xbutton
.button
== Button1
) {
1883 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1884 panel
->color
.set
= cpRGB
;
1885 updateSwatch(panel
, panel
->color
);
1887 switch (panel
->mode
) {
1888 case WMWheelModeColorPanel
:
1893 case WMGrayModeColorPanel
:
1896 case WMRGBModeColorPanel
:
1899 case WMCMYKModeColorPanel
:
1902 case WMHSBModeColorPanel
:
1908 panel
->lastChanged
= panel
->mode
;
1910 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1914 while (XPending(event
.xmotion
.display
)) {
1916 XPeekEvent(event
.xmotion
.display
, &ev
);
1917 if (ev
.type
== MotionNotify
)
1918 XNextEvent(event
.xmotion
.display
, &event
);
1923 /* Get a "dirty rectangle" */
1924 magnifyGetImageStored( panel
,
1925 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1926 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1928 /* Update coordinates */
1929 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1930 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1933 W_MoveView(panel
->magnifyGlass
->view
,
1934 panel
->magnifyGlass
->x
- Cursor_x_hot
,
1935 panel
->magnifyGlass
->y
- Cursor_y_hot
);
1937 /* Put new image (with magn.) in view */
1938 pixmap
= magnifyCreatePixmap(panel
);
1939 if (pixmap
!= None
) {
1940 /* Change the window background */
1941 XSetWindowBackgroundPixmap(scr
->display
,
1942 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1943 /* Force an Expose (handled by X) */
1944 XClearWindow(scr
->display
,
1945 WMViewXID(panel
->magnifyGlass
->view
));
1946 /* Synchronize the event queue, so the Expose is handled NOW */
1947 XFlush(scr
->display
);
1949 XFreePixmap(scr
->display
, pixmap
);
1954 /* Try XQueryPointer for this !!! It returns windows that the pointer
1955 * is over. Note: We found this solving the invisible donkey cap bug
1957 #if 0 /* As it is impossible to make this work in all cases,
1958 * we consider it confusing. Therefore we disabled it.
1960 case FocusOut
: /* fall through */
1963 * Color Panel window (panel->win) lost or received focus.
1964 * We need to update the pixmap in the magnifying glass.
1966 * BUG Doesn't work with focus switches between two windows
1967 * if none of them is the color panel.
1969 XUngrabPointer(scr
->display
, CurrentTime
);
1970 W_UnmapView(panel
->magnifyGlass
->view
);
1972 magnifyInitialize(panel
);
1974 W_MapView(panel
->magnifyGlass
->view
);
1975 XGrabPointer (scr
->display
, panel
->magnifyGlass
->view
->window
,
1976 True
, PointerMotionMask
| ButtonPressMask
,
1977 GrabModeAsync
, GrabModeAsync
,
1978 scr
->rootWin
, magCursor
, CurrentTime
);
1982 WMHandleEvent(&event
);
1987 XUngrabPointer(scr
->display
, CurrentTime
);
1988 XFreeCursor(scr
->display
, magCursor
);
1990 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1991 panel
->magnifyGlass
->magPix
= None
;
1993 W_UnmapView(panel
->magnifyGlass
->view
);
1994 W_DestroyView(panel
->magnifyGlass
->view
);
1995 panel
->magnifyGlass
->view
= NULL
;
1997 wfree(panel
->magnifyGlass
);
2002 /****************** ColorWheel Functions ************************/
2005 wheelCreateMatrix(unsigned int width
, unsigned int height
)
2007 wheelMatrix
*matrix
= NULL
;
2010 assert((width
> 0) && (height
> 0));
2012 matrix
= wmalloc(sizeof(wheelMatrix
));
2013 memset(matrix
, 0, sizeof(wheelMatrix
));
2014 matrix
->width
= width
;
2015 matrix
->height
= height
;
2017 for (i
= 0; i
< 3; i
++) {
2018 matrix
->data
[i
] = wmalloc(width
*height
*sizeof(unsigned char));
2026 wheelDestroyMatrix(wheelMatrix
*matrix
)
2033 for (i
= 0; i
< 3; i
++) {
2034 if (matrix
->data
[i
])
2035 wfree(matrix
->data
[i
]);
2042 wheelInitMatrix(W_ColorPanel
*panel
)
2046 unsigned char *rp
, *gp
, *bp
;
2052 const int cw_halfsize
= (colorWheelSize
+ 4)/2,
2053 cw_sqsize
= (colorWheelSize
+4) * (colorWheelSize
+4),
2054 uchar_shift
= getShift(sizeof(unsigned char));
2056 if (!panel
->wheelMtrx
)
2059 cpColor
.hsv
.value
= 255;
2060 cpColor
.set
= cpHSV
;
2063 ofs
[1] = -(colorWheelSize
+ 4);
2065 /* offsets are counterclockwise (in triangles).
2068 * _______________________________________
2069 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
2070 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
2071 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
2072 * o | | | | | | | | | | | | | | | | | | | | | [3]
2076 * |\ /| <-- triangles
2082 for (y
= 0; y
< cw_halfsize
; y
++) {
2083 for (x
= y
; x
< (colorWheelSize
+4-y
); x
++) {
2084 /* (xcor, ycor) is (x,y) relative to center of matrix */
2085 xcor
= 2 * x
- 4 - colorWheelSize
;
2086 ycor
= 2 * y
- 4 - colorWheelSize
;
2088 /* RColor.saturation is unsigned char and will wrap after 255 */
2089 sat
= rint(255.0 * sqrt(xcor
*xcor
+ ycor
*ycor
) / colorWheelSize
);
2091 cpColor
.hsv
.saturation
= (unsigned char)sat
;
2093 ofs
[0]++; /* top quarter of matrix*/
2094 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
2095 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
2096 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
2100 dhue
[0] = rint(atan((double)ycor
/ (double)xcor
) *
2101 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
2105 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
2106 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
2107 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
2108 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
2110 for (i
= 0; i
< 4; i
++) {
2111 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
2112 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
2113 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
2115 cpColor
.hsv
.hue
= dhue
[i
];
2116 convertCPColor(&cpColor
);
2118 *rp
= (unsigned char)(cpColor
.rgb
.red
);
2119 *gp
= (unsigned char)(cpColor
.rgb
.green
);
2120 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
2124 for (i
= 0; i
< 4; i
++) {
2125 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
2126 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
2127 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
2129 *rp
= (unsigned char)0;
2130 *gp
= (unsigned char)0;
2131 *bp
= (unsigned char)0;
2137 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2*y
);
2143 wheelCalculateValues(W_ColorPanel
*panel
, int maxvalue
)
2148 for (i
= 0; i
< 256; i
++) {
2149 /* We divide by 128 in advance, and check whether that number divides
2150 * by 2 properly. If not, we add one to round the number correctly
2152 v
= (i
*maxvalue
) >> 7;
2153 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) +(v
& 0x01));
2159 wheelRender(W_ColorPanel
*panel
)
2161 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2166 unsigned long ofs
= 0;
2167 /*unsigned char shift = getShift(sizeof(unsigned char));*/
2169 image
= RCreateImage(colorWheelSize
+4, colorWheelSize
+4, True
);
2171 wwarning(NO_MEMORY_ERR
);
2177 /* TODO Make this transparent istead of gray */
2178 gray
.red
= gray
.blue
= 0xae; gray
.green
= 0xaa;
2180 for (y
= 0; y
< colorWheelSize
+4; y
++) {
2181 for (x
= 0; x
< colorWheelSize
+4; x
++) {
2182 if (wheelInsideColorWheel(panel
, ofs
)) {
2183 *(ptr
++) = (unsigned char)(panel
->wheelMtrx
->values
[
2184 panel
->wheelMtrx
->data
[0][ofs
] ]);
2185 *(ptr
++) = (unsigned char)(panel
->wheelMtrx
->values
[
2186 panel
->wheelMtrx
->data
[1][ofs
] ]);
2187 *(ptr
++) = (unsigned char)(panel
->wheelMtrx
->values
[
2188 panel
->wheelMtrx
->data
[2][ofs
] ]);
2192 *(ptr
++) = (unsigned char)(gray
.red
);
2193 *(ptr
++) = (unsigned char)(gray
.green
);
2194 *(ptr
++) = (unsigned char)(gray
.blue
);
2201 if (panel
->wheelImg
)
2202 XFreePixmap(scr
->display
, panel
->wheelImg
);
2204 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2205 RReleaseImage(image
);
2207 /* Check if backimage exists. If it doesn't, allocate and fill it */
2208 if (!panel
->selectionBackImg
) {
2209 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2210 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2211 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2212 scr
->copyGC
, panel
->colx
-2, panel
->coly
-2, 4, 4, 0, 0);
2213 /* -2 is hot spot correction */
2219 wheelInsideColorWheel(W_ColorPanel
*panel
, unsigned long ofs
)
2221 return ((panel
->wheelMtrx
->data
[0][ofs
] != 0) &&
2222 (panel
->wheelMtrx
->data
[1][ofs
] != 0) &&
2223 (panel
->wheelMtrx
->data
[2][ofs
] != 0));
2228 wheelPaint (W_ColorPanel
*panel
)
2230 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2232 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->wheelView
->window
,
2233 scr
->copyGC
, 0, 0, colorWheelSize
+4, colorWheelSize
+4, 0, 0);
2235 /* Draw selection image */
2236 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2237 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
-2, panel
->coly
-2);
2242 wheelHandleEvents(XEvent
*event
, void *data
)
2244 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2246 switch (event
->type
) {
2248 if (event
->xexpose
.count
!= 0) /* TODO Improve */
2257 wheelHandleActionEvents(XEvent
*event
, void *data
)
2259 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2261 switch (event
->type
) {
2263 if (getPickerPart(panel
, event
->xbutton
.x
, event
->xbutton
.y
) ==
2266 panel
->lastChanged
= WMWheelModeColorPanel
;
2267 panel
->flags
.dragging
= 1;
2269 wheelPositionSelection(panel
, event
->xbutton
.x
, event
->xbutton
.y
);
2274 panel
->flags
.dragging
= 0;
2275 if (!panel
->flags
.continuous
) {
2277 (*panel
->action
)(panel
, panel
->clientData
);
2282 if (panel
->flags
.dragging
) {
2283 if (getPickerPart(panel
, event
->xmotion
.x
, event
->xmotion
.y
) ==
2285 wheelPositionSelection(panel
, event
->xmotion
.x
,
2289 wheelPositionSelectionOutBounds(panel
, event
->xmotion
.x
,
2298 getPickerPart(W_ColorPanel
*panel
, int x
, int y
)
2306 if (panel
->mode
== WMWheelModeColorPanel
) {
2307 if ((lx
>= 2) && (lx
<= 2+colorWheelSize
) && (ly
>= 2) &&
2308 (ly
<= 2+colorWheelSize
)) {
2310 ofs
= ly
*panel
->wheelMtrx
->width
+lx
;
2312 if (wheelInsideColorWheel(panel
, ofs
))
2313 return COLORWHEEL_PART
;
2317 if (panel
->mode
== WMCustomPaletteModeColorPanel
) {
2318 if ((lx
>= 2) && (lx
< customPaletteWidth
-2) && (ly
>= 2) &&
2319 (ly
< customPaletteHeight
-2)) {
2320 return CUSTOMPALETTE_PART
;
2329 wheelBrightnessSliderCallback(WMWidget
*w
, void *data
)
2333 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2335 value
= 255-WMGetSliderValue(panel
->wheelBrightnessS
);
2337 wheelCalculateValues(panel
, value
);
2339 if (panel
->color
.set
== cpRGB
) {
2340 convertCPColor(&panel
->color
);
2341 panel
->color
.set
= cpHSV
;
2344 panel
->color
.hsv
.value
= value
;
2348 wheelUpdateSelection(panel
);
2353 wheelUpdateSelection(W_ColorPanel
*panel
)
2355 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2357 updateSwatch(panel
, panel
->color
);
2358 panel
->lastChanged
= WMWheelModeColorPanel
;
2360 /* Redraw color selector (and make a backup of the part it will cover) */
2361 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2362 scr
->copyGC
, panel
->colx
-2, panel
->coly
-2, 4, 4, 0, 0);
2363 /* "-2" is correction for hotspot location */
2364 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2365 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
-2, panel
->coly
-2);
2371 wheelUndrawSelection(W_ColorPanel
*panel
)
2373 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2375 XCopyArea(scr
->display
, panel
->selectionBackImg
, panel
->wheelView
->window
,
2376 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
-2, panel
->coly
-2);
2381 wheelPositionSelection(W_ColorPanel
*panel
, int x
, int y
)
2383 unsigned long ofs
= (y
* panel
->wheelMtrx
->width
)+ x
;
2385 panel
->color
.rgb
.red
= panel
->wheelMtrx
->values
[
2386 panel
->wheelMtrx
->data
[0][ofs
] ];
2388 panel
->color
.rgb
.green
= panel
->wheelMtrx
->values
[
2389 panel
->wheelMtrx
->data
[1][ofs
] ];
2391 panel
->color
.rgb
.blue
= panel
->wheelMtrx
->values
[
2392 panel
->wheelMtrx
->data
[2][ofs
] ];
2393 panel
->color
.set
= cpRGB
;
2395 wheelUndrawSelection(panel
);
2400 wheelUpdateSelection(panel
);
2401 wheelUpdateBrightnessGradientFromLocation(panel
);
2405 wheelPositionSelectionOutBounds(W_ColorPanel
*panel
, int x
, int y
)
2411 xcor
= x
* 2 - colorWheelSize
- 4;
2412 ycor
= y
* 2 - colorWheelSize
- 4;
2414 panel
->color
.hsv
.saturation
= 255;
2415 panel
->color
.hsv
.value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2418 hue
= rint(atan(- (double)ycor
/ (double)xcor
) * (180.0/M_PI
));
2429 if ((xcor
> 0) && (ycor
> 0))
2432 panel
->color
.hsv
.hue
= hue
;
2433 panel
->color
.set
= cpHSV
;
2434 convertCPColor(&panel
->color
);
2436 wheelUndrawSelection(panel
);
2438 panel
->colx
= 2 + rint((colorWheelSize
* (1.0 +
2439 cos( panel
->color
.hsv
.hue
* (M_PI
/180.0) ))) / 2.0);
2440 /* "+2" because of "colorWheelSize + 4" */
2441 panel
->coly
= 2 + rint((colorWheelSize
* (1.0 +
2442 sin(- panel
->color
.hsv
.hue
* (M_PI
/180.0) ))) / 2.0);
2444 wheelUpdateSelection(panel
);
2445 cpColor
= panel
->color
;
2446 wheelUpdateBrightnessGradient(panel
, cpColor
);
2450 wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
*panel
)
2455 ofs
= panel
->coly
* panel
->wheelMtrx
->width
+ panel
->colx
;
2457 from
.rgb
.red
= panel
->wheelMtrx
->data
[0][ofs
];
2458 from
.rgb
.green
= panel
->wheelMtrx
->data
[1][ofs
];
2459 from
.rgb
.blue
= panel
->wheelMtrx
->data
[2][ofs
];
2462 wheelUpdateBrightnessGradient(panel
, from
);
2466 wheelUpdateBrightnessGradient(W_ColorPanel
*panel
, CPColor topColor
)
2470 WMPixmap
*sliderPxmp
;
2472 to
.red
= to
.green
= to
.blue
= 0;
2474 if (topColor
.set
== cpHSV
)
2475 convertCPColor(&topColor
);
2477 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2478 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
),
2480 RReleaseImage(sliderImg
);
2481 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2482 WMReleasePixmap(sliderPxmp
);
2485 /****************** Grayscale Panel Functions ***************/
2488 grayBrightnessSliderCallback(WMWidget
*w
, void *data
)
2493 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2495 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2497 sprintf(tmp
, "%d", value
);
2499 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2500 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55*value
);
2501 cpColor
.set
= cpRGB
;
2503 updateSwatch(panel
, cpColor
);
2504 panel
->lastChanged
= WMGrayModeColorPanel
;
2508 grayPresetButtonCallback(WMWidget
*w
, void *data
)
2514 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2517 if (w
== panel
->grayPresetBtn
[i
])
2522 value
= rint((100.0*i
)/6.0);
2523 sprintf(tmp
, "%d", value
);
2525 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2526 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
=
2527 rint((255.0*i
)/6.0);
2528 cpColor
.set
= cpRGB
;
2530 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0*i
)/6.0));
2532 updateSwatch(panel
, cpColor
);
2533 panel
->lastChanged
= WMGrayModeColorPanel
;
2537 grayBrightnessTextFieldCallback(void *observerData
,
2538 WMNotification
*notification
)
2543 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2545 value
= atoi(WMGetTextFieldText(panel
->grayBrightnessT
));
2551 sprintf(tmp
, "%d", value
);
2552 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2553 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2555 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
=
2556 rint((255.0*value
)/100.0);
2557 cpColor
.set
= cpRGB
;
2559 updateSwatch(panel
, cpColor
);
2560 panel
->lastChanged
= WMGrayModeColorPanel
;
2563 /******************* RGB Panel Functions *****************/
2566 rgbSliderCallback(WMWidget
*w
, void *data
)
2571 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2573 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2574 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2575 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2577 sprintf(tmp
, "%d", value
[0]);
2578 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2579 sprintf(tmp
, "%d", value
[1]);
2580 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2581 sprintf(tmp
, "%d", value
[2]);
2582 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2584 cpColor
.rgb
.red
= value
[0];
2585 cpColor
.rgb
.green
= value
[1];
2586 cpColor
.rgb
.blue
= value
[2];
2587 cpColor
.set
= cpRGB
;
2589 updateSwatch(panel
, cpColor
);
2590 panel
->lastChanged
= WMRGBModeColorPanel
;
2594 rgbTextFieldCallback(void *observerData
, WMNotification
*notification
)
2600 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2602 value
[0] = atoi(WMGetTextFieldText(panel
->rgbRedT
));
2603 value
[1] = atoi(WMGetTextFieldText(panel
->rgbGreenT
));
2604 value
[2] = atoi(WMGetTextFieldText(panel
->rgbBlueT
));
2606 for (n
=0; n
< 3; n
++) {
2613 sprintf(tmp
, "%d", value
[0]);
2614 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2615 sprintf(tmp
, "%d", value
[1]);
2616 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2617 sprintf(tmp
, "%d", value
[2]);
2618 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2620 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2621 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2622 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2624 cpColor
.rgb
.red
= value
[0];
2625 cpColor
.rgb
.green
= value
[1];
2626 cpColor
.rgb
.blue
= value
[2];
2627 cpColor
.set
= cpRGB
;
2629 updateSwatch(panel
, cpColor
);
2630 panel
->lastChanged
= WMRGBModeColorPanel
;
2634 /******************* CMYK Panel Functions *****************/
2637 cmykSliderCallback(WMWidget
*w
, void *data
)
2642 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2645 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2646 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2647 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2648 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2650 sprintf(tmp
, "%d", value
[0]);
2651 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2652 sprintf(tmp
, "%d", value
[1]);
2653 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2654 sprintf(tmp
, "%d", value
[2]);
2655 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2656 sprintf(tmp
, "%d", value
[3]);
2657 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2659 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2660 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2661 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2662 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2663 cpColor
.set
= cpRGB
;
2665 updateSwatch(panel
, cpColor
);
2666 panel
->lastChanged
= WMCMYKModeColorPanel
;
2670 cmykTextFieldCallback(void *observerData
, WMNotification
*notification
)
2677 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2679 value
[0] = atoi(WMGetTextFieldText(panel
->cmykCyanT
));
2680 value
[1] = atoi(WMGetTextFieldText(panel
->cmykMagentaT
));
2681 value
[2] = atoi(WMGetTextFieldText(panel
->cmykYellowT
));
2682 value
[3] = atoi(WMGetTextFieldText(panel
->cmykBlackT
));
2684 for (n
=0; n
< 4; n
++) {
2691 sprintf(tmp
, "%d", value
[0]);
2692 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2694 sprintf(tmp
, "%d", value
[1]);
2695 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2697 sprintf(tmp
, "%d", value
[2]);
2698 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2700 sprintf(tmp
, "%d", value
[3]);
2701 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2703 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2704 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2705 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2706 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2708 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2709 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2710 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2711 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2712 cpColor
.set
= cpRGB
;
2714 updateSwatch(panel
, cpColor
);
2715 panel
->lastChanged
= WMCMYKModeColorPanel
;
2718 /********************** HSB Panel Functions ***********************/
2721 hsbSliderCallback(WMWidget
*w
, void *data
)
2726 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
2728 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2729 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2730 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2732 sprintf(tmp
, "%d", value
[0]);
2733 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2734 sprintf(tmp
, "%d", value
[1]);
2735 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2736 sprintf(tmp
, "%d", value
[2]);
2737 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2739 cpColor
.hsv
.hue
= value
[0];
2740 cpColor
.hsv
.saturation
= value
[1]*2.55;
2741 cpColor
.hsv
.value
= value
[2]*2.55;
2742 cpColor
.set
= cpHSV
;
2744 convertCPColor(&cpColor
);
2746 panel
->lastChanged
= WMHSBModeColorPanel
;
2747 updateSwatch(panel
, cpColor
);
2749 if (w
!= panel
->hsbBrightnessS
)
2750 hsbUpdateBrightnessGradient(panel
);
2751 if (w
!= panel
->hsbSaturationS
)
2752 hsbUpdateSaturationGradient(panel
);
2753 if (w
!= panel
->hsbHueS
)
2754 hsbUpdateHueGradient(panel
);
2758 hsbTextFieldCallback(void *observerData
, WMNotification
*notification
)
2764 W_ColorPanel
*panel
= (W_ColorPanel
*)observerData
;
2766 value
[0] = atoi(WMGetTextFieldText(panel
->hsbHueT
));
2767 value
[1] = atoi(WMGetTextFieldText(panel
->hsbSaturationT
));
2768 value
[2] = atoi(WMGetTextFieldText(panel
->hsbBrightnessT
));
2775 for (n
=1; n
< 3; n
++) {
2782 sprintf(tmp
, "%d", value
[0]);
2783 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2784 sprintf(tmp
, "%d", value
[1]);
2785 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2786 sprintf(tmp
, "%d", value
[2]);
2787 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2789 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2790 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2791 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2793 cpColor
.hsv
.hue
= value
[0];
2794 cpColor
.hsv
.saturation
= value
[1]*2.55;
2795 cpColor
.hsv
.value
= value
[2]*2.55;
2796 cpColor
.set
= cpHSV
;
2798 convertCPColor(&cpColor
);
2800 panel
->lastChanged
= WMHSBModeColorPanel
;
2801 updateSwatch(panel
, cpColor
);
2803 hsbUpdateBrightnessGradient(panel
);
2804 hsbUpdateSaturationGradient(panel
);
2805 hsbUpdateHueGradient(panel
);
2809 hsbUpdateBrightnessGradient(W_ColorPanel
*panel
)
2811 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2815 WMPixmap
*sliderPxmp
;
2817 from
.red
= from
.green
= from
.blue
= 0;
2818 to
.hsv
= panel
->color
.hsv
;
2822 convertCPColor(&to
);
2824 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2825 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2826 RReleaseImage(sliderImg
);
2829 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2830 panel
->font12
, 2, 0, 100, WALeft
, WMColorGC(scr
->white
),
2831 False
, "Brightness", strlen("Brightness"));
2833 wwarning(NO_MEMORY_ERR
);
2835 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2836 WMReleasePixmap(sliderPxmp
);
2840 hsbUpdateSaturationGradient(W_ColorPanel
*panel
)
2842 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2846 WMPixmap
*sliderPxmp
;
2848 from
.hsv
= panel
->color
.hsv
;
2849 from
.hsv
.saturation
= 0;
2851 convertCPColor(&from
);
2853 to
.hsv
= panel
->color
.hsv
;
2854 to
.hsv
.saturation
= 255;
2856 convertCPColor(&to
);
2858 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
),
2860 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2861 RReleaseImage(sliderImg
);
2864 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2865 panel
->font12
, 2, 0, 100, WALeft
,
2866 WMColorGC(from
.hsv
.value
< 128 ? scr
->white
: scr
->black
), False
,
2867 "Saturation", strlen("Saturation"));
2869 wwarning(NO_MEMORY_ERR
);
2871 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2872 WMReleasePixmap(sliderPxmp
);
2876 hsbUpdateHueGradient(W_ColorPanel
*panel
)
2878 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2879 RColor
**colors
= NULL
;
2882 WMPixmap
*sliderPxmp
;
2885 hsvcolor
= panel
->color
.hsv
;
2887 colors
= wmalloc(sizeof(RColor
*)*(8));
2888 for (i
=0; i
<7; i
++) {
2889 hsvcolor
.hue
= (360*i
)/6;
2890 colors
[i
] = wmalloc(sizeof(RColor
));
2891 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2895 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2896 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2897 RReleaseImage(sliderImg
);
2900 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2901 panel
->font12
, 2, 0, 100, WALeft
,
2902 WMColorGC(hsvcolor
.value
< 128 ? scr
->white
: scr
->black
), False
,
2903 "Hue", strlen("Hue"));
2905 wwarning(NO_MEMORY_ERR
);
2907 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2908 WMReleasePixmap(sliderPxmp
);
2916 /*************** Custom Palette Functions ****************/
2919 customRenderSpectrum(W_ColorPanel
*panel
)
2926 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, False
);
2928 ptr
= spectrum
->data
;
2930 for (y
= 0; y
< SPECTRUM_HEIGHT
; y
++) {
2931 cpColor
.hsv
.hue
= y
;
2932 cpColor
.hsv
.saturation
= 0;
2933 cpColor
.hsv
.value
= 255;
2934 cpColor
.set
= cpHSV
;
2936 for (x
= 0; x
< SPECTRUM_WIDTH
; x
++) {
2937 convertCPColor(&cpColor
);
2939 *(ptr
++) = (unsigned char)cpColor
.rgb
.red
;
2940 *(ptr
++) = (unsigned char)cpColor
.rgb
.green
;
2941 *(ptr
++) = (unsigned char)cpColor
.rgb
.blue
;
2943 if (x
< (SPECTRUM_WIDTH
/2))
2944 cpColor
.hsv
.saturation
++;
2946 if (x
> (SPECTRUM_WIDTH
/2))
2947 cpColor
.hsv
.value
--;
2950 if (panel
->customPaletteImg
) {
2951 RReleaseImage(panel
->customPaletteImg
);
2952 panel
->customPaletteImg
= NULL
;
2954 panel
->customPaletteImg
= spectrum
;
2960 customSetPalette(W_ColorPanel
*panel
)
2962 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2967 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
,
2968 customPaletteHeight
, scr
->depth
);
2969 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
,
2970 customPaletteHeight
);
2971 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2972 RReleaseImage(scaledImg
);
2974 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2975 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2977 /* Check backimage exists. If it doesn't, allocate and fill it */
2978 if (!panel
->selectionBackImg
) {
2979 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2980 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2983 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2984 panel
->palx
-2, panel
->paly
-2, 4, 4, 0, 0);
2985 XCopyArea(scr
->display
, panel
->selectionImg
,
2986 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0 , 0, 4, 4,
2987 panel
->palx
-2, panel
->paly
-2);
2988 XFreePixmap(scr
->display
, image
);
2990 panel
->palXRatio
= (double)(panel
->customPaletteImg
->width
) /
2991 (double)(customPaletteWidth
);
2992 panel
->palYRatio
= (double)(panel
->customPaletteImg
->height
) /
2993 (double)(customPaletteHeight
);
2995 item
= WMGetPopUpButtonSelectedItem (panel
->customPaletteHistoryBtn
);
3000 customPalettePositionSelection(W_ColorPanel
*panel
, int x
, int y
)
3002 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3006 /* undraw selection */
3007 XCopyArea(scr
->display
, panel
->selectionBackImg
,
3008 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
3009 panel
->palx
-2, panel
->paly
-2);
3014 ofs
= (rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) *
3015 panel
->customPaletteImg
->width
) * 3;
3017 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[ofs
];
3018 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[ofs
+1];
3019 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[ofs
+2];
3020 panel
->color
.set
= cpRGB
;
3022 updateSwatch(panel
, panel
->color
);
3023 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
3025 /* Redraw color selector (and make a backup of the part it will cover) */
3026 XCopyArea(scr
->display
, panel
->customPaletteContentView
->window
,
3027 panel
->selectionBackImg
, scr
->copyGC
, panel
->palx
-2, panel
->paly
-2,
3028 4, 4, 0, 0); /* "-2" is correction for hotspot location */
3029 XCopyArea(scr
->display
, panel
->selectionImg
,
3030 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
3031 panel
->palx
-2, panel
->paly
-2); /* see above */
3036 customPalettePositionSelectionOutBounds(W_ColorPanel
*panel
, int x
, int y
)
3042 if (x
>= customPaletteWidth
)
3043 x
= customPaletteWidth
-2;
3044 if (y
>= customPaletteHeight
)
3045 y
= customPaletteHeight
-2;
3047 customPalettePositionSelection(panel
, x
, y
);
3052 customPaletteHandleEvents(XEvent
*event
, void *data
)
3054 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3056 switch (event
->type
) {
3058 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
3060 customSetPalette(panel
);
3066 customPaletteHandleActionEvents(XEvent
*event
, void *data
)
3068 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3071 switch (event
->type
) {
3073 x
= event
->xbutton
.x
;
3074 y
= event
->xbutton
.y
;
3076 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
3077 panel
->flags
.dragging
= 1;
3078 customPalettePositionSelection(panel
, x
, y
);
3083 panel
->flags
.dragging
= 0;
3084 if (!panel
->flags
.continuous
) {
3086 (*panel
->action
)(panel
, panel
->clientData
);
3091 x
= event
->xmotion
.x
;
3092 y
= event
->xmotion
.y
;
3094 if (panel
->flags
.dragging
) {
3095 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
3096 customPalettePositionSelection(panel
, x
, y
);
3099 customPalettePositionSelectionOutBounds(panel
, x
, y
);
3107 customPaletteMenuCallback(WMWidget
*w
, void *data
)
3109 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3110 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
3113 case CPmenuNewFromFile
:
3114 customPaletteMenuNewFromFile(panel
);
3117 customPaletteMenuRename(panel
);
3120 customPaletteMenuRemove(panel
);
3124 case CPmenuNewFromClipboard
:
3131 customPaletteMenuNewFromFile(W_ColorPanel
*panel
)
3133 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3134 WMOpenPanel
*browseP
;
3136 char *filename
= NULL
;
3140 RImage
*tmpImg
= NULL
;
3142 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
,"\0") == 0))
3143 spath
= wexpandpath(wgethomedir());
3145 spath
= wexpandpath(panel
->lastBrowseDir
);
3147 browseP
= WMGetOpenPanel(scr
);
3148 WMSetFilePanelCanChooseDirectories(browseP
, 0);
3149 WMSetFilePanelCanChooseFiles(browseP
, 1);
3151 /* Get a filename */
3152 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
3153 "Open Palette", RSupportedFileFormats()) ) {
3154 filepath
= WMGetFilePanelFileName(browseP
);
3156 /* Get seperation position between path and filename */
3157 i
= strrchr(filepath
, '/') - filepath
+ 1;
3158 if (i
> strlen(filepath
))
3159 i
= strlen(filepath
);
3161 /* Store last browsed path */
3162 if (panel
->lastBrowseDir
)
3163 wfree(panel
->lastBrowseDir
);
3164 panel
->lastBrowseDir
= wmalloc((i
+1)*sizeof(char));
3165 strncpy(panel
->lastBrowseDir
, filepath
, i
);
3166 panel
->lastBrowseDir
[i
] = '\0';
3168 /* Get filename from path */
3169 filename
= wstrdup(filepath
+ i
);
3171 /* Check for duplicate files, and rename it if there are any */
3172 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3173 while (access (tmp
, F_OK
) == 0) {
3178 newName
= generateNewFilename(filename
);
3182 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3186 /* Copy image to $(gnustepdir)/Library/Colors/ &
3187 * Add filename to history menu */
3188 if (fetchFile (panel
->configurationPath
, filepath
, filename
) == 0) {
3190 /* filepath is a "local" path now the file has been copied */
3192 filepath
= wstrconcat(panel
->configurationPath
, filename
);
3194 /* load the image & add menu entries */
3195 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
3197 if (panel
->customPaletteImg
)
3198 RReleaseImage(panel
->customPaletteImg
);
3199 panel
->customPaletteImg
= tmpImg
;
3201 customSetPalette(panel
);
3202 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
3204 panel
->currentPalette
= WMGetPopUpButtonNumberOfItems(
3205 panel
->customPaletteHistoryBtn
)-1;
3207 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3208 panel
->currentPalette
);
3211 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3213 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
3214 WMRunAlertPanel(scr
, panel
->win
, "File Error",
3215 "Invalid file format !", "OK", NULL
, NULL
);
3217 wsyserror("can't remove file %s", tmp
);
3218 WMRunAlertPanel(scr
, panel
->win
, "File Error",
3219 "Couldn't remove file from Configuration Directory !",
3227 WMFreeFilePanel(browseP
);
3234 customPaletteMenuRename(W_ColorPanel
*panel
)
3236 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3237 char *toName
= NULL
;
3239 char *toPath
, *fromPath
;
3243 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3244 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3246 toName
= WMRunInputPanel(scr
, panel
->win
, "Rename", "Rename palette to:",
3247 fromName
, "OK", "Cancel");
3251 /* As some people do certain stupid things... */
3252 if (strcmp(toName
, fromName
) == 0) {
3257 /* For normal people */
3258 fromPath
= wstrconcat(panel
->configurationPath
, fromName
);
3259 toPath
= wstrconcat(panel
->configurationPath
, toName
);
3261 if (access (toPath
, F_OK
) == 0) {
3262 /* Careful, this palette exists already */
3263 if (WMRunAlertPanel(scr
, panel
->win
, "Warning",
3264 "Palette already exists !\n\nOverwrite ?", "No", "Yes",
3266 /* "No" = 0, "Yes" = 1 */
3267 int items
= WMGetPopUpButtonNumberOfItems(
3268 panel
->customPaletteHistoryBtn
);
3272 /* Remove from History list too */
3274 while ((index
< items
) && (strcmp(WMGetPopUpButtonItem(
3275 panel
->customPaletteHistoryBtn
, index
),
3279 if (index
< items
) {
3280 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
,
3295 if ( rename(fromPath
, toPath
) != 0)
3296 wsyserror("Couldn't rename palette %s to %s\n", fromName
, toName
);
3298 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3299 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
,
3302 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3312 customPaletteMenuRemove(W_ColorPanel
*panel
)
3314 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3320 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3322 tmp
= wstrconcat( "This will permanently remove the palette ",
3323 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3324 text
= wstrconcat( tmp
,
3325 ".\n\nAre you sure you want to remove this palette ?");
3328 choice
= WMRunAlertPanel(scr
, panel
->win
, "Remove", text
, "Yes", "No",
3330 /* returns 0 (= "Yes") or 1 (="No") */
3335 tmp
= wstrconcat(panel
->configurationPath
,
3336 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3338 if ( remove(tmp
) == 0) {
3339 /* item-1 always exists */
3340 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3343 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
,
3345 customSetPalette(panel
);
3347 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3350 wsyserror("Couldn't remove palette %s\n", tmp
);
3359 customPaletteHistoryCallback(WMWidget
*w
, void *data
)
3361 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3362 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3366 unsigned char perm_mask
;
3368 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3369 if (item
== panel
->currentPalette
)
3373 customRenderSpectrum(panel
);
3375 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
,
3377 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
,
3380 /* Load file from configpath */
3381 filename
= wstrconcat( panel
->configurationPath
,
3382 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
) );
3384 /* If the file corresponding to the item does not exist,
3385 * remove it from the history list and select the next one.
3387 perm_mask
= (access(filename
, F_OK
) == 0);
3389 /* File does not exist */
3391 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3393 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3394 customPaletteHistoryCallback(w
, data
);
3399 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3401 if (panel
->customPaletteImg
) {
3402 RReleaseImage(panel
->customPaletteImg
);
3403 panel
->customPaletteImg
= NULL
;
3405 panel
->customPaletteImg
= tmp
;
3408 /* If the image is not writable, don't allow removing/renaming */
3409 perm_mask
= (access(filename
, W_OK
) == 0);
3410 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
,
3412 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
,
3417 customSetPalette(panel
);
3419 panel
->currentPalette
= item
;
3422 /************************* ColorList Panel Functions **********************/
3425 colorListPaintItem(WMList
*lPtr
, int index
, Drawable d
, char *text
,
3426 int state
, WMRect
*rect
)
3428 int width
, height
, x
, y
;
3429 RColor color
= *((RColor
*)WMGetListItem(lPtr
, index
)->clientData
);
3430 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3431 Display
*dpy
= WMScreenDisplay(scr
);
3432 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3433 WMColor
*white
= WMWhiteColor(scr
);
3434 WMColor
*black
= WMBlackColor(scr
);
3437 width
= rect
->size
.width
;
3438 height
= rect
->size
.height
;
3442 if (state
& WLDSSelected
)
3443 WMPaintColorSwatch(white
, d
, x
+15, y
, width
-15, height
);
3445 XClearArea(dpy
, d
, x
+15, y
, width
-15, height
, False
);
3447 fillColor
= WMCreateRGBColor(scr
, color
.red
*256, color
.green
*256,
3448 color
.blue
*256, False
);
3450 WMSetColorInGC(fillColor
, WMColorGC(fillColor
));
3451 WMPaintColorSwatch(fillColor
, d
, x
, y
, 15, 15);
3452 WMReleaseColor(fillColor
);
3454 WMDrawString(scr
, d
, WMColorGC(black
), panel
->font12
, x
+18, y
, text
,
3457 WMReleaseColor(white
);
3458 WMReleaseColor(black
);
3463 colorListSelect(WMWidget
*w
, void *data
)
3465 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3468 cpColor
.rgb
= *((RColor
*)WMGetListSelectedItem(w
)->clientData
);
3469 cpColor
.set
= cpRGB
;
3471 panel
->lastChanged
= WMColorListModeColorPanel
;
3472 updateSwatch(panel
, cpColor
);
3477 colorListColorMenuCallback(WMWidget
*w
, void *data
)
3479 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3480 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3494 colorListListMenuCallback(WMWidget
*w
, void *data
)
3496 W_ColorPanel
*panel
= (W_ColorPanel
*)data
;
3497 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3501 /* New Color List */
3502 colorListListMenuNew(panel
);
3513 colorListListMenuNew(W_ColorPanel
*panel
)
3519 /*************** Panel Initialisation Functions *****************/
3522 wheelInit(W_ColorPanel
*panel
)
3526 if (panel
->color
.set
!= cpHSV
)
3527 convertCPColor(&panel
->color
);
3529 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3531 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3532 (1 + ( panel
->color
.hsv
.saturation
/255.0) *
3533 cos( panel
->color
.hsv
.hue
* M_PI
/180.0)));
3534 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3535 (1 + ( panel
->color
.hsv
.saturation
/255.0) *
3536 sin(- panel
->color
.hsv
.hue
*M_PI
/180.0)));
3538 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3540 cpColor
= panel
->color
;
3541 cpColor
.hsv
.value
= 255;
3542 cpColor
.set
= cpHSV
;
3543 wheelUpdateBrightnessGradient(panel
, cpColor
);
3548 grayInit(W_ColorPanel
*panel
)
3553 if (panel
->color
.set
!= cpHSV
)
3554 convertCPColor(&panel
->color
);
3556 value
= rint(panel
->color
.hsv
.value
/2.55);
3557 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3559 sprintf(tmp
, "%d", value
);
3560 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3565 rgbInit(W_ColorPanel
*panel
)
3569 if (panel
->color
.set
!= cpRGB
)
3570 convertCPColor(&panel
->color
);
3572 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3573 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3574 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3576 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3577 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3578 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3579 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3580 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3581 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3586 cmykInit(W_ColorPanel
*panel
)
3591 if (panel
->color
.set
!= cpRGB
)
3592 convertCPColor(&panel
->color
);
3594 value
[0] = rint((255-panel
->color
.rgb
.red
)/2.55);
3595 value
[1] = rint((255-panel
->color
.rgb
.green
)/2.55);
3596 value
[2] = rint((255-panel
->color
.rgb
.blue
)/2.55);
3598 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3599 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3600 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3601 WMSetSliderValue(panel
->cmykBlackS
, 0);
3603 sprintf(tmp
, "%d", value
[0]);
3604 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3605 sprintf(tmp
, "%d", value
[1]);
3606 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3607 sprintf(tmp
, "%d", value
[2]);
3608 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3609 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3614 hsbInit(W_ColorPanel
*panel
)
3619 if (panel
->color
.set
!= cpHSV
)
3620 convertCPColor(&panel
->color
);
3622 value
[0] = panel
->color
.hsv
.hue
;
3623 value
[1] = rint(panel
->color
.hsv
.saturation
/2.55);
3624 value
[2] = rint(panel
->color
.hsv
.value
/2.55);
3626 WMSetSliderValue(panel
->hsbHueS
,value
[0]);
3627 WMSetSliderValue(panel
->hsbSaturationS
,value
[1]);
3628 WMSetSliderValue(panel
->hsbBrightnessS
,value
[2]);
3630 sprintf(tmp
, "%d", value
[0]);
3631 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3632 sprintf(tmp
, "%d", value
[1]);
3633 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3634 sprintf(tmp
, "%d", value
[2]);
3635 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3637 hsbUpdateBrightnessGradient(panel
);
3638 hsbUpdateSaturationGradient(panel
);
3639 hsbUpdateHueGradient(panel
);
3644 /************************** Common utility functions ************************/
3647 fetchFile(char *toPath
, char *srcFile
, char *destFile
)
3654 if ((src
= open(srcFile
, O_RDONLY
)) == 0) {
3655 wsyserror("Could not open %s", srcFile
);
3659 tmp
= wstrconcat(toPath
, destFile
);
3660 if ((dest
= open( tmp
, O_RDWR
|O_CREAT
, S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IROTH
))
3662 wsyserror("Could not create %s", tmp
);
3670 while ((n
= read(src
, buf
, BUFSIZE
)) > 0)
3672 if (write (dest
, buf
, n
) != n
) {
3673 wsyserror("Write error on file %s", destFile
);
3683 generateNewFilename(char *curName
)
3696 if (((ptr
= strrchr(ptr
, '{'))==0) || sscanf(ptr
, "{%i}%c", &n
, &c
)!=1)
3697 return wstrconcat(curName
, " {1}");
3699 baseLen
= ptr
- curName
-1;
3701 newName
= wmalloc(baseLen
+ 16);
3702 strncpy(newName
, curName
, baseLen
);
3703 newName
[baseLen
] = 0;
3705 sprintf(&newName
[baseLen
], " {%i}", n
+1);
3712 convertCPColor(CPColor
*color
)
3714 unsigned short old_hue
= 0;
3716 switch (color
->set
) {
3718 wwarning("Color Panel: Color unspecified");
3721 old_hue
= color
->hsv
.hue
;
3722 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3724 /* In black the hue is undefined, and may change by conversion
3725 * Same for white. */
3727 ((color
->rgb
.red
== 0) &&
3728 (color
->rgb
.green
== 0) &&
3729 (color
->rgb
.blue
== 0)) ||
3730 ((color
->rgb
.red
== 0) &&
3731 (color
->rgb
.green
== 0) &&
3732 (color
->rgb
.blue
== 255))
3734 color
->hsv
.hue
= old_hue
;
3737 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3743 #define ABS_SHIFT(val, shift) \
3744 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3747 ulongToRColor(WMScreen
*scr
, unsigned long value
)
3750 XColor
*xcolor
= NULL
;
3752 if (!(xcolor
= wmalloc(sizeof(XColor
)) )) {
3753 wwarning(NO_MEMORY_ERR
);
3760 xcolor
->pixel
= value
;
3761 XQueryColor(scr
->display
, scr
->rcontext
->cmap
, xcolor
);
3763 color
.red
= xcolor
->red
>> 8;
3764 color
.green
= xcolor
->green
>> 8;
3765 color
.blue
= xcolor
->blue
>> 8;
3774 getShift(unsigned char value
)
3776 unsigned char i
= -1;
3791 #ifdef SHAPE_WAS_DEFINED
3792 #undef SHAPE_WAS_DEFINED