fix portability bug for non-X11R6 systems
[wmaker-crm.git] / WINGs / wcolorpanel.c
blobe9dd181b1be2347b65b517f2ce8547ca5f0e5f6a
1 /*
2 * ColorPanel for WINGs
4 * by ]d : Original idea and basic initial code
5 * Pascal Hofstee : Code for wheeldrawing and calculating
6 * colors from it.
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 ;-)
15 * small note: Tabstop size = 4
20 /* BUGS:
21 * For some reason after using the magnifying glass, the windowlist
22 * of the color-panel (panel->view->screen) becomes 0x0. This
23 * results in a core-dump of testcolorpanel, and in 3 times
24 * "WPrefs in free(): warning: chunk is already free." with WPrefs.
27 /* TODO:
28 * - Custom color-lists and custom colors in custom colo-lists.
29 * - Stored colors
30 * - Resizing
34 #include "WINGsP.h"
35 #include <math.h>
36 #include <unistd.h>
37 #include <ctype.h>
38 #include <fcntl.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <dirent.h>
42 #include <errno.h>
45 #ifndef PATH_MAX
46 # define PATH_MAX 1024
47 #endif
50 char *WMColorPanelColorChangedNotification = "WMColorPanelColorChangedNotification";
54 * Bitmaps for magnifying glass cursor
57 /* Cursor */
58 #define Cursor_x_hot 11
59 #define Cursor_y_hot 11
60 #define Cursor_width 32
61 #define Cursor_height 32
62 static unsigned char Cursor_bits[] = {
63 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
64 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
65 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
66 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
67 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
68 0x00,0x08,0x00,0x50,0x00,0x10,0x00,0x88,0x00,0x20,0x00,0x5c,0x01,0xc0,0x81,
69 0x3b,0x02,0x00,0x7e,0x70,0x05,0x00,0x00,0xe0,0x08,0x00,0x00,0xc0,0x15,0x00,
70 0x00,0x80,0x23,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x5c,
71 0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x70};
73 /* Cursor shape-mask */
74 #define Cursor_shape_width 32
75 #define Cursor_shape_height 32
76 static unsigned char Cursor_shape_bits[] = {
77 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
78 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
79 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
80 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
81 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
82 0x00,0x08,0x00,0x70,0x00,0x10,0x00,0xf8,0x00,0x20,0x00,0xfc,0x01,0xc0,0x81,
83 0xfb,0x03,0x00,0x7e,0xf0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x1f,0x00,
84 0x00,0x80,0x3f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfc,
85 0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70};
87 /* Clip-mask for magnified pixels */
88 #define Cursor_mask_width 22
89 #define Cursor_mask_height 22
90 static unsigned char Cursor_mask_bits[] = {
91 0x00,0x3f,0x00,0xe0,0xff,0x01,0xf0,0xff,0x03,0xf8,0xff,0x07,0xfc,0xff,0x0f,
92 0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xff,0xff,0x3f,0xff,0xff,0x3f,
93 0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xfe,0xff,0x1f,
94 0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfc,0xff,0x0f,0xf8,0xff,0x07,0xf0,0xff,0x03,
95 0xe0,0xff,0x01,0x00,0x3f,0x00};
98 typedef struct MovingView {
99 WMView *view; /* The view this is all about */
100 Pixmap pixmap; /* What's under the view */
101 Pixmap mask; /* Pixmap mask for view-contents */
102 int valid; /* Are contents still valid ? */
103 RColor color; /* Color of a pixel in the image */
104 } MovingView;
106 typedef struct WheelMatrix {
107 unsigned int width, height; /* Size of the colorwheel */
108 unsigned char *data[3]; /* Wheel data (R,G,B) */
109 unsigned char values[256]; /* Precalculated values R,G & B = 0-255 */
110 } wheelMatrix;
112 typedef struct W_ColorPanel {
113 WMWindow *win;
114 WMFont *font8;
115 WMFont *font12;
117 void *clientData;
118 WMAction2 *action;
120 /* Common Stuff */
121 WMColorWell *colorWell;
122 WMButton *magnifyBtn;
123 WMButton *wheelBtn;
124 WMButton *slidersBtn;
125 WMButton *customPaletteBtn;
126 WMButton *colorListBtn;
128 /* Magnifying Glass */
129 MovingView *magnifyGlass;
131 /* ColorWheel Panel */
132 WMFrame *wheelFrm;
133 WMSlider *wheelBrightnessS;
134 WMView *wheelView;
136 /* Slider Panels */
137 WMFrame *slidersFrm;
138 WMFrame *seperatorFrm;
139 WMButton *grayBtn;
140 WMButton *rgbBtn;
141 WMButton *cmykBtn;
142 WMButton *hsbBtn;
143 /* Gray Scale Panel */
144 WMFrame *grayFrm;
145 WMLabel *grayMinL;
146 WMLabel *grayMaxL;
147 WMSlider *grayBrightnessS;
148 WMTextField *grayBrightnessT;
149 WMButton *grayPresetBtn[7];
151 /* RGB Panel */
152 WMFrame *rgbFrm;
153 WMLabel *rgbMinL;
154 WMLabel *rgbMaxL;
155 WMSlider *rgbRedS;
156 WMSlider *rgbGreenS;
157 WMSlider *rgbBlueS;
158 WMTextField *rgbRedT;
159 WMTextField *rgbGreenT;
160 WMTextField *rgbBlueT;
162 /* CMYK Panel */
163 WMFrame *cmykFrm;
164 WMLabel *cmykMinL;
165 WMLabel *cmykMaxL;
166 WMSlider *cmykCyanS;
167 WMSlider *cmykMagentaS;
168 WMSlider *cmykYellowS;
169 WMSlider *cmykBlackS;
170 WMTextField *cmykCyanT;
171 WMTextField *cmykMagentaT;
172 WMTextField *cmykYellowT;
173 WMTextField *cmykBlackT;
175 /* HSB Panel */
176 WMFrame *hsbFrm;
177 WMSlider *hsbHueS;
178 WMSlider *hsbSaturationS;
179 WMSlider *hsbBrightnessS;
180 WMTextField *hsbHueT;
181 WMTextField *hsbSaturationT;
182 WMTextField *hsbBrightnessT;
184 /* Custom Palette Panel*/
185 WMFrame *customPaletteFrm;
186 WMPopUpButton *customPaletteHistoryBtn;
187 WMFrame *customPaletteContentFrm;
188 WMPopUpButton *customPaletteMenuBtn;
189 WMView *customPaletteContentView;
191 /* Color List Panel */
192 WMFrame *colorListFrm;
193 WMPopUpButton *colorListHistoryBtn;
194 WMList *colorListContentLst;
195 WMPopUpButton *colorListColorMenuBtn;
196 WMPopUpButton *colorListListMenuBtn;
198 /* Look-Up Tables and Images */
199 wheelMatrix *wheelMtrx;
200 Pixmap wheelImg;
201 Pixmap selectionImg;
202 Pixmap selectionBackImg;
203 RImage *customPaletteImg;
204 char *lastBrowseDir;
206 /* Common Data Fields */
207 RColor color; /* Current color */
208 Bool colorSet; /* Is color already set ? */
209 RHSVColor hsvcolor; /* Backup HSV Color */
210 WMColorPanelMode mode; /* Current color selection mode */
211 WMColorPanelMode slidersmode;/* Current color sel. mode sliders panel */
212 WMColorPanelMode lastChanged;/* Panel that last changed the color */
213 int colx, coly; /* (x,y) of sel.-marker in WheelMode */
214 int palx, paly; /* (x,y) of sel.-marker in
215 CustomPaletteMode */
216 float palXRatio, palYRatio; /* Ratios in x & y between
217 original and scaled
218 palettesize */
219 int currentPalette;
220 char *configurationPath;
222 struct {
223 unsigned int continuous:1;
225 unsigned int dragging:1;
226 } flags;
227 } W_ColorPanel;
229 enum {
230 CPmenuNewFromFile,
231 CPmenuRename,
232 CPmenuRemove,
233 CPmenuCopy,
234 CPmenuNewFromClipboard
235 } customPaletteMenuItem;
237 enum {
238 CLmenuAdd,
239 CLmenuRename,
240 CLmenuRemove
241 } colorListMenuItem;
244 #define PWIDTH 194
245 #define PHEIGHT 266
246 #define colorWheelSize 150
247 #define customPaletteWidth 182
248 #define customPaletteHeight 106
249 #define knobThickness 8
251 #define SPECTRUM_WIDTH 511
252 #define SPECTRUM_HEIGHT 360
254 #define COLORWHEEL_PART 1
255 #define CUSTOMPALETTE_PART 2
256 #define BUFSIZE 1024
258 #undef EASTEREGG
260 #ifndef RGBTXT
261 #define RGBTXT "/usr/X11R6/lib/X11/rgb.txt"
262 #endif
264 #define MAX_LENGTH 1024
266 static int fetchFile(char* toPath, char *imageSrcFile,
267 char *imageDestFileName);
268 char *generateNewFilename(char *curName);
270 static void modeButtonCallback(WMWidget *w, void *data);
271 static int getPickerPart(W_ColorPanel *panel, int x, int y);
272 static void readConfiguration(W_ColorPanel *panel);
273 static void readXColors(W_ColorPanel *panel);
275 static void closeWindowCallback(WMWidget *w, void *data);
277 static Cursor magnifyGrabPointer(W_ColorPanel *panel);
278 static WMPoint magnifyInitialize(W_ColorPanel *panel);
279 static void magnifyPutCursor(WMWidget *w, void *data);
280 static Pixmap magnifyCreatePixmap(WMColorPanel *panel);
281 static Pixmap magnifyGetStorePixmap(W_ColorPanel *panel, int x1, int y1,
282 int x2, int y2);
283 static Pixmap magnifyGetImage(WMScreen *scr, int x, int y);
285 static wheelMatrix* wheelCreateMatrix(unsigned int width , unsigned int height);
286 static void wheelDestroyMatrix(wheelMatrix *matrix);
287 static wheelMatrix* wheelInitMatrix(W_ColorPanel *panel);
288 static void wheelRender(W_ColorPanel *panel);
289 static Bool wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs);
290 static void wheelPaint(W_ColorPanel *panel);
292 static void wheelHandleEvents(XEvent *event, void *data);
293 static void wheelHandleActionEvents(XEvent *event, void *data);
294 static void wheelBrightnessSliderCallback(WMWidget *w, void *data);
295 static void wheelUpdateSelection(W_ColorPanel *panel);
296 static void wheelUndrawSelection(W_ColorPanel *panel);
298 static void wheelPositionSelection(W_ColorPanel *panel, int x, int y);
299 static void wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y);
300 static void wheelUpdateBrightnessGradientFromHSV (W_ColorPanel *panel,
301 RHSVColor topColor);
302 static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel *panel);
303 static void wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor);
305 static void grayBrightnessSliderCallback(WMWidget *w, void *data);
306 static void grayPresetButtonCallback(WMWidget *w, void *data);
307 static void grayBrightnessTextFieldCallback(void *observerData,
308 WMNotification *notification);
310 static void rgbSliderCallback(WMWidget *w, void *data);
311 static void rgbTextFieldCallback(void *observerData,
312 WMNotification *notification);
314 static void cmykSliderCallback(WMWidget *w, void *data);
315 static void cmykTextFieldCallback(void *observerData,
316 WMNotification *notification);
318 static void hsbSliderCallback(WMWidget *w, void *data);
319 static void hsbTextFieldCallback(void *observerData,
320 WMNotification *notification);
321 static void hsbUpdateBrightnessGradient(W_ColorPanel *panel);
322 static void hsbUpdateSaturationGradient(W_ColorPanel *panel);
323 static void hsbUpdateHueGradient(W_ColorPanel *panel);
325 static void customRenderSpectrum(W_ColorPanel *panel);
326 static void customSetPalette(W_ColorPanel *panel);
327 static void customPaletteHandleEvents(XEvent *event, void *data);
328 static void customPaletteHandleActionEvents(XEvent *event, void *data);
329 static void customPalettePositionSelection(W_ColorPanel *panel, int x, int y);
330 static void customPalettePositionSelectionOutBounds(W_ColorPanel *panel,
331 int x, int y);
332 static void customPaletteMenuCallback(WMWidget *w, void *data);
333 static void customPaletteHistoryCallback(WMWidget *w, void *data);
335 static void customPaletteMenuNewFromFile(W_ColorPanel *panel);
336 static void customPaletteMenuRename(W_ColorPanel *panel);
337 static void customPaletteMenuRemove(W_ColorPanel *panel);
339 static void colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text,
340 int state, WMRect *rect);
341 static void colorListSelect(WMWidget *w, void *data);
342 static void colorListColorMenuCallback(WMWidget *w, void *data);
343 static void colorListListMenuCallback(WMWidget *w, void *data);
344 static void colorListListMenuNew(W_ColorPanel *panel);
346 static void wheelInit(W_ColorPanel *panel);
347 static void grayInit(W_ColorPanel *panel);
348 static void rgbInit(W_ColorPanel *panel);
349 static void cmykInit(W_ColorPanel *panel);
350 static void hsbInit(W_ColorPanel *panel);
354 void
355 WMSetColorPanelAction(WMColorPanel *panel, WMAction2 *action, void *data)
357 panel->action = action;
358 panel->clientData = data;
361 static WMColorPanel*
362 makeColorPanel(WMScreen *scrPtr, char *name)
364 WMColorPanel *panel;
365 RImage *image;
366 WMPixmap *pixmap;
367 RColor from;
368 RColor to;
369 WMColor *textcolor;
370 int i;
371 int x,y;
374 panel = wmalloc(sizeof(WMColorPanel));
375 memset(panel, 0, sizeof(WMColorPanel));
377 panel->colorSet = False; /* Color has not been set yet */
379 panel->font8 = WMSystemFontOfSize(scrPtr, 8);
380 panel->font12 = WMSystemFontOfSize(scrPtr, 12);
382 panel->win = WMCreateWindowWithStyle(scrPtr, name,
383 WMTitledWindowMask | WMClosableWindowMask | WMResizableWindowMask);
384 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
385 WMSetWindowTitle(panel->win, "Colors");
386 WMSetWindowCloseAction(panel->win, closeWindowCallback, panel);
389 /* Set Default ColorPanel Mode(s) */
390 panel->mode = WMWheelModeColorPanel;
391 panel->lastChanged = WMWheelModeColorPanel;
392 panel->slidersmode = WMRGBModeColorPanel;
393 panel->configurationPath = wstrappend(wusergnusteppath(),
394 "/Library/Colors/");
396 /* Some General Purpose Widgets */
397 panel->colorWell = WMCreateColorWell(panel->win);
398 WMResizeWidget(panel->colorWell, 134, 36);
399 WSetColorWellBordered(panel->colorWell, False);
400 WMMoveWidget(panel->colorWell, 56, 4);
402 panel->magnifyBtn = WMCreateCustomButton(panel->win,
403 WBBStateLightMask|WBBStateChangeMask);
404 WMResizeWidget(panel->magnifyBtn, 46, 36);
405 WMMoveWidget(panel->magnifyBtn, 6,4);
406 WMSetButtonAction(panel->magnifyBtn, magnifyPutCursor, panel);
407 WMSetButtonImagePosition(panel->magnifyBtn, WIPImageOnly);
408 WMSetButtonImage(panel->magnifyBtn, scrPtr->magnifyIcon);
410 panel->wheelBtn = WMCreateCustomButton(panel->win,
411 WBBStateLightMask|WBBStateChangeMask);
412 WMResizeWidget(panel->wheelBtn, 46, 32);
413 WMMoveWidget(panel->wheelBtn, 6, 44);
414 WMSetButtonAction(panel->wheelBtn, modeButtonCallback, panel);
415 WMSetButtonImagePosition(panel->wheelBtn, WIPImageOnly);
416 WMSetButtonImage(panel->wheelBtn, scrPtr->wheelIcon);
418 panel->slidersBtn = WMCreateCustomButton(panel->win,
419 WBBStateLightMask|WBBStateChangeMask);
420 WMResizeWidget(panel->slidersBtn, 46, 32);
421 WMMoveWidget(panel->slidersBtn, 52, 44);
422 WMSetButtonAction(panel->slidersBtn, modeButtonCallback, panel);
423 WMSetButtonImagePosition(panel->slidersBtn, WIPImageOnly);
424 WMSetButtonImage(panel->slidersBtn, scrPtr->rgbIcon);
426 panel->customPaletteBtn = WMCreateCustomButton(panel->win,
427 WBBStateLightMask|WBBStateChangeMask);
428 WMResizeWidget(panel->customPaletteBtn, 46, 32);
429 WMMoveWidget(panel->customPaletteBtn, 98, 44);
430 WMSetButtonAction(panel->customPaletteBtn, modeButtonCallback, panel);
431 WMSetButtonImagePosition(panel->customPaletteBtn, WIPImageOnly);
432 WMSetButtonImage(panel->customPaletteBtn, scrPtr->customPaletteIcon);
434 panel->colorListBtn = WMCreateCustomButton(panel->win,
435 WBBStateLightMask|WBBStateChangeMask);
436 WMResizeWidget(panel->colorListBtn, 46, 32);
437 WMMoveWidget(panel->colorListBtn, 144, 44);
438 WMSetButtonAction(panel->colorListBtn, modeButtonCallback, panel);
439 WMSetButtonImagePosition(panel->colorListBtn, WIPImageOnly);
440 WMSetButtonImage(panel->colorListBtn, scrPtr->colorListIcon);
442 /* Let's Group some of them together */
443 WMGroupButtons(panel->wheelBtn, panel->slidersBtn);
444 WMGroupButtons(panel->wheelBtn, panel->customPaletteBtn);
445 WMGroupButtons(panel->wheelBtn, panel->colorListBtn);
447 /* Widgets for the ColorWheel Panel */
448 panel->wheelFrm = WMCreateFrame(panel->win);
449 WMSetFrameRelief(panel->wheelFrm, WRFlat);
450 WMResizeWidget(panel->wheelFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
451 WMMoveWidget(panel->wheelFrm, 5, 80);
453 panel->wheelView = W_CreateView(W_VIEW(panel->wheelFrm));
454 /* XXX Can we create a view ? */
455 W_ResizeView(panel->wheelView, colorWheelSize+4, colorWheelSize+4);
456 W_MoveView(panel->wheelView, 0, 0);
458 /* Create an event handler to handle expose/click events in ColorWheel */
459 WMCreateEventHandler(panel->wheelView,
460 ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
461 LeaveWindowMask|ButtonMotionMask, wheelHandleActionEvents, panel);
463 WMCreateEventHandler(panel->wheelView, ExposureMask, wheelHandleEvents,
464 panel);
466 panel->wheelBrightnessS = WMCreateSlider(panel->wheelFrm);
467 WMResizeWidget(panel->wheelBrightnessS, 16, 153);
468 WMMoveWidget(panel->wheelBrightnessS, 5+colorWheelSize+14, 1);
469 WMSetSliderMinValue(panel->wheelBrightnessS, 0);
470 WMSetSliderMaxValue(panel->wheelBrightnessS, 255);
471 WMSetSliderAction(panel->wheelBrightnessS, wheelBrightnessSliderCallback,
472 panel);
473 WMSetSliderKnobThickness(panel->wheelBrightnessS, knobThickness);
476 /* Widgets for the Slider Panels */
477 panel->slidersFrm = WMCreateFrame(panel->win);
478 WMSetFrameRelief(panel->slidersFrm, WRFlat);
479 WMResizeWidget(panel->slidersFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
480 WMMoveWidget(panel->slidersFrm, 4, 80);
482 panel->seperatorFrm = WMCreateFrame(panel->slidersFrm);
483 WMSetFrameRelief(panel->seperatorFrm, WRPushed);
484 WMResizeWidget(panel->seperatorFrm, PWIDTH - 8, 2);
485 WMMoveWidget(panel->seperatorFrm, 0, 1);
487 panel->grayBtn = WMCreateCustomButton(panel->slidersFrm,
488 WBBStateLightMask|WBBStateChangeMask);
489 WMResizeWidget(panel->grayBtn, 46, 24);
490 WMMoveWidget(panel->grayBtn, 1, 8);
491 WMSetButtonAction(panel->grayBtn, modeButtonCallback, panel);
492 WMSetButtonImagePosition(panel->grayBtn, WIPImageOnly);
493 WMSetButtonImage(panel->grayBtn, scrPtr->grayIcon);
495 panel->rgbBtn = WMCreateCustomButton(panel->slidersFrm,
496 WBBStateLightMask|WBBStateChangeMask);
497 WMResizeWidget(panel->rgbBtn, 46, 24);
498 WMMoveWidget(panel->rgbBtn, 47, 8);
499 WMSetButtonAction(panel->rgbBtn, modeButtonCallback, panel);
500 WMSetButtonImagePosition(panel->rgbBtn, WIPImageOnly);
501 WMSetButtonImage(panel->rgbBtn, scrPtr->rgbIcon);
503 panel->cmykBtn = WMCreateCustomButton(panel->slidersFrm,
504 WBBStateLightMask|WBBStateChangeMask);
505 WMResizeWidget(panel->cmykBtn, 46, 24);
506 WMMoveWidget(panel->cmykBtn, 93, 8);
507 WMSetButtonAction(panel->cmykBtn, modeButtonCallback, panel);
508 WMSetButtonImagePosition(panel->cmykBtn, WIPImageOnly);
509 WMSetButtonImage(panel->cmykBtn, scrPtr->cmykIcon);
511 panel->hsbBtn = WMCreateCustomButton(panel->slidersFrm,
512 WBBStateLightMask|WBBStateChangeMask);
513 WMResizeWidget(panel->hsbBtn, 46, 24);
514 WMMoveWidget(panel->hsbBtn, 139, 8);
515 WMSetButtonAction(panel->hsbBtn, modeButtonCallback, panel);
516 WMSetButtonImagePosition(panel->hsbBtn, WIPImageOnly);
517 WMSetButtonImage(panel->hsbBtn, scrPtr->hsbIcon);
519 /* Let's Group the Slider Panel Buttons Together */
520 WMGroupButtons(panel->grayBtn, panel->rgbBtn);
521 WMGroupButtons(panel->grayBtn, panel->cmykBtn);
522 WMGroupButtons(panel->grayBtn, panel->hsbBtn);
524 textcolor = WMDarkGrayColor(scrPtr);
526 /* Widgets for GrayScale Panel */
527 panel->grayFrm = WMCreateFrame(panel->slidersFrm);
528 WMSetFrameRelief(panel->grayFrm, WRFlat);
529 WMResizeWidget(panel->grayFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
530 WMMoveWidget(panel->grayFrm, 0, 34);
532 panel->grayMinL = WMCreateLabel(panel->grayFrm);
533 WMResizeWidget(panel->grayMinL, 20, 10);
534 WMMoveWidget(panel->grayMinL, 2, 2);
535 WMSetLabelText(panel->grayMinL, "0");
536 WMSetLabelTextAlignment(panel->grayMinL, WALeft);
537 WMSetLabelTextColor(panel->grayMinL, textcolor);
538 WMSetLabelFont(panel->grayMinL, panel->font8);
540 panel->grayMaxL = WMCreateLabel(panel->grayFrm);
541 WMResizeWidget(panel->grayMaxL, 40, 10);
542 WMMoveWidget(panel->grayMaxL, 104, 2);
543 WMSetLabelText(panel->grayMaxL, "100");
544 WMSetLabelTextAlignment(panel->grayMaxL, WARight);
545 WMSetLabelTextColor(panel->grayMaxL, textcolor);
546 WMSetLabelFont(panel->grayMaxL, panel->font8);
548 panel->grayBrightnessS = WMCreateSlider(panel->grayFrm);
549 WMResizeWidget(panel->grayBrightnessS, 141, 16);
550 WMMoveWidget(panel->grayBrightnessS, 2, 14);
551 WMSetSliderMinValue(panel->grayBrightnessS, 0);
552 WMSetSliderMaxValue(panel->grayBrightnessS, 100);
553 WMSetSliderKnobThickness(panel->grayBrightnessS, knobThickness);
554 WMSetSliderAction(panel->grayBrightnessS, grayBrightnessSliderCallback,
555 panel);
557 from.red = 0;
558 from.green = 0;
559 from.blue = 0;
561 to.red = 255;
562 to.green = 255;
563 to.blue = 255;
565 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
566 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
567 RDestroyImage(image);
568 W_PaintText(W_VIEW(panel->grayBrightnessS), pixmap->pixmap,
569 panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->white),
570 False, "Brightness", strlen("Brightness"));
571 WMSetSliderImage(panel->grayBrightnessS, pixmap);
572 WMReleasePixmap(pixmap);
574 panel->grayBrightnessT = WMCreateTextField(panel->grayFrm);
575 WMResizeWidget(panel->grayBrightnessT, 40, 18);
576 WMMoveWidget(panel->grayBrightnessT, 146, 13);
577 WMSetTextFieldAlignment(panel->grayBrightnessT, WALeft);
578 WMAddNotificationObserver(grayBrightnessTextFieldCallback, panel,
579 WMTextDidEndEditingNotification, panel->grayBrightnessT);
581 image = RCreateImage(13,13,False);
582 for (i=0; i < 7; i++) {
583 for (x=0; x < 13; x++) {
584 for (y=0; y < 13; y++) {
585 image->data[0][y*13+x] = 255/6*i;
586 image->data[1][y*13+x] = 255/6*i;
587 image->data[2][y*13+x] = 255/6*i;
590 panel->grayPresetBtn[i] = WMCreateCommandButton(panel->grayFrm);
591 WMResizeWidget(panel->grayPresetBtn[i], 20, 24);
592 WMMoveWidget(panel->grayPresetBtn[i], 2+(i*20), 34);
593 WMSetButtonAction(panel->grayPresetBtn[i],
594 grayPresetButtonCallback, panel);
595 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
596 WMSetButtonImage(panel->grayPresetBtn[i], pixmap);
597 WMSetButtonImagePosition(panel->grayPresetBtn[i], WIPImageOnly);
598 WMReleasePixmap(pixmap);
600 RDestroyImage(image);
601 /* End of GrayScale Panel */
603 /* Widgets for RGB Panel */
604 panel->rgbFrm = WMCreateFrame(panel->slidersFrm);
605 WMSetFrameRelief(panel->rgbFrm, WRFlat);
606 WMResizeWidget(panel->rgbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
607 WMMoveWidget(panel->rgbFrm, 0, 34);
609 panel->rgbMinL = WMCreateLabel(panel->rgbFrm);
610 WMResizeWidget(panel->rgbMinL, 20, 10);
611 WMMoveWidget(panel->rgbMinL, 2, 2);
612 WMSetLabelText(panel->rgbMinL, "0");
613 WMSetLabelTextAlignment(panel->rgbMinL, WALeft);
614 WMSetLabelTextColor(panel->rgbMinL, textcolor);
615 WMSetLabelFont(panel->rgbMinL, panel->font8);
617 panel->rgbMaxL = WMCreateLabel(panel->rgbFrm);
618 WMResizeWidget(panel->rgbMaxL, 40, 10);
619 WMMoveWidget(panel->rgbMaxL, 104, 2);
620 WMSetLabelText(panel->rgbMaxL, "255");
621 WMSetLabelTextAlignment(panel->rgbMaxL, WARight);
622 WMSetLabelTextColor(panel->rgbMaxL, textcolor);
623 WMSetLabelFont(panel->rgbMaxL, panel->font8);
625 panel->rgbRedS = WMCreateSlider(panel->rgbFrm);
626 WMResizeWidget(panel->rgbRedS, 141, 16);
627 WMMoveWidget(panel->rgbRedS, 2, 14);
628 WMSetSliderMinValue(panel->rgbRedS, 0);
629 WMSetSliderMaxValue(panel->rgbRedS, 255);
630 WMSetSliderKnobThickness(panel->rgbRedS, knobThickness);
631 WMSetSliderAction(panel->rgbRedS, rgbSliderCallback, panel);
633 to.red = 255;
634 to.green = 0;
635 to.blue = 0;
637 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
638 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
639 W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12,
640 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Red",
641 strlen("Red"));
642 RDestroyImage(image);
643 WMSetSliderImage(panel->rgbRedS, pixmap);
644 WMReleasePixmap(pixmap);
646 panel->rgbRedT = WMCreateTextField(panel->rgbFrm);
647 WMResizeWidget(panel->rgbRedT, 40, 18);
648 WMMoveWidget(panel->rgbRedT, 146, 13);
649 WMSetTextFieldAlignment(panel->rgbRedT, WALeft);
650 WMAddNotificationObserver(rgbTextFieldCallback, panel,
651 WMTextDidEndEditingNotification, panel->rgbRedT);
654 panel->rgbGreenS = WMCreateSlider(panel->rgbFrm);
655 WMResizeWidget(panel->rgbGreenS, 141, 16);
656 WMMoveWidget(panel->rgbGreenS, 2, 36);
657 WMSetSliderMinValue(panel->rgbGreenS, 0);
658 WMSetSliderMaxValue(panel->rgbGreenS, 255);
659 WMSetSliderKnobThickness(panel->rgbGreenS, knobThickness);
660 WMSetSliderAction(panel->rgbGreenS, rgbSliderCallback, panel);
662 to.red = 0;
663 to.green = 255;
664 to.blue = 0;
666 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
667 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
668 W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12,
669 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Green",
670 strlen("Green"));
671 RDestroyImage(image);
672 WMSetSliderImage(panel->rgbGreenS, pixmap);
673 WMReleasePixmap(pixmap);
675 panel->rgbGreenT = WMCreateTextField(panel->rgbFrm);
676 WMResizeWidget(panel->rgbGreenT, 40, 18);
677 WMMoveWidget(panel->rgbGreenT, 146, 35);
678 WMSetTextFieldAlignment(panel->rgbGreenT, WALeft);
679 WMAddNotificationObserver(rgbTextFieldCallback, panel,
680 WMTextDidEndEditingNotification, panel->rgbGreenT);
683 panel->rgbBlueS = WMCreateSlider(panel->rgbFrm);
684 WMResizeWidget(panel->rgbBlueS, 141, 16);
685 WMMoveWidget(panel->rgbBlueS, 2, 58);
686 WMSetSliderMinValue(panel->rgbBlueS, 0);
687 WMSetSliderMaxValue(panel->rgbBlueS, 255);
688 WMSetSliderKnobThickness(panel->rgbBlueS, knobThickness);
689 WMSetSliderAction(panel->rgbBlueS, rgbSliderCallback, panel);
691 to.red = 0;
692 to.green = 0;
693 to.blue = 255;
695 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
696 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
697 W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12,
698 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Blue",
699 strlen("Blue"));
700 RDestroyImage(image);
701 WMSetSliderImage(panel->rgbBlueS, pixmap);
702 WMReleasePixmap(pixmap);
704 panel->rgbBlueT = WMCreateTextField(panel->rgbFrm);
705 WMResizeWidget(panel->rgbBlueT, 40, 18);
706 WMMoveWidget(panel->rgbBlueT, 146, 57);
707 WMSetTextFieldAlignment(panel->rgbBlueT, WALeft);
708 WMAddNotificationObserver(rgbTextFieldCallback, panel,
709 WMTextDidEndEditingNotification, panel->rgbBlueT);
710 /* End of RGB Panel */
712 /* Widgets for CMYK Panel */
713 panel->cmykFrm = WMCreateFrame(panel->slidersFrm);
714 WMSetFrameRelief(panel->cmykFrm, WRFlat);
715 WMResizeWidget(panel->cmykFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
716 WMMoveWidget(panel->cmykFrm, 0, 34);
718 panel->cmykMinL = WMCreateLabel(panel->cmykFrm);
719 WMResizeWidget(panel->cmykMinL, 20, 10);
720 WMMoveWidget(panel->cmykMinL, 2, 2);
721 WMSetLabelText(panel->cmykMinL, "0");
722 WMSetLabelTextAlignment(panel->cmykMinL, WALeft);
723 WMSetLabelTextColor(panel->cmykMinL, textcolor);
724 WMSetLabelFont(panel->cmykMinL, panel->font8);
726 panel->cmykMaxL = WMCreateLabel(panel->cmykFrm);
727 WMResizeWidget(panel->cmykMaxL, 40, 10);
728 WMMoveWidget(panel->cmykMaxL, 104, 2);
729 WMSetLabelText(panel->cmykMaxL, "100");
730 WMSetLabelTextAlignment(panel->cmykMaxL, WARight);
731 WMSetLabelTextColor(panel->cmykMaxL, textcolor);
732 WMSetLabelFont(panel->cmykMaxL, panel->font8);
734 panel->cmykCyanS = WMCreateSlider(panel->cmykFrm);
735 WMResizeWidget(panel->cmykCyanS, 141, 16);
736 WMMoveWidget(panel->cmykCyanS, 2, 14);
737 WMSetSliderMinValue(panel->cmykCyanS, 0);
738 WMSetSliderMaxValue(panel->cmykCyanS, 100);
739 WMSetSliderKnobThickness(panel->cmykCyanS, knobThickness);
740 WMSetSliderAction(panel->cmykCyanS, cmykSliderCallback, panel);
742 from.red = 255;
743 from.green = 255;
744 from.blue = 255;
746 to.red = 0;
747 to.green = 255;
748 to.blue = 255;
750 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
751 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
752 W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12,
753 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Cyan",
754 strlen("Cyan"));
755 RDestroyImage(image);
756 WMSetSliderImage(panel->cmykCyanS, pixmap);
757 WMReleasePixmap(pixmap);
759 panel->cmykCyanT = WMCreateTextField(panel->cmykFrm);
760 WMResizeWidget(panel->cmykCyanT, 40, 18);
761 WMMoveWidget(panel->cmykCyanT, 146, 13);
762 WMSetTextFieldAlignment(panel->cmykCyanT, WALeft);
763 WMAddNotificationObserver(cmykTextFieldCallback, panel,
764 WMTextDidEndEditingNotification, panel->cmykCyanT);
767 panel->cmykMagentaS = WMCreateSlider(panel->cmykFrm);
768 WMResizeWidget(panel->cmykMagentaS, 141, 16);
769 WMMoveWidget(panel->cmykMagentaS, 2, 36);
770 WMSetSliderMinValue(panel->cmykMagentaS, 0);
771 WMSetSliderMaxValue(panel->cmykMagentaS, 100);
772 WMSetSliderKnobThickness(panel->cmykMagentaS, knobThickness);
773 WMSetSliderAction(panel->cmykMagentaS, cmykSliderCallback, panel);
775 to.red = 255;
776 to.green = 0;
777 to.blue = 255;
779 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
780 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
781 W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12,
782 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Magenta",
783 strlen("Magenta"));
784 RDestroyImage(image);
785 WMSetSliderImage(panel->cmykMagentaS, pixmap);
786 WMReleasePixmap(pixmap);
788 panel->cmykMagentaT = WMCreateTextField(panel->cmykFrm);
789 WMResizeWidget(panel->cmykMagentaT, 40, 18);
790 WMMoveWidget(panel->cmykMagentaT, 146, 35);
791 WMSetTextFieldAlignment(panel->cmykMagentaT, WALeft);
792 WMAddNotificationObserver(cmykTextFieldCallback, panel,
793 WMTextDidEndEditingNotification, panel->cmykMagentaT);
796 panel->cmykYellowS = WMCreateSlider(panel->cmykFrm);
797 WMResizeWidget(panel->cmykYellowS, 141, 16);
798 WMMoveWidget(panel->cmykYellowS, 2, 58);
799 WMSetSliderMinValue(panel->cmykYellowS, 0);
800 WMSetSliderMaxValue(panel->cmykYellowS, 100);
801 WMSetSliderKnobThickness(panel->cmykYellowS, knobThickness);
802 WMSetSliderAction(panel->cmykYellowS, cmykSliderCallback, panel);
804 to.red = 255;
805 to.green = 255;
806 to.blue = 0;
808 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
809 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
810 W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12,
811 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Yellow",
812 strlen("Yellow"));
813 RDestroyImage(image);
814 WMSetSliderImage(panel->cmykYellowS, pixmap);
815 WMReleasePixmap(pixmap);
817 panel->cmykYellowT = WMCreateTextField(panel->cmykFrm);
818 WMResizeWidget(panel->cmykYellowT, 40, 18);
819 WMMoveWidget(panel->cmykYellowT, 146, 57);
820 WMSetTextFieldAlignment(panel->cmykYellowT, WALeft);
821 WMAddNotificationObserver(cmykTextFieldCallback, panel,
822 WMTextDidEndEditingNotification, panel->cmykYellowT);
825 panel->cmykBlackS = WMCreateSlider(panel->cmykFrm);
826 WMResizeWidget(panel->cmykBlackS, 141, 16);
827 WMMoveWidget(panel->cmykBlackS, 2, 80);
828 WMSetSliderMinValue(panel->cmykBlackS, 0);
829 WMSetSliderMaxValue(panel->cmykBlackS, 100);
830 WMSetSliderValue(panel->cmykBlackS, 0);
831 WMSetSliderKnobThickness(panel->cmykBlackS, knobThickness);
832 WMSetSliderAction(panel->cmykBlackS, cmykSliderCallback, panel);
834 to.red = 0;
835 to.green = 0;
836 to.blue = 0;
838 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
839 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
840 W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12,
841 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Black",
842 strlen("Black"));
843 RDestroyImage(image);
844 WMSetSliderImage(panel->cmykBlackS, pixmap);
845 WMReleasePixmap(pixmap);
847 panel->cmykBlackT = WMCreateTextField(panel->cmykFrm);
848 WMResizeWidget(panel->cmykBlackT, 40, 18);
849 WMMoveWidget(panel->cmykBlackT, 146, 79);
850 WMSetTextFieldAlignment(panel->cmykBlackT, WALeft);
851 WMAddNotificationObserver(cmykTextFieldCallback, panel,
852 WMTextDidEndEditingNotification, panel->cmykBlackT);
853 /* End of CMYK Panel */
855 /* Widgets for HSB Panel */
856 panel->hsbFrm = WMCreateFrame(panel->slidersFrm);
857 WMSetFrameRelief(panel->hsbFrm, WRFlat);
858 WMResizeWidget(panel->hsbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
859 WMMoveWidget(panel->hsbFrm, 0, 34);
861 panel->hsbHueS = WMCreateSlider(panel->hsbFrm);
862 WMResizeWidget(panel->hsbHueS, 141, 16);
863 WMMoveWidget(panel->hsbHueS, 2, 14);
864 WMSetSliderMinValue(panel->hsbHueS, 0);
865 WMSetSliderMaxValue(panel->hsbHueS, 359);
866 WMSetSliderKnobThickness(panel->hsbHueS, knobThickness);
867 WMSetSliderAction(panel->hsbHueS, hsbSliderCallback, panel);
869 panel->hsbHueT = WMCreateTextField(panel->hsbFrm);
870 WMResizeWidget(panel->hsbHueT, 40, 18);
871 WMMoveWidget(panel->hsbHueT, 146, 13);
872 WMSetTextFieldAlignment(panel->hsbHueT, WALeft);
873 WMAddNotificationObserver(hsbTextFieldCallback, panel,
874 WMTextDidEndEditingNotification, panel->hsbHueT);
877 panel->hsbSaturationS = WMCreateSlider(panel->hsbFrm);
878 WMResizeWidget(panel->hsbSaturationS, 141, 16);
879 WMMoveWidget(panel->hsbSaturationS, 2, 36);
880 WMSetSliderMinValue(panel->hsbSaturationS, 0);
881 WMSetSliderMaxValue(panel->hsbSaturationS, 100);
882 WMSetSliderKnobThickness(panel->hsbSaturationS, knobThickness);
883 WMSetSliderAction(panel->hsbSaturationS, hsbSliderCallback, panel);
885 panel->hsbSaturationT = WMCreateTextField(panel->hsbFrm);
886 WMResizeWidget(panel->hsbSaturationT, 40, 18);
887 WMMoveWidget(panel->hsbSaturationT, 146, 35);
888 WMSetTextFieldAlignment(panel->hsbSaturationT, WALeft);
889 WMAddNotificationObserver(hsbTextFieldCallback, panel,
890 WMTextDidEndEditingNotification, panel->hsbSaturationT);
893 panel->hsbBrightnessS = WMCreateSlider(panel->hsbFrm);
894 WMResizeWidget(panel->hsbBrightnessS, 141, 16);
895 WMMoveWidget(panel->hsbBrightnessS, 2, 58);
896 WMSetSliderMinValue(panel->hsbBrightnessS, 0);
897 WMSetSliderMaxValue(panel->hsbBrightnessS, 100);
898 WMSetSliderKnobThickness(panel->hsbBrightnessS, knobThickness);
899 WMSetSliderAction(panel->hsbBrightnessS, hsbSliderCallback, panel);
901 panel->hsbBrightnessT = WMCreateTextField(panel->hsbFrm);
902 WMResizeWidget(panel->hsbBrightnessT, 40, 18);
903 WMMoveWidget(panel->hsbBrightnessT, 146, 57);
904 WMSetTextFieldAlignment(panel->hsbBrightnessT, WALeft);
905 WMAddNotificationObserver(hsbTextFieldCallback, panel,
906 WMTextDidEndEditingNotification, panel->hsbBrightnessT);
907 /* End of HSB Panel */
910 WMReleaseColor(textcolor);
912 /* Widgets for the CustomPalette Panel */
913 panel->customPaletteFrm = WMCreateFrame(panel->win);
914 WMSetFrameRelief(panel->customPaletteFrm, WRFlat);
915 WMResizeWidget(panel->customPaletteFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
916 WMMoveWidget(panel->customPaletteFrm, 5, 80);
918 panel->customPaletteHistoryBtn = WMCreatePopUpButton(
919 panel->customPaletteFrm);
920 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, "Spectrum");
921 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
922 WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn)-1);
923 WMSetPopUpButtonAction(panel->customPaletteHistoryBtn,
924 customPaletteHistoryCallback, panel);
925 WMResizeWidget(panel->customPaletteHistoryBtn, PWIDTH - 8, 20);
926 WMMoveWidget(panel->customPaletteHistoryBtn, 0, 0);
928 panel->customPaletteContentFrm = WMCreateFrame(panel->customPaletteFrm);
929 WMSetFrameRelief(panel->customPaletteContentFrm, WRSunken);
930 WMResizeWidget(panel->customPaletteContentFrm, PWIDTH - 8, PHEIGHT - 156);
931 WMMoveWidget(panel->customPaletteContentFrm, 0, 23);
933 panel->customPaletteContentView = W_CreateView(
934 W_VIEW(panel->customPaletteContentFrm));
935 /* XXX Can we create a view ? */
936 W_ResizeView(panel->customPaletteContentView, customPaletteWidth,
937 customPaletteHeight);
938 W_MoveView(panel->customPaletteContentView, 2, 2);
940 /* Create event handler to handle expose/click events in CustomPalette */
941 WMCreateEventHandler(panel->customPaletteContentView,
942 ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
943 LeaveWindowMask|ButtonMotionMask, customPaletteHandleActionEvents,
944 panel);
946 WMCreateEventHandler(panel->customPaletteContentView, ExposureMask,
947 customPaletteHandleEvents, panel);
949 panel->customPaletteMenuBtn = WMCreatePopUpButton(panel->customPaletteFrm);
950 WMSetPopUpButtonPullsDown(panel->customPaletteMenuBtn, 1);
951 WMSetPopUpButtonText(panel->customPaletteMenuBtn, "Palette");
952 WMSetPopUpButtonAction(panel->customPaletteMenuBtn,
953 customPaletteMenuCallback, panel);
954 WMResizeWidget(panel->customPaletteMenuBtn, PWIDTH - 8, 20);
955 WMMoveWidget(panel->customPaletteMenuBtn, 0, PHEIGHT - 130);
957 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from File...");
958 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Rename...");
959 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Remove");
960 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Copy");
961 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from Clipboard");
963 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, 0);
964 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, 0);
965 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuCopy, 0);
966 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn,
967 CPmenuNewFromClipboard, 0);
969 customRenderSpectrum(panel);
970 panel->currentPalette = 0;
973 /* Widgets for the ColorList Panel */
974 panel->colorListFrm = WMCreateFrame(panel->win);
975 WMSetFrameRelief(panel->colorListFrm, WRFlat);
976 WMResizeWidget(panel->colorListFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
977 WMMoveWidget(panel->colorListFrm, 5, 80);
979 panel->colorListHistoryBtn = WMCreatePopUpButton(panel->colorListFrm);
980 WMAddPopUpButtonItem(panel->colorListHistoryBtn, "X11-Colors");
981 WMSetPopUpButtonSelectedItem(panel->colorListHistoryBtn,
982 WMGetPopUpButtonNumberOfItems(panel->colorListHistoryBtn)-1);
983 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
984 * colorListHistoryCallback, panel); */
985 WMResizeWidget(panel->colorListHistoryBtn, PWIDTH - 8, 20);
986 WMMoveWidget(panel->colorListHistoryBtn, 0, 0);
988 panel->colorListContentLst = WMCreateList(panel->colorListFrm);
989 WMSetListAction(panel->colorListContentLst, colorListSelect, panel);
990 WMSetListUserDrawProc(panel->colorListContentLst, colorListPaintItem);
991 WMResizeWidget(panel->colorListContentLst, PWIDTH - 8, PHEIGHT - 156);
992 WMMoveWidget(panel->colorListContentLst, 0, 23);
993 WMHangData(panel->colorListContentLst, panel);
995 panel->colorListColorMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
996 WMSetPopUpButtonPullsDown(panel->colorListColorMenuBtn, 1);
997 WMSetPopUpButtonText(panel->colorListColorMenuBtn, "Color");
998 WMSetPopUpButtonAction(panel->colorListColorMenuBtn,
999 colorListColorMenuCallback, panel);
1000 WMResizeWidget(panel->colorListColorMenuBtn, (PWIDTH - 16)/2, 20);
1001 WMMoveWidget(panel->colorListColorMenuBtn, 0, PHEIGHT - 130);
1003 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Add...");
1004 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Rename...");
1005 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Remove");
1007 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuAdd, 0);
1008 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRename, 0);
1009 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRemove, 0);
1011 panel->colorListListMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
1012 WMSetPopUpButtonPullsDown(panel->colorListListMenuBtn, 1);
1013 WMSetPopUpButtonText(panel->colorListListMenuBtn, "List");
1014 WMSetPopUpButtonAction(panel->colorListListMenuBtn,
1015 colorListListMenuCallback, panel);
1016 WMResizeWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2, 20);
1017 WMMoveWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2 + 8,
1018 PHEIGHT - 130);
1020 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "New...");
1021 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Rename...");
1022 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Remove");
1024 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRename, 0);
1025 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRemove, 0);
1027 WMRealizeWidget(panel->win);
1028 WMMapSubwidgets(panel->win);
1030 WMMapSubwidgets(panel->wheelFrm);
1031 WMMapSubwidgets(panel->slidersFrm);
1032 WMMapSubwidgets(panel->grayFrm);
1033 WMMapSubwidgets(panel->rgbFrm);
1034 WMMapSubwidgets(panel->cmykFrm);
1035 WMMapSubwidgets(panel->hsbFrm);
1036 WMMapSubwidgets(panel->customPaletteFrm);
1037 WMMapSubwidgets(panel->customPaletteContentFrm);
1038 WMMapSubwidgets(panel->colorListFrm);
1040 readConfiguration(panel);
1041 readXColors(panel);
1043 return panel;
1047 WMColorPanel*
1048 WMGetColorPanel(WMScreen *scrPtr)
1050 WMColorPanel *panel;
1052 if (scrPtr->sharedColorPanel)
1053 return scrPtr->sharedColorPanel;
1055 panel = makeColorPanel(scrPtr, "colorPanel");
1057 scrPtr->sharedColorPanel = panel;
1059 return panel;
1063 void
1064 WMFreeColorPanel(WMColorPanel *panel)
1066 W_Screen *scr = WMWidgetScreen(panel->win);
1068 if (panel == scr->sharedColorPanel) {
1069 scr->sharedColorPanel = NULL;
1072 WMRemoveNotificationObserver(panel);
1074 WMUnmapWidget(panel->win);
1075 WMDestroyWidget(panel->win);
1077 /* fonts */
1078 if (panel->font8)
1079 WMReleaseFont(panel->font8);
1080 if (panel->font12)
1081 WMReleaseFont(panel->font12);
1083 /* pixmaps */
1084 if (panel->wheelMtrx)
1085 wheelDestroyMatrix(panel->wheelMtrx);
1086 if (panel->wheelImg)
1087 XFreePixmap(scr->display, panel->wheelImg);
1088 if (panel->selectionImg)
1089 XFreePixmap(scr->display, panel->selectionImg);
1090 if (panel->selectionBackImg)
1091 XFreePixmap(scr->display, panel->selectionBackImg);
1092 if (panel->customPaletteImg)
1093 RDestroyImage(panel->customPaletteImg);
1095 /* structs */
1096 if (panel->lastBrowseDir)
1097 free(panel->lastBrowseDir);
1098 if (panel->configurationPath)
1099 free(panel->configurationPath);
1101 free(panel);
1105 void
1106 WMCloseColorPanel(WMColorPanel *panel)
1108 WMCloseWindow(panel->win);
1109 WMFreeColorPanel(panel);
1113 void
1114 WMShowColorPanel(WMColorPanel *panel)
1116 WMScreen *scr = WMWidgetScreen(panel->win);
1117 WMColor *white = WMWhiteColor(scr);
1119 if (!panel->colorSet )
1120 WMSetColorPanelColor(panel, white);
1121 WMReleaseColor(white);
1123 WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel);
1124 wheelInit(panel);
1126 WMMapWidget(panel->win);
1130 static void
1131 closeWindowCallback(WMWidget *w, void *data)
1133 W_ColorPanel *panel = (W_ColorPanel*)data;
1135 WMCloseColorPanel(panel);
1139 static void
1140 readConfiguration(W_ColorPanel *panel)
1142 /* XXX Doesn't take care of "invalid" files */
1144 DIR *dPtr;
1145 struct dirent *dp;
1146 struct stat stat_buf;
1149 if (stat(panel->configurationPath, &stat_buf)!=0) {
1150 if (mkdir(panel->configurationPath,
1151 S_IRWXU|S_IRGRP|S_IROTH|S_IXGRP|S_IXOTH)!=0) {
1152 wsyserror("ColorPanel could not create directory %s needed"
1153 " to store configurations", panel->configurationPath);
1154 WMSetPopUpButtonEnabled(panel->customPaletteMenuBtn, False);
1155 WMSetPopUpButtonEnabled(panel->colorListColorMenuBtn, False);
1156 WMSetPopUpButtonEnabled(panel->colorListListMenuBtn, False);
1157 WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win,
1158 "File Error", "Could not create ColorPanel configuration"
1159 " directory", "OK", NULL, NULL);
1161 return;
1164 dPtr = opendir(panel->configurationPath);
1165 while ((dp = readdir(dPtr)) != NULL) {
1166 if (dp->d_name[0] != '.')
1167 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, dp->d_name);
1169 (void)closedir(dPtr);
1173 static void
1174 readXColors(W_ColorPanel *panel)
1176 struct stat stat_buf;
1177 FILE *rgbtxt;
1178 char line[MAX_LENGTH];
1179 int red, green, blue;
1180 char name[48];
1181 RColor *color;
1182 WMListItem *item;
1184 if (stat(RGBTXT, &stat_buf) != 0) {
1185 wwarning("Cannot find file %s", RGBTXT);
1186 return;
1188 else {
1189 rgbtxt = fopen(RGBTXT, "r");
1190 if (rgbtxt) {
1191 while (fgets(line, MAX_LENGTH, rgbtxt)) {
1192 if (sscanf(line, "%d%d%d %[^\n]", &red, &green, &blue, name)) {
1193 color = wmalloc(sizeof(RColor));
1194 color->red = (unsigned char)red;
1195 color->green = (unsigned char)green;
1196 color->blue = (unsigned char)blue;
1197 item = WMAddListItem(panel->colorListContentLst, name);
1198 item->clientData = (void *)color;
1201 fclose(rgbtxt);
1203 else {
1204 wsyserror("Unable to open file %s for reading", RGBTXT);
1210 void
1211 WMSetColorPanelPickerMode(WMColorPanel *panel, WMColorPanelMode mode)
1213 W_Screen *scr = WMWidgetScreen(panel->win);
1215 if (mode != WMWheelModeColorPanel) {
1216 WMUnmapWidget(panel->wheelFrm);
1217 if (panel->selectionBackImg) {
1218 XFreePixmap(WMWidgetScreen(panel->win)->display,
1219 panel->selectionBackImg);
1220 panel->selectionBackImg = None;
1223 if (mode != WMGrayModeColorPanel)
1224 WMUnmapWidget(panel->grayFrm);
1225 if (mode != WMRGBModeColorPanel)
1226 WMUnmapWidget(panel->rgbFrm);
1227 if (mode != WMCMYKModeColorPanel)
1228 WMUnmapWidget(panel->cmykFrm);
1229 if (mode != WMHSBModeColorPanel)
1230 WMUnmapWidget(panel->hsbFrm);
1231 if (mode != WMCustomPaletteModeColorPanel) {
1232 WMUnmapWidget(panel->customPaletteFrm);
1233 if (panel->selectionBackImg) {
1234 XFreePixmap(WMWidgetScreen(panel->win)->display,
1235 panel->selectionBackImg);
1236 panel->selectionBackImg = None;
1239 if (mode != WMColorListModeColorPanel)
1240 WMUnmapWidget(panel->colorListFrm);
1241 if ((mode != WMGrayModeColorPanel) && (mode != WMRGBModeColorPanel) &&
1242 (mode != WMCMYKModeColorPanel) && (mode != WMHSBModeColorPanel))
1243 WMUnmapWidget(panel->slidersFrm);
1244 else
1245 panel->slidersmode = mode;
1247 if (mode == WMWheelModeColorPanel) {
1248 WMMapWidget(panel->wheelFrm);
1249 WMSetButtonSelected(panel->wheelBtn, True);
1250 if (panel->lastChanged != WMWheelModeColorPanel)
1251 wheelInit(panel);
1252 wheelRender(panel);
1253 wheelPaint(panel);
1254 } else if (mode == WMGrayModeColorPanel) {
1255 WMMapWidget(panel->slidersFrm);
1256 WMSetButtonSelected(panel->slidersBtn, True);
1257 WMMapWidget(panel->grayFrm);
1258 WMSetButtonSelected(panel->grayBtn, True);
1259 WMSetButtonImage(panel->slidersBtn, scr->grayIcon);
1260 if (panel->lastChanged != WMGrayModeColorPanel)
1261 grayInit(panel);
1262 } else if (mode == WMRGBModeColorPanel) {
1263 WMMapWidget(panel->slidersFrm);
1264 WMSetButtonSelected(panel->slidersBtn, True);
1265 WMMapWidget(panel->rgbFrm);
1266 WMSetButtonSelected(panel->rgbBtn, True);
1267 WMSetButtonImage(panel->slidersBtn, scr->rgbIcon);
1268 if (panel->lastChanged != WMRGBModeColorPanel)
1269 rgbInit(panel);
1270 } else if (mode == WMCMYKModeColorPanel) {
1271 WMMapWidget(panel->slidersFrm);
1272 WMSetButtonSelected(panel->slidersBtn, True);
1273 WMMapWidget(panel->cmykFrm);
1274 WMSetButtonSelected(panel->cmykBtn, True);
1275 WMSetButtonImage(panel->slidersBtn, scr->cmykIcon);
1276 if (panel->lastChanged != WMCMYKModeColorPanel)
1277 cmykInit(panel);
1278 } else if (mode == WMHSBModeColorPanel) {
1279 WMMapWidget(panel->slidersFrm);
1280 WMSetButtonSelected(panel->slidersBtn, True);
1281 WMMapWidget(panel->hsbFrm);
1282 WMSetButtonSelected(panel->hsbBtn, True);
1283 WMSetButtonImage(panel->slidersBtn, scr->hsbIcon);
1284 if (panel->lastChanged != WMHSBModeColorPanel)
1285 hsbInit(panel);
1286 } else if (mode == WMCustomPaletteModeColorPanel) {
1287 WMMapWidget(panel->customPaletteFrm);
1288 WMSetButtonSelected(panel->customPaletteBtn, True);
1289 customSetPalette(panel);
1290 } else if (mode == WMColorListModeColorPanel) {
1291 WMMapWidget(panel->colorListFrm);
1292 WMSetButtonSelected(panel->colorListBtn, True);
1295 panel->mode = mode;
1299 WMColor*
1300 WMGetColorPanelColor(WMColorPanel *panel)
1302 return WMGetColorWellColor(panel->colorWell);
1306 void
1307 WMSetColorPanelColor(WMColorPanel *panel, WMColor *color)
1309 WMScreen *scr = WMWidgetScreen(panel->win);
1310 RHSVColor hsvcolor;
1311 RColor intcolor;
1312 GC bgc = WMColorGC(scr->black);
1313 GC wgc = WMColorGC(scr->white);
1314 int originalHue;
1316 WMSetColorWellColor(panel->colorWell, color);
1318 intcolor.red = color->color.red >> 8;
1319 intcolor.green = color->color.green >> 8;
1320 intcolor.blue = color->color.blue >> 8;
1322 panel->color = intcolor;
1323 panel->colorSet = True;
1325 /* If color was set by HSB-Panel do not convert back to hsv */
1326 if (panel->lastChanged != WMHSBModeColorPanel) {
1328 /* if color is black, hue is undetermined, so it must be restored */
1329 if ((panel->color.red == 0) &&
1330 (panel->color.green == 0) &&
1331 (panel->color.blue == 0) &&
1332 (panel->hsvcolor.hue <= 359))
1334 originalHue = panel->hsvcolor.hue;
1335 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1336 panel->hsvcolor.hue = originalHue;
1337 } else {
1338 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1342 panel->wheelMtrx = wheelInitMatrix(panel); /* Needs to be done After Color is set */
1344 /* Maybe put this in a sub-function ... Initialising selected images */
1345 RRGBtoHSV(&intcolor, &hsvcolor);
1346 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 +
1347 (hsvcolor.saturation/255.0) * cos( hsvcolor.hue*M_PI/180.0)));
1348 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 +
1349 (hsvcolor.saturation/255.0) * sin(-hsvcolor.hue*M_PI/180.0)));
1350 wheelUpdateBrightnessGradientFromHSV(panel, hsvcolor);
1351 WMSetSliderValue(panel->wheelBrightnessS, 255 - hsvcolor.value);
1353 panel->selectionImg = XCreatePixmap(scr->display,
1354 W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
1355 XFillRectangle(scr->display, panel->selectionImg, bgc, 0, 0, 4, 4);
1356 XFillRectangle(scr->display, panel->selectionImg, wgc, 1, 1, 2, 2);
1357 /* End of initialisation section */
1359 panel->palx = customPaletteWidth/2;
1360 panel->paly = customPaletteHeight/2;
1362 WMSetColorPanelPickerMode(panel, panel->mode);
1366 static void
1367 updateSwatch(WMColorPanel *panel, RColor color)
1369 WMScreen *scr = WMWidgetScreen(panel->win);
1370 WMColor *wellcolor;
1371 int originalHue;
1373 wellcolor = WMCreateRGBColor(scr, color.red << 8, color.green << 8,
1374 color.blue << 8, True);
1376 WMSetColorWellColor(panel->colorWell, wellcolor);
1377 WMReleaseColor(wellcolor);
1379 panel->color = color;
1381 /* If color was set by HSB-Panel do not convert back to hsv */
1382 if (panel->lastChanged != WMHSBModeColorPanel) {
1384 /* if color is black, hue is undetermined, so it must be restored */
1385 if ((panel->color.red == 0) &&
1386 (panel->color.green == 0) &&
1387 (panel->color.blue == 0) &&
1388 (panel->hsvcolor.hue <= 359))
1390 originalHue = panel->hsvcolor.hue;
1391 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1392 panel->hsvcolor.hue = originalHue;
1393 } else {
1394 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1398 if (!panel->flags.dragging || panel->flags.continuous) {
1399 if (panel->action)
1400 (*panel->action)(panel, panel->clientData);
1402 WMPostNotificationName(WMColorPanelColorChangedNotification, panel,
1403 NULL);
1407 static void
1408 modeButtonCallback(WMWidget *w, void *data)
1410 W_ColorPanel *panel = (W_ColorPanel*)(data);
1412 if (w == panel->wheelBtn)
1413 WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel);
1414 else if (w == panel->slidersBtn)
1415 WMSetColorPanelPickerMode(panel, panel->slidersmode);
1416 else if (w == panel->customPaletteBtn)
1417 WMSetColorPanelPickerMode(panel, WMCustomPaletteModeColorPanel);
1418 else if (w == panel->colorListBtn)
1419 WMSetColorPanelPickerMode(panel, WMColorListModeColorPanel);
1420 else if (w == panel->grayBtn)
1421 WMSetColorPanelPickerMode(panel, WMGrayModeColorPanel);
1422 else if (w == panel->rgbBtn)
1423 WMSetColorPanelPickerMode(panel, WMRGBModeColorPanel);
1424 else if (w == panel->cmykBtn)
1425 WMSetColorPanelPickerMode(panel, WMCMYKModeColorPanel);
1426 else if (w == panel->hsbBtn)
1427 WMSetColorPanelPickerMode(panel, WMHSBModeColorPanel);
1431 /****************** Magnifying Cursor Functions *******************/
1432 static Pixmap
1433 magnifyGetImage(WMScreen *scr, int x, int y)
1435 XImage *image;
1436 Pixmap pixmap;
1437 int x0, y0, w0, h0;
1438 int displayWidth = DisplayWidth(scr->display, scr->screen);
1439 int displayHeight = DisplayHeight(scr->display, scr->screen);
1440 const int half_mask_width = (Cursor_mask_width +1)/2;
1441 const int half_mask_height = (Cursor_mask_height +1)/2;
1443 /* Coordinate correction for back pixmap
1444 * if magnifying glass is at screen-borders */
1445 x0 = 0; y0 = 0; w0 = Cursor_mask_width; h0 = Cursor_mask_height;
1447 if (x < half_mask_width) {
1448 if (x < 0) x = 0;
1449 x0 = half_mask_width - x;
1450 w0 = Cursor_mask_width - x0;
1453 if (x > displayWidth - half_mask_width) {
1454 if (x > displayWidth) x = displayWidth;
1455 w0 = Cursor_mask_width - (half_mask_width - (displayWidth - x));
1458 if (y < half_mask_height) {
1459 if (y < 0) y = 0;
1460 y0 = half_mask_height - y;
1461 h0 = Cursor_mask_height - y0;
1464 if (y > displayHeight - half_mask_height) {
1465 if (y > displayHeight) y = displayHeight;
1466 h0 = Cursor_mask_height - (half_mask_height - (displayHeight - y));
1468 /* end of coordinate correction */
1470 image = XGetImage(scr->display, scr->rootWin, x + x0 - Cursor_x_hot,
1471 y + y0 - Cursor_y_hot, w0, h0, AllPlanes, ZPixmap);
1473 pixmap = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1474 Cursor_mask_height, scr->depth);
1475 XPutImage(scr->display, pixmap, scr->copyGC, image, 0, 0, x0, y0, w0, h0);
1476 XDestroyImage(image);
1478 return pixmap;
1482 static Pixmap
1483 magnifyGetStorePixmap(WMColorPanel *panel, int x1, int y1, int x2, int y2)
1486 * (x1, y1) = topleft corner of existing rectangle
1487 * (x2, y2) = topleft corner of new position
1490 W_Screen *scr = WMWidgetScreen(panel->win);
1491 Pixmap pixmap;
1492 int xa, ya, xb, yb, w, h;
1494 if (x1 < x2) {
1495 xa = x2 - x1;
1496 xb = 0;
1497 } else {
1498 xa = 0;
1499 xb = x1 - x2;
1502 if (y1 < y2) {
1503 ya = y2 - y1;
1504 yb = 0;
1505 } else {
1506 ya = 0;
1507 yb = y1 - y2;
1510 w = Cursor_mask_width - abs(x1-x2);
1511 h = Cursor_mask_height - abs(y1-y2);
1513 /* Get pixmap from screen */
1514 pixmap = magnifyGetImage(scr, x2, y2);
1516 /* Copy previously stored pixmap on covered part of above pixmap */
1517 if (panel->magnifyGlass->valid)
1519 XCopyArea(scr->display, panel->magnifyGlass->pixmap, pixmap,
1520 scr->copyGC, xa, ya, w, h, xb, yb);
1522 /* Free it, so we can reuse it */
1523 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1526 return pixmap;
1530 static Pixmap
1531 magnifyCreatePixmap(WMColorPanel *panel)
1533 W_Screen *scr = WMWidgetScreen(panel->win);
1534 int u, v;
1535 int i, j;
1536 int ofs;
1537 Pixmap magPix;
1538 Pixmap backPix;
1539 RImage *pixelImg;
1540 const int half_mask_width = Cursor_mask_width/2;
1541 const int half_mask_height = Cursor_mask_height/2;
1545 * Get image
1548 /* Rectangle that's going to be the background */
1549 backPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1550 Cursor_mask_height , scr->depth);
1551 XCopyArea(scr->display, panel->magnifyGlass->pixmap, backPix, scr->copyGC,
1552 0, 0, Cursor_mask_width, Cursor_mask_height, 0, 0);
1555 * Magnify image
1558 magPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width +2,
1559 Cursor_mask_height +2, scr->depth);
1561 for (u=0; u<5+1; u++) /* Copy an area of 5x5 pixels from the center */
1562 for (v=0; v<5+1; v++)
1563 for (i=u*5; i < (u+1)*5; i++) /* magnify it 5 times */
1564 for (j=v*5; j < (v+1)*5; j++)
1565 XCopyArea(scr->display, backPix, magPix, scr->copyGC,
1566 u +9, v +9, 1, 1, i, j);
1568 /* Get color under hotspot */
1569 ofs = half_mask_width + half_mask_height * Cursor_mask_width;
1570 pixelImg = RCreateImageFromDrawable(scr->rcontext, backPix, backPix);
1571 panel->magnifyGlass->color.red = pixelImg->data[0][ofs];
1572 panel->magnifyGlass->color.green = pixelImg->data[1][ofs];
1573 panel->magnifyGlass->color.blue = pixelImg->data[2][ofs];
1574 RDestroyImage(pixelImg);
1576 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1577 XSetClipMask(scr->display, scr->clipGC, panel->magnifyGlass->mask);
1578 XSetClipOrigin(scr->display, scr->clipGC, 0, 0);
1580 XCopyArea(scr->display, magPix, backPix, scr->clipGC, 2, 2,
1581 Cursor_mask_width, Cursor_mask_height, 0, 0);
1582 /* (2,2) puts center pixel on center of glass */
1584 XFreePixmap(scr->display, magPix);
1586 return backPix;
1590 static WMView*
1591 magnifyCreateView(W_ColorPanel *panel)
1593 W_Screen *scr = WMWidgetScreen(panel->win);
1594 WMView *magView;
1596 magView = W_CreateTopView(scr);
1598 W_ResizeView(magView, Cursor_mask_width, Cursor_mask_height);
1600 magView->attribFlags |= CWOverrideRedirect | CWSaveUnder;
1601 magView->attribs.event_mask = StructureNotifyMask;
1602 magView->attribs.override_redirect = True;
1603 magView->attribs.save_under = True;
1605 W_RealizeView(magView);
1607 return magView;
1611 static Cursor
1612 magnifyGrabPointer(W_ColorPanel *panel)
1614 W_Screen *scr = WMWidgetScreen(panel->win);
1615 Pixmap magPixmap, magPixmap2;
1616 Cursor magCursor;
1617 XColor fgColor = {0, 0,0,0, DoRed|DoGreen|DoBlue};
1618 XColor bgColor = {0, 0xbf00, 0xa000, 0x5000, DoRed|DoGreen|DoBlue};
1620 /* Cursor creation stuff */
1621 magPixmap = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1622 Cursor_bits, Cursor_width, Cursor_height, 1, 0, 1);
1623 magPixmap2 = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1624 Cursor_shape_bits, Cursor_width, Cursor_height, 1, 0, 1);
1626 magCursor = XCreatePixmapCursor(scr->display, magPixmap, magPixmap2,
1627 &fgColor, &bgColor, Cursor_x_hot, Cursor_y_hot);
1629 XFreePixmap(scr->display, magPixmap);
1630 XFreePixmap(scr->display, magPixmap2);
1632 XRecolorCursor(scr->display, magCursor, &fgColor, &bgColor);
1634 /* Set up Pointer */
1635 XGrabPointer (scr->display, panel->magnifyGlass->view->window, True,
1636 PointerMotionMask | ButtonPressMask,
1637 GrabModeAsync, GrabModeAsync,
1638 scr->rootWin, magCursor, CurrentTime);
1640 return magCursor;
1644 static WMPoint
1645 magnifyInitialize(W_ColorPanel *panel)
1647 W_Screen *scr = WMWidgetScreen(panel->win);
1648 int x, y, u, v;
1649 unsigned int mask;
1650 Pixmap pixmap;
1651 WMPoint point;
1653 XQueryPointer(scr->display, scr->rootWin, &scr->rootWin,
1654 &W_VIEW(panel->win)->window, &x, &y, &u, &v, &mask);
1657 /* Clipmask to make magnified view-contents circular */
1658 panel->magnifyGlass->mask = XCreatePixmapFromBitmapData(scr->display,
1659 W_DRAWABLE(scr), Cursor_mask_bits,
1660 Cursor_mask_width, Cursor_mask_height, 1, 0, 1);
1662 /* Draw initial magnified part */
1663 panel->magnifyGlass->valid = False;
1664 /* also free's magnifyGlass->pixmap */
1665 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(panel, x, y, x, y);
1666 panel->magnifyGlass->valid = True;
1668 pixmap = magnifyCreatePixmap(panel);
1670 XSetWindowBackgroundPixmap(scr->display, panel->magnifyGlass->view->window,
1671 pixmap);
1672 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1673 XFlush(scr->display);
1675 XFreePixmap(scr->display, pixmap);
1677 point.x = x;
1678 point.y = y;
1680 return point;
1684 static void
1685 magnifyPutCursor(WMWidget *w, void *data)
1687 W_ColorPanel *panel = (W_ColorPanel*)(data);
1688 W_Screen *scr = WMWidgetScreen(panel->win);
1689 Cursor magCursor;
1690 int x, y;
1691 Pixmap pixmap;
1692 XEvent event;
1693 WMPoint initialPosition;
1695 /* Destroy wheelBackImg, so it'll update properly */
1696 if (panel->selectionBackImg) {
1697 XFreePixmap(WMWidgetScreen(panel->win)->display,
1698 panel->selectionBackImg);
1699 panel->selectionBackImg = None;
1702 /* Create magnifying glass */
1703 panel->magnifyGlass = wmalloc(sizeof(MovingView));
1704 panel->magnifyGlass->view = magnifyCreateView(panel);
1706 initialPosition = magnifyInitialize(panel);
1707 x = initialPosition.x;
1708 y = initialPosition.y;
1710 W_MoveView(panel->magnifyGlass->view,
1711 x - Cursor_x_hot +1,
1712 y - Cursor_y_hot +1);
1713 W_MapView(panel->magnifyGlass->view);
1715 magCursor = magnifyGrabPointer(panel);
1717 while(panel->magnifyGlass->valid)
1719 WMNextEvent(scr->display, &event);
1720 while (XCheckTypedEvent(scr->display, MotionNotify, &event)) {
1723 switch (event.type)
1725 case ButtonPress:
1726 if (event.xbutton.button == Button1) {
1727 updateSwatch(panel, panel->magnifyGlass->color);
1729 switch (panel->mode) {
1730 case WMWheelModeColorPanel:
1731 wheelInit(panel);
1732 wheelRender(panel);
1733 wheelPaint(panel);
1734 break;
1735 case WMGrayModeColorPanel:
1736 grayInit(panel);
1737 break;
1738 case WMRGBModeColorPanel:
1739 rgbInit(panel);
1740 break;
1741 case WMCMYKModeColorPanel:
1742 cmykInit(panel);
1743 break;
1744 case WMHSBModeColorPanel:
1745 hsbInit(panel);
1746 break;
1747 default:
1748 break;
1750 panel->lastChanged = panel->mode;
1751 panel->magnifyGlass->valid = False;
1752 WMSetButtonSelected(panel->magnifyBtn, False);
1753 break;
1755 case MotionNotify:
1756 /* Get a "dirty rectangle" */
1757 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(
1758 panel, x+1, y+1,
1759 event.xmotion.x_root+1, event.xmotion.y_root+1);
1760 /* also free's magnifyGlass->pixmap */
1762 /* Update coordinates */
1763 x = event.xmotion.x_root;
1764 y = event.xmotion.y_root;
1766 /* Move view */
1767 W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot +1,
1768 y - Cursor_y_hot +1);
1770 /* Put new image (with magn.) in view */
1771 pixmap = magnifyCreatePixmap(panel);
1772 XSetWindowBackgroundPixmap(scr->display,
1773 panel->magnifyGlass->view->window, pixmap);
1774 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1776 XFreePixmap(scr->display, pixmap);
1777 break;
1779 case FocusOut: /* fall through */
1780 case FocusIn:
1782 * Color Panel window (panel->win) lost or received focus.
1783 * We need to update the pixmap in the magnifying glass.
1785 XUngrabPointer(scr->display, CurrentTime);
1786 W_UnmapView(panel->magnifyGlass->view);
1788 magnifyInitialize(panel);
1790 W_MapView(panel->magnifyGlass->view);
1791 XGrabPointer (scr->display,
1792 panel->magnifyGlass->view->window,
1793 True,
1794 PointerMotionMask | ButtonPressMask,
1795 GrabModeAsync,
1796 GrabModeAsync,
1797 scr->rootWin,
1798 magCursor,
1799 CurrentTime);
1800 break;
1802 default:
1803 WMHandleEvent(&event);
1804 break;
1805 } /* of switch */
1807 panel->magnifyGlass->valid = False;
1809 XUngrabPointer(scr->display, CurrentTime);
1810 XFreeCursor(scr->display, magCursor);
1811 W_DestroyView(panel->magnifyGlass->view);
1813 XFreePixmap(scr->display, panel->magnifyGlass->mask);
1814 panel->magnifyGlass->mask = None;
1816 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1817 panel->magnifyGlass->pixmap = None;
1819 free(panel->magnifyGlass);
1824 /****************** WheelMatrix Functions ************************/
1826 static wheelMatrix*
1827 wheelCreateMatrix(unsigned int width, unsigned int height)
1829 wheelMatrix *matrix = NULL;
1830 int i;
1832 assert((width > 0) && (height > 0));
1834 matrix = malloc(sizeof(wheelMatrix));
1835 if (!matrix) {
1836 RErrorCode = RERR_NOMEMORY;
1837 return NULL;
1840 memset(matrix, 0, sizeof(wheelMatrix));
1841 matrix->width = width;
1842 matrix->height = height;
1843 for (i = 0; i < 3; i++) {
1844 matrix->data[i] = malloc(width*height*sizeof(unsigned char));
1845 if (!matrix->data[i])
1846 goto error;
1849 return matrix;
1851 error:
1852 for (i = 0; i < 3; i++) {
1853 if (matrix->data[i])
1854 free(matrix->data[i]);
1856 if (matrix)
1857 free(matrix);
1858 RErrorCode = RERR_NOMEMORY;
1859 return NULL;
1863 static void
1864 wheelDestroyMatrix(wheelMatrix *matrix)
1866 int i;
1868 assert (matrix!=NULL);
1870 for (i = 0; i < 3; i++) {
1871 if (matrix->data[i])
1872 free(matrix->data[i]);
1874 free(matrix);
1878 static wheelMatrix*
1879 wheelInitMatrix(W_ColorPanel *panel)
1881 int i;
1882 int x,y;
1883 wheelMatrix *matrix;
1884 unsigned char *rp, *gp, *bp;
1885 RHSVColor cur_hsv;
1886 RColor cur_rgb;
1887 long ofs[4];
1888 float hue;
1889 int sat;
1890 float xcor, ycor;
1891 int dhue[4];
1893 matrix = wheelCreateMatrix(colorWheelSize+4, colorWheelSize+4);
1894 if (!matrix)
1895 return NULL;
1897 RRGBtoHSV(&panel->color, &cur_hsv);
1899 for (i = 0; i < 256; i++)
1900 matrix->values[i] = (unsigned char)(rint(i*cur_hsv.value/255));
1902 cur_hsv.value = 255;
1904 ofs[0] = -1;
1905 ofs[1] = -(colorWheelSize + 4);
1906 /* ofs[2] = 0; superfluous
1907 ofs[3] = 0;
1909 for (y = 0; y < (colorWheelSize+4)/2; y++) {
1910 for (x = y; x < (colorWheelSize+4-y); x++) {
1911 xcor = ((float)(2.0*x - 4.0) / colorWheelSize) - 1;
1912 ycor = ((float)(2.0*y - 4.0) / colorWheelSize) - 1;
1914 sat = rint(255.0 * sqrt((xcor*xcor) + (ycor*ycor)));
1918 /* offsets are counterclockwise (in triangles) */
1920 /* top quarter */
1921 if (y < (colorWheelSize+4)/2)
1922 ofs[0]++;
1924 /* left quarter */
1925 ofs[1] += colorWheelSize + 4;
1927 /* bottom quarter */
1928 ofs[2] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[0];
1930 /* right quarter */
1931 ofs[3] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[1];
1933 if (sat < 256) {
1934 cur_hsv.saturation = (unsigned char)sat;
1936 if (xcor != 0)
1937 hue = atan(ycor/xcor);
1938 else {
1939 if (ycor > 0)
1940 hue = M_PI * 0.5;
1941 else
1942 hue = M_PI * 1.5;
1945 if (xcor < 0)
1946 hue += M_PI;
1947 if ((xcor > 0) && (ycor < 0))
1948 hue += M_PI * 2.0;
1950 hue = -hue; /* Reverse direction of ColorWheel */
1952 if (hue < 0)
1953 hue += M_PI * 2.0;
1955 dhue[0] = (hue*360) / (M_PI * 2.0);
1957 for (i = 0; i < 4; i++) {
1959 if (i > 0)
1960 dhue[i] = (dhue[i-1] + 90) % 360;
1962 if ((i == 1) || (i == 3))
1963 dhue[i] = 360 - dhue[i];
1965 if (i == 2)
1966 dhue[i] = 360 - dhue[i] + 180;
1968 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1969 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1970 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1972 cur_hsv.hue = dhue[i];
1973 RHSVtoRGB(&cur_hsv, &cur_rgb);
1975 *rp = (unsigned char)(cur_rgb.red);
1976 *gp = (unsigned char)(cur_rgb.green);
1977 *bp = (unsigned char)(cur_rgb.blue);
1980 else {
1981 for (i = 0; i < 4; i++) {
1982 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1983 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1984 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1986 *rp = (unsigned char)(0);
1987 *gp = (unsigned char)(0);
1988 *bp = (unsigned char)(0);
1992 if (y < (colorWheelSize+4)/2)
1993 ofs[0] += 2*y+1;
1995 ofs[1] += 1 - (colorWheelSize + 4) * (colorWheelSize + 4 - 1 - 2*y);
1998 return matrix;
2001 /****************** ColorWheel Functions *******************/
2003 static void
2004 wheelRender(W_ColorPanel *panel)
2006 W_Screen *scr = WMWidgetScreen(panel->win);
2007 int x,y;
2008 RImage *image;
2009 unsigned char *rp, *gp, *bp;
2010 RColor gray;
2011 unsigned long ofs;
2013 image = RCreateImage(colorWheelSize+4, colorWheelSize+4, False);
2014 if (!image)
2015 return;
2017 gray.red = gray.green = gray.blue = 0xaa;
2019 for (x = 0; x < colorWheelSize+4; x++) {
2020 for (y = 0; y < colorWheelSize+4; y++) {
2022 ofs = (y * image->width) + x;
2023 rp = image->data[0] + ofs;
2024 gp = image->data[1] + ofs;
2025 bp = image->data[2] + ofs;
2027 if (wheelInsideColorWheel(panel, ofs)) {
2028 *rp = (unsigned int)(panel->wheelMtrx->values[
2029 panel->wheelMtrx->data[0][ofs] ]);
2030 *gp = (unsigned int)(panel->wheelMtrx->values[
2031 panel->wheelMtrx->data[1][ofs] ]);
2032 *bp = (unsigned int)(panel->wheelMtrx->values[
2033 panel->wheelMtrx->data[2][ofs] ]);
2035 else {
2036 *rp = (unsigned char)(gray.red);
2037 *gp = (unsigned char)(gray.green);
2038 *bp = (unsigned char)(gray.blue);
2043 if (panel->wheelImg)
2044 XFreePixmap(scr->display, panel->wheelImg);
2046 panel->wheelImg = XCreatePixmap(scr->display, W_DRAWABLE(scr),
2047 colorWheelSize+4, colorWheelSize+4, scr->depth);
2048 RConvertImage(scr->rcontext, image, &panel->wheelImg);
2050 /* Check if backimage exists. If it doesn't, allocate and fill it */
2051 if (!panel->selectionBackImg) {
2052 panel->selectionBackImg = XCreatePixmap(scr->display,
2053 W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
2054 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg,
2055 scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0);
2056 /* -2 is hot spot correction */
2059 RDestroyImage(image);
2062 static Bool
2063 wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs)
2065 return ((panel->wheelMtrx->data[0][ofs] != 0) &&
2066 (panel->wheelMtrx->data[1][ofs] != 0) &&
2067 (panel->wheelMtrx->data[2][ofs] != 0));
2070 static void
2071 wheelPaint (W_ColorPanel *panel)
2073 W_Screen *scr = WMWidgetScreen(panel->win);
2075 XCopyArea(scr->display, panel->wheelImg, panel->wheelView->window,
2076 scr->copyGC, 0, 0, colorWheelSize+4, colorWheelSize+4, 0, 0);
2078 /* Draw selection image */
2079 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window,
2080 scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
2083 static void
2084 wheelHandleEvents(XEvent *event, void *data)
2086 W_ColorPanel *panel = (W_ColorPanel*)data;
2088 switch (event->type) {
2089 case Expose:
2090 if (event->xexpose.count != 0)
2091 break;
2092 wheelPaint(panel);
2093 break;
2097 static void
2098 wheelHandleActionEvents(XEvent *event, void *data)
2100 W_ColorPanel *panel = (W_ColorPanel*)data;
2102 switch (event->type) {
2103 case ButtonPress:
2104 if (getPickerPart(panel, event->xbutton.x, event->xbutton.y) ==
2105 COLORWHEEL_PART) {
2106 panel->flags.dragging = 1;
2107 wheelPositionSelection(panel, event->xbutton.x,
2108 event->xbutton.y);
2110 break;
2112 case ButtonRelease:
2113 panel->flags.dragging = 0;
2114 if (!panel->flags.continuous) {
2115 if (panel->action)
2116 (*panel->action)(panel, panel->clientData);
2118 break;
2120 case MotionNotify:
2121 if (panel->flags.dragging) {
2122 if (getPickerPart(panel, event->xmotion.x, event->xmotion.y) ==
2123 COLORWHEEL_PART) {
2124 wheelPositionSelection(panel, event->xmotion.x,
2125 event->xmotion.y);
2127 else
2128 wheelPositionSelectionOutBounds(panel, event->xmotion.x,
2129 event->xmotion.y);
2131 break;
2136 static int
2137 getPickerPart(W_ColorPanel *panel, int x, int y)
2139 int lx, ly;
2140 unsigned long ofs;
2142 lx = x;
2143 ly = y;
2145 if (panel->mode == WMWheelModeColorPanel) {
2146 if ((lx >= 2) && (lx <= 2+colorWheelSize) && (ly >= 2) &&
2147 (ly <= 2+colorWheelSize)) {
2149 ofs = ly*panel->wheelMtrx->width+lx;
2151 if (wheelInsideColorWheel(panel, ofs))
2152 return COLORWHEEL_PART;
2156 if (panel->mode == WMCustomPaletteModeColorPanel) {
2157 if ((lx >= 2) && (lx < customPaletteWidth-2) && (ly >= 2) &&
2158 (ly < customPaletteHeight-2)) {
2159 return CUSTOMPALETTE_PART;
2163 return 0;
2167 static void
2168 wheelBrightnessSliderCallback(WMWidget *w, void *data)
2170 int i;
2171 unsigned int v;
2172 int value;
2173 unsigned long ofs;
2174 RColor cur_rgb;
2176 W_ColorPanel *panel = (W_ColorPanel*)data;
2178 value = 255-WMGetSliderValue(panel->wheelBrightnessS);
2180 for (i = 0; i < 256; i++) {
2181 /* We divide by 128 in advance, and check whether that number divides
2182 * by 2 properly. If not, we add one to round the number correctly
2184 v = (i*value) >> 7;
2185 #ifdef EASTEREGG
2186 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + v);
2187 #else
2188 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) +(v & 0x01));
2189 #endif
2192 ofs = (panel->coly * panel->wheelMtrx->width) + panel->colx;
2194 if (!wheelInsideColorWheel(panel, ofs)) {
2195 panel->hsvcolor.saturation = 255;
2196 panel->hsvcolor.value = value;
2197 RHSVtoRGB(&panel->hsvcolor, &cur_rgb);
2199 panel->color = cur_rgb;
2201 else {
2202 panel->color.red = panel->wheelMtrx->values[
2203 panel->wheelMtrx->data[0][ofs] ];
2204 panel->color.green = panel->wheelMtrx->values[
2205 panel->wheelMtrx->data[1][ofs] ];
2206 panel->color.blue = panel->wheelMtrx->values[
2207 panel->wheelMtrx->data[2][ofs] ];
2210 wheelRender(panel);
2211 wheelPaint(panel);
2212 wheelUpdateSelection(panel);
2216 static void
2217 wheelUpdateSelection(W_ColorPanel *panel)
2219 W_Screen *scr = WMWidgetScreen(panel->win);
2221 updateSwatch(panel, panel->color);
2222 panel->lastChanged = WMWheelModeColorPanel;
2224 /* Redraw color selector (and make a backup of the part it will cover) */
2225 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg,
2226 scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0);
2227 /* "-2" is correction for hotspot location */
2228 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window,
2229 scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
2230 /* see above */
2233 static void
2234 wheelUndrawSelection(W_ColorPanel *panel)
2236 W_Screen *scr = WMWidgetScreen(panel->win);
2238 XCopyArea(scr->display, panel->selectionBackImg, panel->wheelView->window,
2239 scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
2240 /* see above */
2243 static void
2244 wheelPositionSelection(W_ColorPanel *panel, int x, int y)
2246 unsigned long ofs = (y * panel->wheelMtrx->width)+ x;
2249 panel->color.red = panel->wheelMtrx->values[
2250 panel->wheelMtrx->data[0][ofs] ];
2251 panel->color.green = panel->wheelMtrx->values[
2252 panel->wheelMtrx->data[1][ofs] ];
2253 panel->color.blue = panel->wheelMtrx->values[
2254 panel->wheelMtrx->data[2][ofs] ];
2256 wheelUndrawSelection(panel);
2258 panel->colx = x;
2259 panel->coly = y;
2261 wheelUpdateSelection(panel);
2262 wheelUpdateBrightnessGradientFromLocation(panel);
2265 static void
2266 wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2268 RHSVColor cur_hsv;
2269 float hue;
2270 float xcor, ycor;
2272 xcor = ((x*2.0) / (colorWheelSize+4)) - 1.0;
2273 ycor = ((y*2.0) / (colorWheelSize+4)) - 1.0;
2275 cur_hsv.saturation = 255;
2276 cur_hsv.value = 255 - WMGetSliderValue(panel->wheelBrightnessS);
2278 if (xcor != 0)
2279 hue = atan(ycor/xcor);
2280 else {
2281 if (ycor > 0)
2282 hue = M_PI * 0.5;
2283 else
2284 hue = M_PI * 1.5;
2287 if (xcor < 0)
2288 hue += M_PI;
2289 if ((xcor > 0) && (ycor < 0))
2290 hue += M_PI * 2.0;
2292 hue = -hue;
2294 if (hue < 0)
2295 hue += M_PI * 2.0;
2297 cur_hsv.hue = (hue*180.0)/(M_PI);
2298 RHSVtoRGB(&cur_hsv, &panel->color);
2300 wheelUndrawSelection(panel);
2302 panel->colx = 2 + rint((colorWheelSize * (1.0 +
2303 cos( cur_hsv.hue*M_PI/180))) /2.0);
2304 /* "+2" because of "colorWheelSize + 4" */
2305 panel->coly = 2 + rint((colorWheelSize * (1.0 +
2306 sin(-cur_hsv.hue*M_PI/180))) /2.0);
2308 wheelUpdateSelection(panel);
2309 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
2312 static void
2313 wheelUpdateBrightnessGradientFromHSV(W_ColorPanel *panel, RHSVColor topColor)
2315 RColor from;
2317 /* Update Brightness-Slider */
2318 topColor.value = 255;
2319 RHSVtoRGB(&topColor, &from);
2321 wheelUpdateBrightnessGradient(panel, from);
2324 static void
2325 wheelUpdateBrightnessGradientFromLocation(W_ColorPanel *panel)
2327 RColor from;
2328 unsigned long ofs;
2330 ofs = panel->coly * panel->wheelMtrx->width + panel->colx;
2332 from.red = panel->wheelMtrx->data[0][ofs];
2333 from.green = panel->wheelMtrx->data[1][ofs];
2334 from.blue = panel->wheelMtrx->data[2][ofs];
2336 wheelUpdateBrightnessGradient(panel, from);
2339 static void
2340 wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor)
2342 RColor to;
2343 RImage *sliderImg;
2344 WMPixmap *sliderPxmp;
2346 to.red = to.green = to.blue = 0;
2348 sliderImg = RRenderGradient(16, 153, &topColor, &to, RGRD_VERTICAL);
2349 sliderPxmp = WMCreatePixmapFromRImage(WMWidgetScreen(panel->win),
2350 sliderImg, 0);
2351 RDestroyImage(sliderImg);
2352 WMSetSliderImage(panel->wheelBrightnessS, sliderPxmp);
2353 WMReleasePixmap(sliderPxmp);
2356 /****************** Grayscale Panel Functions ***************/
2358 static void
2359 grayBrightnessSliderCallback(WMWidget *w, void *data)
2361 RColor color;
2362 int value;
2363 char tmp[4];
2365 W_ColorPanel *panel = (W_ColorPanel*)data;
2367 value = WMGetSliderValue(panel->grayBrightnessS);
2369 sprintf(tmp, "%d", value);
2371 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2372 color.red = color.green = color.blue = rint(2.55*value);
2374 updateSwatch(panel, color);
2375 panel->lastChanged = WMGrayModeColorPanel;
2378 static void
2379 grayPresetButtonCallback(WMWidget *w, void *data)
2381 RColor color;
2382 char tmp[4];
2383 int value;
2384 int i=0;
2386 W_ColorPanel *panel = (W_ColorPanel*)data;
2388 while (i < 7) {
2389 if (w == panel->grayPresetBtn[i])
2390 break;
2391 i++;
2394 value = rint(100.0/6.0*i);
2395 sprintf(tmp, "%d", value);
2397 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2398 color.red = color.green = color.blue = rint(255.0*i/6.0);
2400 WMSetSliderValue(panel->grayBrightnessS, rint(100.0*i/6.0));
2402 updateSwatch(panel, color);
2403 panel->lastChanged = WMGrayModeColorPanel;
2406 static void
2407 grayBrightnessTextFieldCallback(void *observerData,
2408 WMNotification *notification)
2410 RColor color;
2411 char tmp[4];
2412 int value;
2413 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2415 value = atoi(WMGetTextFieldText(panel->grayBrightnessT));
2416 if (value > 100)
2417 value = 100;
2418 if (value < 0)
2419 value = 0;
2421 sprintf(tmp, "%d", value);
2422 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2423 WMSetSliderValue(panel->grayBrightnessS, value);
2425 color.red = color.green = color.blue = rint(255.0*value/100.0);
2426 updateSwatch(panel, color);
2427 panel->lastChanged = WMGrayModeColorPanel;
2430 /******************* RGB Panel Functions *****************/
2432 static void
2433 rgbSliderCallback(WMWidget *w, void *data)
2435 RColor color;
2436 int value[3];
2437 char tmp[4];
2439 W_ColorPanel *panel = (W_ColorPanel*)data;
2441 value[0] = WMGetSliderValue(panel->rgbRedS);
2442 value[1] = WMGetSliderValue(panel->rgbGreenS);
2443 value[2] = WMGetSliderValue(panel->rgbBlueS);
2445 sprintf(tmp, "%d", value[0]);
2446 WMSetTextFieldText(panel->rgbRedT, tmp);
2447 sprintf(tmp, "%d", value[1]);
2448 WMSetTextFieldText(panel->rgbGreenT, tmp);
2449 sprintf(tmp, "%d", value[2]);
2450 WMSetTextFieldText(panel->rgbBlueT, tmp);
2452 color.red = value[0];
2453 color.green = value[1];
2454 color.blue = value[2];
2456 updateSwatch(panel, color);
2457 panel->lastChanged = WMRGBModeColorPanel;
2460 static void
2461 rgbTextFieldCallback(void *observerData, WMNotification *notification)
2463 RColor color;
2464 int value[3];
2465 char tmp[4];
2466 int n;
2467 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2469 value[0] = atoi(WMGetTextFieldText(panel->rgbRedT));
2470 value[1] = atoi(WMGetTextFieldText(panel->rgbGreenT));
2471 value[2] = atoi(WMGetTextFieldText(panel->rgbBlueT));
2473 for (n=0; n < 3; n++) {
2474 if (value[n] > 255)
2475 value[n] = 255;
2476 if (value[n] < 0)
2477 value[n] = 0;
2480 sprintf(tmp, "%d", value[0]);
2481 WMSetTextFieldText(panel->rgbRedT, tmp);
2482 sprintf(tmp, "%d", value[1]);
2483 WMSetTextFieldText(panel->rgbGreenT, tmp);
2484 sprintf(tmp, "%d", value[2]);
2485 WMSetTextFieldText(panel->rgbBlueT, tmp);
2487 WMSetSliderValue(panel->rgbRedS, value[0]);
2488 WMSetSliderValue(panel->rgbGreenS, value[1]);
2489 WMSetSliderValue(panel->rgbBlueS, value[2]);
2491 color.red = value[0];
2492 color.green = value[1];
2493 color.blue = value[2];
2495 updateSwatch(panel, color);
2496 panel->lastChanged = WMRGBModeColorPanel;
2500 /******************* CMYK Panel Functions *****************/
2502 static void
2503 cmykSliderCallback(WMWidget *w, void *data)
2505 RColor color;
2506 int value[4];
2507 char tmp[4];
2509 W_ColorPanel *panel = (W_ColorPanel*)data;
2511 value[0] = WMGetSliderValue(panel->cmykCyanS);
2512 value[1] = WMGetSliderValue(panel->cmykMagentaS);
2513 value[2] = WMGetSliderValue(panel->cmykYellowS);
2514 value[3] = WMGetSliderValue(panel->cmykBlackS);
2516 sprintf(tmp, "%d", value[0]);
2517 WMSetTextFieldText(panel->cmykCyanT, tmp);
2518 sprintf(tmp, "%d", value[1]);
2519 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2520 sprintf(tmp, "%d", value[2]);
2521 WMSetTextFieldText(panel->cmykYellowT, tmp);
2522 sprintf(tmp, "%d", value[3]);
2523 WMSetTextFieldText(panel->cmykBlackT, tmp);
2525 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2526 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3]/100.0)));
2527 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] /100.0)));
2529 updateSwatch(panel, color);
2530 panel->lastChanged = WMCMYKModeColorPanel;
2533 static void
2534 cmykTextFieldCallback(void *observerData, WMNotification *notification)
2536 RColor color;
2537 int value[4];
2538 char tmp[4];
2539 int n;
2540 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2542 value[0] = atoi(WMGetTextFieldText(panel->cmykCyanT));
2543 value[1] = atoi(WMGetTextFieldText(panel->cmykMagentaT));
2544 value[2] = atoi(WMGetTextFieldText(panel->cmykYellowT));
2545 value[3] = atoi(WMGetTextFieldText(panel->cmykBlackT));
2547 for (n=0; n < 4; n++) {
2548 if (value[n] > 100)
2549 value[n] = 100;
2550 if (value[n] < 0)
2551 value[n] = 0;
2554 sprintf(tmp, "%d", value[0]);
2555 WMSetTextFieldText(panel->cmykCyanT, tmp);
2556 sprintf(tmp, "%d", value[1]);
2557 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2558 sprintf(tmp, "%d", value[2]);
2559 WMSetTextFieldText(panel->cmykYellowT, tmp);
2560 sprintf(tmp, "%d", value[3]);
2561 WMSetTextFieldText(panel->cmykBlackT, tmp);
2563 WMSetSliderValue(panel->cmykCyanS, value[0]);
2564 WMSetSliderValue(panel->cmykMagentaS, value[1]);
2565 WMSetSliderValue(panel->cmykYellowS, value[2]);
2566 WMSetSliderValue(panel->cmykBlackS, value[3]);
2568 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2569 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3]/100.0)));
2570 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] /100.0)));
2572 updateSwatch(panel, color);
2573 panel->lastChanged = WMCMYKModeColorPanel;
2576 /********************** HSB Panel Functions ***********************/
2578 static void
2579 hsbSliderCallback(WMWidget *w, void *data)
2581 RColor color;
2582 int value[3];
2583 char tmp[4];
2585 W_ColorPanel *panel = (W_ColorPanel*)data;
2587 value[0] = WMGetSliderValue(panel->hsbHueS);
2588 value[1] = WMGetSliderValue(panel->hsbSaturationS);
2589 value[2] = WMGetSliderValue(panel->hsbBrightnessS);
2591 sprintf(tmp, "%d", value[0]);
2592 WMSetTextFieldText(panel->hsbHueT, tmp);
2593 sprintf(tmp, "%d", value[1]);
2594 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2595 sprintf(tmp, "%d", value[2]);
2596 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2598 panel->hsvcolor.hue = value[0];
2599 panel->hsvcolor.saturation = value[1]*2.55;
2600 panel->hsvcolor.value = value[2]*2.55;
2602 RHSVtoRGB(&panel->hsvcolor, &color);
2604 panel->lastChanged = WMHSBModeColorPanel;
2605 updateSwatch(panel, color);
2607 if (w != panel->hsbBrightnessS)
2608 hsbUpdateBrightnessGradient(panel);
2609 if (w != panel->hsbSaturationS)
2610 hsbUpdateSaturationGradient(panel);
2611 if (w != panel->hsbHueS)
2612 hsbUpdateHueGradient(panel);
2615 static void
2616 hsbTextFieldCallback(void *observerData, WMNotification *notification)
2618 RColor color;
2619 int value[3];
2620 char tmp[4];
2621 int n;
2622 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2624 value[0] = atoi(WMGetTextFieldText(panel->hsbHueT));
2625 value[1] = atoi(WMGetTextFieldText(panel->hsbSaturationT));
2626 value[2] = atoi(WMGetTextFieldText(panel->hsbBrightnessT));
2628 if (value[0] > 359)
2629 value[0] = 359;
2630 if (value[0] < 0)
2631 value[0] = 0;
2633 for (n=1; n < 3; n++) {
2634 if (value[n] > 100)
2635 value[n] = 100;
2636 if (value[n] < 0)
2637 value[n] = 0;
2640 sprintf(tmp, "%d", value[0]);
2641 WMSetTextFieldText(panel->hsbHueT, tmp);
2642 sprintf(tmp, "%d", value[1]);
2643 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2644 sprintf(tmp, "%d", value[2]);
2645 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2647 WMSetSliderValue(panel->hsbHueS, value[0]);
2648 WMSetSliderValue(panel->hsbSaturationS, value[1]);
2649 WMSetSliderValue(panel->hsbBrightnessS, value[2]);
2651 panel->hsvcolor.hue = value[0];
2652 panel->hsvcolor.saturation = value[1]*2.55;
2653 panel->hsvcolor.value = value[2]*2.55;
2655 RHSVtoRGB(&panel->hsvcolor, &color);
2657 panel->lastChanged = WMHSBModeColorPanel;
2658 updateSwatch(panel, color);
2660 hsbUpdateBrightnessGradient(panel);
2661 hsbUpdateSaturationGradient(panel);
2662 hsbUpdateHueGradient(panel);
2665 static void
2666 hsbUpdateBrightnessGradient(W_ColorPanel *panel)
2668 W_Screen *scr = WMWidgetScreen(panel->win);
2669 RColor from;
2670 RColor to;
2671 RHSVColor hsvcolor;
2672 RImage *sliderImg;
2673 WMPixmap *sliderPxmp;
2675 from.red = from.green = from.blue = 0;
2676 hsvcolor = panel->hsvcolor;
2677 hsvcolor.value = 255;
2679 RHSVtoRGB(&hsvcolor, &to);
2681 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2682 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2683 RDestroyImage(sliderImg);
2684 W_PaintText(W_VIEW(panel->hsbBrightnessS), sliderPxmp->pixmap,
2685 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
2686 "Brightness", strlen("Brightness"));
2687 WMSetSliderImage(panel->hsbBrightnessS, sliderPxmp);
2688 WMReleasePixmap(sliderPxmp);
2691 static void
2692 hsbUpdateSaturationGradient(W_ColorPanel *panel)
2694 W_Screen *scr = WMWidgetScreen(panel->win);
2695 RColor from;
2696 RColor to;
2697 RHSVColor hsvcolor;
2698 RImage *sliderImg;
2699 WMPixmap *sliderPxmp;
2701 hsvcolor = panel->hsvcolor;
2702 hsvcolor.saturation = 0;
2703 RHSVtoRGB(&hsvcolor, &from);
2705 hsvcolor.saturation = 255;
2706 RHSVtoRGB(&hsvcolor, &to);
2708 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2709 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2710 RDestroyImage(sliderImg);
2711 if (hsvcolor.value < 128)
2712 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap,
2713 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
2714 "Saturation", strlen("Saturation"));
2715 else
2716 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap,
2717 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False,
2718 "Saturation", strlen("Saturation"));
2720 WMSetSliderImage(panel->hsbSaturationS, sliderPxmp);
2721 WMReleasePixmap(sliderPxmp);
2724 static void
2725 hsbUpdateHueGradient(W_ColorPanel *panel)
2727 W_Screen *scr = WMWidgetScreen(panel->win);
2728 RColor **colors = NULL;
2729 RHSVColor hsvcolor;
2730 RImage *sliderImg;
2731 WMPixmap *sliderPxmp;
2732 int i;
2734 hsvcolor = panel->hsvcolor;
2736 colors = malloc(sizeof(RColor*)*(8));
2737 for (i=0; i<7; i++) {
2738 hsvcolor.hue = (360*i)/6;
2739 colors[i] = malloc(sizeof(RColor));
2740 RHSVtoRGB(&hsvcolor, colors[i]);
2742 colors[7] = NULL;
2744 sliderImg = RRenderMultiGradient(141, 16, colors, RGRD_HORIZONTAL);
2745 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2746 RDestroyImage(sliderImg);
2747 if (hsvcolor.value < 128)
2748 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap,
2749 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
2750 "Hue", strlen("Hue"));
2751 else
2752 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap,
2753 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False,
2754 "Hue", strlen("Hue"));
2756 WMSetSliderImage(panel->hsbHueS, sliderPxmp);
2757 WMReleasePixmap(sliderPxmp);
2759 for (i=0; i<7; i++) {
2760 if (colors[i])
2761 free(colors[i]);
2763 if (colors)
2764 free(colors);
2767 /*************** Custom Palette Functions ****************/
2769 static void
2770 customRenderSpectrum(W_ColorPanel *panel)
2772 RImage *spectrum;
2773 int hue, sat, val;
2774 int x,y;
2775 unsigned long ofs;
2776 unsigned char *rp, *gp, *bp;
2777 RColor color;
2778 RHSVColor cur_hsv;
2780 spectrum = RCreateImage(SPECTRUM_WIDTH, SPECTRUM_HEIGHT, 0);
2782 for (y=0; y<360; y++) {
2783 val = 255;
2784 sat = 0;
2785 hue = y;
2786 for (x=0; x<511; x++) {
2787 ofs = (y * 511) + x;
2789 cur_hsv.hue = hue;
2790 cur_hsv.saturation = sat;
2791 cur_hsv.value = val;
2793 RHSVtoRGB (&cur_hsv, &color);
2795 rp = spectrum->data[0] + ofs;
2796 gp = spectrum->data[1] + ofs;
2797 bp = spectrum->data[2] + ofs;
2799 *rp = (unsigned char)color.red;
2800 *gp = (unsigned char)color.green;
2801 *bp = (unsigned char)color.blue;
2803 if (x<255)
2804 sat++;
2806 if (x>255)
2807 val--;
2810 if (panel->customPaletteImg) {
2811 RDestroyImage(panel->customPaletteImg);
2812 panel->customPaletteImg = NULL;
2814 panel->customPaletteImg = spectrum;
2819 static void
2820 customSetPalette(W_ColorPanel *panel)
2822 W_Screen *scr = WMWidgetScreen(panel->win);
2823 RImage *scaledImg;
2824 Pixmap image;
2825 int item;
2827 image = XCreatePixmap(scr->display, W_DRAWABLE(scr), customPaletteWidth,
2828 customPaletteHeight, scr->depth);
2830 scaledImg = RScaleImage(panel->customPaletteImg, customPaletteWidth,
2831 customPaletteHeight);
2832 RConvertImage(scr->rcontext, scaledImg, &image);
2833 RDestroyImage(scaledImg);
2835 XCopyArea(scr->display, image, panel->customPaletteContentView->window,
2836 scr->copyGC, 0, 0, customPaletteWidth, customPaletteHeight, 0, 0);
2838 /* Check backimage exists. If it doesn't, allocate and fill it */
2839 if (!panel->selectionBackImg) {
2840 panel->selectionBackImg = XCreatePixmap(scr->display,
2841 panel->customPaletteContentView->window, 4, 4, scr->depth);
2844 XCopyArea(scr->display, image, panel->selectionBackImg, scr->copyGC,
2845 panel->palx-2, panel->paly-2, 4, 4, 0, 0);
2846 XCopyArea(scr->display, panel->selectionImg,
2847 panel->customPaletteContentView->window, scr->copyGC, 0 , 0, 4, 4,
2848 panel->palx-2, panel->paly-2);
2849 XFreePixmap(scr->display, image);
2851 panel->palXRatio = (float)(panel->customPaletteImg->width) /
2852 (float)(customPaletteWidth);
2853 panel->palYRatio = (float)(panel->customPaletteImg->height) /
2854 (float)(customPaletteHeight);
2856 item = WMGetPopUpButtonSelectedItem (panel->customPaletteHistoryBtn);
2858 /* if palette != "Spectrum", we are allowed to rename and remove it */
2859 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename,
2860 (item > 0) );
2861 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove,
2862 (item > 0) );
2866 static void
2867 customPalettePositionSelection(W_ColorPanel *panel, int x, int y)
2869 W_Screen *scr = WMWidgetScreen(panel->win);
2870 unsigned long ofs;
2873 /* undraw selection */
2874 XCopyArea(scr->display, panel->selectionBackImg,
2875 panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4,
2876 panel->palx-2, panel->paly-2);
2878 panel->palx = x;
2879 panel->paly = y;
2881 ofs = rint(x * panel->palXRatio) + rint(y * panel->palYRatio) *
2882 panel->customPaletteImg->width;
2884 panel->color.red = panel->customPaletteImg->data[0][ofs];
2885 panel->color.green = panel->customPaletteImg->data[1][ofs];
2886 panel->color.blue = panel->customPaletteImg->data[2][ofs];
2888 updateSwatch(panel, panel->color);
2889 panel->lastChanged = WMCustomPaletteModeColorPanel;
2891 /* Redraw color selector (and make a backup of the part it will cover) */
2892 XCopyArea(scr->display, panel->customPaletteContentView->window,
2893 panel->selectionBackImg, scr->copyGC, panel->palx-2, panel->paly-2,
2894 4, 4, 0, 0); /* "-2" is correction for hotspot location */
2895 XCopyArea(scr->display, panel->selectionImg,
2896 panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4,
2897 panel->palx-2, panel->paly-2); /* see above */
2901 static void
2902 customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2904 if (x < 2)
2905 x = 2;
2906 if (y < 2)
2907 y = 2;
2908 if (x >= customPaletteWidth)
2909 x = customPaletteWidth -2;
2910 if (y >= customPaletteHeight)
2911 y = customPaletteHeight -2;
2913 customPalettePositionSelection(panel, x, y);
2917 static void
2918 customPaletteHandleEvents(XEvent *event, void *data)
2920 W_ColorPanel *panel = (W_ColorPanel*)data;
2922 switch (event->type) {
2923 case Expose:
2924 if (event->xexpose.count != 0)
2925 break;
2926 customSetPalette(panel);
2927 break;
2931 static void
2932 customPaletteHandleActionEvents(XEvent *event, void *data)
2934 W_ColorPanel *panel = (W_ColorPanel*)data;
2935 int x, y;
2937 switch (event->type) {
2938 case ButtonPress:
2939 x = event->xbutton.x;
2940 y = event->xbutton.y;
2942 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2943 panel->flags.dragging = 1;
2944 customPalettePositionSelection(panel, x, y);
2946 break;
2948 case ButtonRelease:
2949 panel->flags.dragging = 0;
2950 if (!panel->flags.continuous) {
2951 if (panel->action)
2952 (*panel->action)(panel, panel->clientData);
2954 break;
2956 case MotionNotify:
2957 x = event->xmotion.x;
2958 y = event->xmotion.y;
2960 if (panel->flags.dragging) {
2961 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2962 customPalettePositionSelection(panel, x, y);
2964 else
2965 customPalettePositionSelectionOutBounds(panel, x, y);
2967 break;
2972 static void
2973 customPaletteMenuCallback(WMWidget *w, void *data)
2975 W_ColorPanel *panel = (W_ColorPanel*)data;
2976 int item = WMGetPopUpButtonSelectedItem(panel->customPaletteMenuBtn);
2978 switch (item) {
2979 case CPmenuNewFromFile:
2980 customPaletteMenuNewFromFile(panel);
2981 break;
2982 case CPmenuRename:
2983 customPaletteMenuRename(panel);
2984 break;
2985 case CPmenuRemove:
2986 customPaletteMenuRemove(panel);
2987 break;
2988 case CPmenuCopy:
2989 break;
2990 case CPmenuNewFromClipboard:
2991 break;
2996 static void
2997 customPaletteMenuNewFromFile(W_ColorPanel *panel)
2999 W_Screen *scr = WMWidgetScreen(panel->win);
3000 WMOpenPanel *browseP;
3001 char *filepath;
3002 char *filename = NULL;
3003 char *spath;
3004 char *tmp;
3005 int i;
3006 RImage *tmpImg = NULL;
3008 if ((!panel->lastBrowseDir) || (strcmp(panel->lastBrowseDir,"\0") == 0))
3009 spath = wexpandpath(wgethomedir());
3010 else
3011 spath = wexpandpath(panel->lastBrowseDir);
3013 browseP = WMGetOpenPanel(scr);
3014 WMSetFilePanelCanChooseDirectories(browseP, 0);
3015 WMSetFilePanelCanChooseFiles(browseP, 1);
3017 /* Get a filename */
3018 if (WMRunModalFilePanelForDirectory(browseP, panel->win, spath,
3019 "Open Palette",
3020 RSupportedFileFormats()) ) {
3021 filepath = WMGetFilePanelFileName(browseP);
3023 /* Get seperation position between path and filename */
3024 i = strrchr(filepath, '/') - filepath + 1;
3025 if (i > strlen(filepath))
3026 i = strlen(filepath);
3028 /* Store last browsed path */
3029 if (panel->lastBrowseDir)
3030 free(panel->lastBrowseDir);
3031 panel->lastBrowseDir = wmalloc((i+1)*sizeof(char));
3032 strncpy(panel->lastBrowseDir, filepath, i);
3033 panel->lastBrowseDir[i] = '\0';
3035 /* Get filename from path */
3036 filename = wstrdup(filepath + i);
3038 /* Check for duplicate files, and rename it if there are any */
3039 tmp = wstrappend(panel->configurationPath, filename);
3040 while (access (tmp, F_OK) == 0) {
3041 char *newName;
3043 free(tmp);
3045 newName = generateNewFilename(filename);
3046 free(filename);
3047 filename = newName;
3049 tmp = wstrappend(panel->configurationPath, filename);
3051 free(tmp);
3053 /* Copy image to $(gnustepdir)/Library/Colors/ &
3054 * Add filename to history menu */
3055 if (fetchFile (panel->configurationPath, filepath, filename) == 0) {
3057 /* filepath is a "local" path now the file has been copied */
3058 free(filepath);
3059 filepath = wstrappend(panel->configurationPath, filename);
3061 /* load the image & add menu entries */
3062 tmpImg = RLoadImage(scr->rcontext, filepath, 0);
3063 if (tmpImg) {
3064 if (panel->customPaletteImg)
3065 RDestroyImage(panel->customPaletteImg);
3066 panel->customPaletteImg = tmpImg;
3068 customSetPalette(panel);
3069 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, filename);
3071 panel->currentPalette = WMGetPopUpButtonNumberOfItems(
3072 panel->customPaletteHistoryBtn)-1;
3074 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
3075 panel->currentPalette);
3078 else
3080 tmp = wstrappend(panel->configurationPath, filename);
3082 i = remove(tmp); /* Delete the file, it doesn't belong here */
3083 WMRunAlertPanel(scr, panel->win, "File Error",
3084 "Invalid file format !", "OK", NULL, NULL);
3085 if (i != 0) {
3086 wsyserror("can't remove file %s", tmp);
3087 WMRunAlertPanel(scr, panel->win, "File Error",
3088 "Couldn't remove file from Configuration Directory !",
3089 "OK", NULL, NULL);
3091 free(tmp);
3093 free(filepath);
3094 free(filename);
3096 WMFreeFilePanel(browseP);
3098 free(spath);
3102 static void
3103 customPaletteMenuRename(W_ColorPanel *panel)
3105 W_Screen *scr = WMWidgetScreen(panel->win);
3106 char *toName = NULL;
3107 char *fromName;
3108 char *toPath, *fromPath;
3109 int item;
3110 int index;
3112 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
3113 fromName = WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item);
3115 toName = WMRunInputPanel(scr, panel->win, "Rename", "Rename palette to:",
3116 fromName, "OK", "Cancel");
3118 if (toName) {
3120 /* As some people do certain stupid things... */
3121 if (strcmp(toName, fromName) == 0) {
3122 free(toName);
3123 return;
3126 /* For normal people */
3127 fromPath = wstrappend(panel->configurationPath, fromName);
3128 toPath = wstrappend(panel->configurationPath, toName);
3130 if (access (toPath, F_OK) == 0) {
3131 /* Careful, this palette exists already */
3132 if (WMRunAlertPanel(scr, panel->win, "Warning",
3133 "Palette already exists !\n\nOverwrite ?", "No", "Yes",
3134 NULL) == 1) {
3135 /* "No" = 0, "Yes" = 1 */
3136 int items = WMGetPopUpButtonNumberOfItems(
3137 panel->customPaletteHistoryBtn);
3139 remove(toPath);
3141 /* Remove from History list too */
3142 index = 1;
3143 while ((index < items) && (strcmp(WMGetPopUpButtonItem(
3144 panel->customPaletteHistoryBtn, index),
3145 toName) != 0 ))
3146 index++;
3148 if (index < items) {
3149 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn,
3150 index);
3151 if (index < item)
3152 item--;
3155 } else {
3156 free(fromPath);
3157 free(toName);
3158 free(toPath);
3160 return;
3164 if ( rename(fromPath, toPath) != 0)
3165 wsyserror("Couldn't rename palette %s to %s\n", fromName, toName);
3166 else {
3167 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
3168 WMInsertPopUpButtonItem(panel->customPaletteHistoryBtn, item,
3169 toName);
3171 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item);
3173 free(fromPath);
3174 free(toPath);
3175 free(toName);
3180 static void
3181 customPaletteMenuRemove(W_ColorPanel *panel)
3183 W_Screen *scr = WMWidgetScreen(panel->win);
3184 char *text;
3185 char *tmp;
3186 int choice;
3187 int item;
3189 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
3191 tmp = wstrappend( "This will permanently remove the palette ",
3192 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
3193 text = wstrappend( tmp, ".\n\nAre you sure you want to remove this"
3194 " palette ?");
3195 free(tmp);
3197 choice = WMRunAlertPanel(scr, panel->win, NULL, text, "Yes", "No", NULL);
3198 /* returns 0 (= "Yes") or 1 (="No") */
3199 free(text);
3201 if (choice == 0) {
3203 tmp = wstrappend(panel->configurationPath,
3204 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
3206 if ( remove(tmp) != 0)
3207 wsyserror("Couldn't remove palette %s\n", tmp);
3208 free(tmp);
3210 /* item -1 always exists */
3211 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item-1);
3213 customPaletteHistoryCallback(panel->customPaletteHistoryBtn, panel);
3214 customSetPalette(panel);
3216 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
3221 static void
3222 customPaletteHistoryCallback(WMWidget *w, void *data)
3224 W_ColorPanel *panel = (W_ColorPanel*)data;
3225 W_Screen *scr = WMWidgetScreen(panel->win);
3226 int item;
3227 char *filename;
3228 RImage *tmp = NULL;
3230 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
3231 if (item == panel->currentPalette)
3232 return;
3234 if (item == 0)
3235 customRenderSpectrum(panel);
3236 else {
3237 /* Load file from configpath */
3238 filename = wstrappend( panel->configurationPath,
3239 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item) );
3241 /* XXX To do: Check existence of file and remove it from the history
3242 * if it doesn't exist */
3244 tmp = RLoadImage(scr->rcontext, filename, 0);
3245 if (tmp) {
3246 if (panel->customPaletteImg) {
3247 RDestroyImage(panel->customPaletteImg);
3248 panel->customPaletteImg = NULL;
3250 panel->customPaletteImg = tmp;
3252 free(filename);
3254 customSetPalette(panel);
3256 panel->currentPalette = item;
3260 /*************** Panel Initialisation Functions *****************/
3262 static void
3263 wheelInit(W_ColorPanel *panel)
3265 RHSVColor cur_hsv;
3266 int i;
3267 int v;
3269 RRGBtoHSV(&panel->color, &cur_hsv);
3271 WMSetSliderValue(panel->wheelBrightnessS, 255-cur_hsv.value);
3272 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
3274 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 + (
3275 cur_hsv.saturation/255.0) * cos( cur_hsv.hue*M_PI/180.0)));
3276 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 + (
3277 cur_hsv.saturation/255.0) * sin(-cur_hsv.hue*M_PI/180.0)));
3279 for (i = 0; i < 256; i++) {
3280 /* We divide by 128 in advance, and check whether that number divides
3281 * by 2 properly. If not, we add one to round the number correctly
3283 v = (i*cur_hsv.value) >> 7;
3284 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + (v & 1));
3288 static void
3289 grayInit(W_ColorPanel *panel)
3291 RHSVColor cur_hsv;
3292 int value;
3293 char tmp[4];
3295 RRGBtoHSV(&panel->color, &cur_hsv);
3297 value = rint(cur_hsv.value/2.55);
3298 WMSetSliderValue(panel->grayBrightnessS, value);
3300 sprintf(tmp, "%d", value);
3301 WMSetTextFieldText(panel->grayBrightnessT, tmp);
3304 static void
3305 rgbInit(W_ColorPanel *panel)
3307 char tmp[4];
3309 WMSetSliderValue(panel->rgbRedS,panel->color.red);
3310 WMSetSliderValue(panel->rgbGreenS,panel->color.green);
3311 WMSetSliderValue(panel->rgbBlueS,panel->color.blue);
3313 sprintf(tmp, "%d", panel->color.red);
3314 WMSetTextFieldText(panel->rgbRedT, tmp);
3315 sprintf(tmp, "%d", panel->color.green);
3316 WMSetTextFieldText(panel->rgbGreenT, tmp);
3317 sprintf(tmp, "%d", panel->color.blue);
3318 WMSetTextFieldText(panel->rgbBlueT, tmp);
3321 static void
3322 cmykInit(W_ColorPanel *panel)
3324 int value[3];
3325 char tmp[4];
3327 value[0] = rint((255-panel->color.red)/2.55);
3328 value[1] = rint((255-panel->color.green)/2.55);
3329 value[2] = rint((255-panel->color.blue)/2.55);
3331 WMSetSliderValue(panel->cmykCyanS, value[0]);
3332 WMSetSliderValue(panel->cmykMagentaS, value[1]);
3333 WMSetSliderValue(panel->cmykYellowS, value[2]);
3334 WMSetSliderValue(panel->cmykBlackS, 0);
3336 sprintf(tmp, "%d", value[0]);
3337 WMSetTextFieldText(panel->cmykCyanT, tmp);
3338 sprintf(tmp, "%d", value[1]);
3339 WMSetTextFieldText(panel->cmykMagentaT, tmp);
3340 sprintf(tmp, "%d", value[2]);
3341 WMSetTextFieldText(panel->cmykYellowT, tmp);
3342 WMSetTextFieldText(panel->cmykBlackT, "0");
3345 static void
3346 hsbInit(W_ColorPanel *panel)
3348 int value[3];
3349 char tmp[4];
3351 value[0] = panel->hsvcolor.hue;
3352 value[1] = rint(panel->hsvcolor.saturation/2.55);
3353 value[2] = rint(panel->hsvcolor.value/2.55);
3355 WMSetSliderValue(panel->hsbHueS,value[0]);
3356 WMSetSliderValue(panel->hsbSaturationS,value[1]);
3357 WMSetSliderValue(panel->hsbBrightnessS,value[2]);
3359 sprintf(tmp, "%d", value[0]);
3360 WMSetTextFieldText(panel->hsbHueT, tmp);
3361 sprintf(tmp, "%d", value[1]);
3362 WMSetTextFieldText(panel->hsbSaturationT, tmp);
3363 sprintf(tmp, "%d", value[2]);
3364 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
3366 hsbUpdateBrightnessGradient(panel);
3367 hsbUpdateSaturationGradient(panel);
3368 hsbUpdateHueGradient(panel);
3374 /************************* ColorList Panel Functions **********************/
3376 static void
3377 colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text,
3378 int state, WMRect *rect)
3380 int width, height, x, y;
3381 RColor color = *((RColor *)WMGetListItem(lPtr, index)->clientData);
3382 WMScreen *scr = WMWidgetScreen(lPtr);
3383 Display *dpy = WMScreenDisplay(scr);
3384 W_ColorPanel *panel = WMGetHangedData(lPtr);
3385 WMColor *white = WMWhiteColor(scr);
3386 WMColor *black = WMBlackColor(scr);
3387 WMColor *fillColor;
3389 width = rect->size.width;
3390 height = rect->size.height;
3391 x = rect->pos.x;
3392 y = rect->pos.y;
3394 if (state & WLDSSelected)
3395 WMPaintColorSwatch(white, d, x +15, y, width -15, height);
3396 else
3397 XClearArea(dpy, d, x +15, y, width -15, height, False);
3399 fillColor = WMCreateRGBColor(scr, color.red*256, color.green*256,
3400 color.blue*256, False);
3402 WMSetColorInGC(fillColor, WMColorGC(fillColor));
3403 WMPaintColorSwatch(fillColor, d, x, y, 15, 15);
3404 WMReleaseColor(fillColor);
3406 WMDrawString(scr, d, WMColorGC(black), panel->font12, x+18, y, text,
3407 strlen(text));
3409 WMReleaseColor(white);
3410 WMReleaseColor(black);
3414 static void
3415 colorListSelect(WMWidget *w, void *data)
3417 W_ColorPanel *panel = (W_ColorPanel *)data;
3418 RColor color = *((RColor *)WMGetListSelectedItem(w)->clientData);
3420 panel->lastChanged = WMColorListModeColorPanel;
3421 updateSwatch(panel, color);
3425 static void
3426 colorListColorMenuCallback(WMWidget *w, void *data)
3428 W_ColorPanel *panel = (W_ColorPanel *)data;
3429 int item = WMGetPopUpButtonSelectedItem(panel->colorListColorMenuBtn);
3431 switch (item) {
3432 case CLmenuAdd:
3433 break;
3434 case CLmenuRename:
3435 break;
3436 case CLmenuRemove:
3437 break;
3442 static void
3443 colorListListMenuCallback(WMWidget *w, void *data)
3445 W_ColorPanel *panel = (W_ColorPanel *)data;
3446 int item = WMGetPopUpButtonSelectedItem(panel->colorListListMenuBtn);
3448 switch (item) {
3449 case CLmenuAdd:
3450 /* New Color List */
3451 colorListListMenuNew(panel);
3452 break;
3453 case CLmenuRename:
3454 break;
3455 case CLmenuRemove:
3456 break;
3461 static void
3462 colorListListMenuNew(W_ColorPanel *panel)
3468 /************************** Common utility functions ************************/
3470 static int
3471 fetchFile(char *toPath, char *srcFile, char *destFile)
3473 int src, dest;
3474 int n;
3475 char *tmp;
3476 char buf[BUFSIZE];
3478 if ((src = open(srcFile, O_RDONLY)) == 0) {
3479 wsyserror("Could not open %s", srcFile);
3480 return -1;
3483 tmp = wstrappend(toPath, destFile);
3484 if ((dest = open( tmp, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))
3485 == 0) {
3486 wsyserror("Could not create %s", tmp);
3487 free(tmp);
3488 return -1;
3490 free(tmp);
3493 /* Copy the file */
3494 while ((n = read(src, buf, BUFSIZE)) > 0)
3496 if (write (dest, buf, n) != n) {
3497 wsyserror("Write error on file %s", destFile);
3498 return -1;
3502 return 0;
3506 char*
3507 generateNewFilename(char *curName)
3509 int n;
3510 char c;
3511 int baseLen;
3512 char *ptr;
3513 char *newName;
3516 assert(curName);
3518 ptr = curName;
3520 if (
3521 ((ptr = strrchr(ptr, '{')) == 0) ||
3522 sscanf(ptr, "{%i}%c", &n, &c) != 1
3524 return wstrappend(curName, " {1}");
3526 baseLen = ptr - curName -1;
3528 newName = wmalloc(baseLen + 16);
3529 strncpy(newName, curName, baseLen);
3530 newName[baseLen] = 0;
3532 sprintf(&newName[baseLen], " {%i}", n+1);
3534 return newName;