Fixed a bug and cleaned up a bit the color panel code (patch submited by
[wmaker-crm.git] / WINGs / wcolorpanel.c
blobd8e5a6ade993dd2297a7187ceea2aafec0667111
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
51 * Bitmaps for magnifying glass cursor
54 /* Cursor */
55 #define Cursor_x_hot 11
56 #define Cursor_y_hot 11
57 #define Cursor_width 32
58 #define Cursor_height 32
59 static unsigned char Cursor_bits[] = {
60 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
61 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
62 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
63 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
64 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
65 0x00,0x08,0x00,0x50,0x00,0x10,0x00,0x88,0x00,0x20,0x00,0x5c,0x01,0xc0,0x81,
66 0x3b,0x02,0x00,0x7e,0x70,0x05,0x00,0x00,0xe0,0x08,0x00,0x00,0xc0,0x15,0x00,
67 0x00,0x80,0x23,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x5c,
68 0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x70};
70 /* Cursor shape-mask */
71 #define Cursor_shape_width 32
72 #define Cursor_shape_height 32
73 static unsigned char Cursor_shape_bits[] = {
74 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
75 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
76 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
77 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
78 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
79 0x00,0x08,0x00,0x70,0x00,0x10,0x00,0xf8,0x00,0x20,0x00,0xfc,0x01,0xc0,0x81,
80 0xfb,0x03,0x00,0x7e,0xf0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x1f,0x00,
81 0x00,0x80,0x3f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfc,
82 0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70};
84 /* Clip-mask for magnified pixels */
85 #define Cursor_mask_width 22
86 #define Cursor_mask_height 22
87 static unsigned char Cursor_mask_bits[] = {
88 0x00,0x3f,0x00,0xe0,0xff,0x01,0xf0,0xff,0x03,0xf8,0xff,0x07,0xfc,0xff,0x0f,
89 0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xff,0xff,0x3f,0xff,0xff,0x3f,
90 0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xfe,0xff,0x1f,
91 0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfc,0xff,0x0f,0xf8,0xff,0x07,0xf0,0xff,0x03,
92 0xe0,0xff,0x01,0x00,0x3f,0x00};
95 typedef struct MovingView {
96 WMView *view; /* The view this is all about */
97 Pixmap pixmap; /* What's under the view */
98 Pixmap mask; /* Pixmap mask for view-contents */
99 int valid; /* Are contents still valid ? */
100 RColor color; /* Color of a pixel in the image */
101 } MovingView;
103 typedef struct WheelMatrix {
104 unsigned int width, height; /* Size of the colorwheel */
105 unsigned char *data[3]; /* Wheel data (R,G,B) */
106 unsigned char values[256]; /* Precalculated values R,G & B = 0-255 */
107 } wheelMatrix;
109 typedef struct W_ColorPanel {
110 WMWindow *win;
111 WMFont *font8;
112 WMFont *font12;
114 void *clientData;
115 WMAction *action;
117 /* Common Stuff */
118 WMColorWell *colorWell;
119 WMButton *magnifyBtn;
120 WMButton *wheelBtn;
121 WMButton *slidersBtn;
122 WMButton *customPaletteBtn;
123 WMButton *colorListBtn;
125 /* Magnifying Glass */
126 MovingView *magnifyGlass;
128 /* ColorWheel Panel */
129 WMFrame *wheelFrm;
130 WMSlider *wheelBrightnessS;
131 WMView *wheelView;
133 /* Slider Panels */
134 WMFrame *slidersFrm;
135 WMFrame *seperatorFrm;
136 WMButton *grayBtn;
137 WMButton *rgbBtn;
138 WMButton *cmykBtn;
139 WMButton *hsbBtn;
140 /* Gray Scale Panel */
141 WMFrame *grayFrm;
142 WMLabel *grayMinL;
143 WMLabel *grayMaxL;
144 WMSlider *grayBrightnessS;
145 WMTextField *grayBrightnessT;
146 WMButton *grayPresetBtn[7];
148 /* RGB Panel */
149 WMFrame *rgbFrm;
150 WMLabel *rgbMinL;
151 WMLabel *rgbMaxL;
152 WMSlider *rgbRedS;
153 WMSlider *rgbGreenS;
154 WMSlider *rgbBlueS;
155 WMTextField *rgbRedT;
156 WMTextField *rgbGreenT;
157 WMTextField *rgbBlueT;
159 /* CMYK Panel */
160 WMFrame *cmykFrm;
161 WMLabel *cmykMinL;
162 WMLabel *cmykMaxL;
163 WMSlider *cmykCyanS;
164 WMSlider *cmykMagentaS;
165 WMSlider *cmykYellowS;
166 WMSlider *cmykBlackS;
167 WMTextField *cmykCyanT;
168 WMTextField *cmykMagentaT;
169 WMTextField *cmykYellowT;
170 WMTextField *cmykBlackT;
172 /* HSB Panel */
173 WMFrame *hsbFrm;
174 WMSlider *hsbHueS;
175 WMSlider *hsbSaturationS;
176 WMSlider *hsbBrightnessS;
177 WMTextField *hsbHueT;
178 WMTextField *hsbSaturationT;
179 WMTextField *hsbBrightnessT;
181 /* Custom Palette Panel*/
182 WMFrame *customPaletteFrm;
183 WMPopUpButton *customPaletteHistoryBtn;
184 WMFrame *customPaletteContentFrm;
185 WMPopUpButton *customPaletteMenuBtn;
186 WMView *customPaletteContentView;
188 /* Color List Panel */
189 WMFrame *colorListFrm;
190 WMPopUpButton *colorListHistoryBtn;
191 WMList *colorListContentLst;
192 WMPopUpButton *colorListColorMenuBtn;
193 WMPopUpButton *colorListListMenuBtn;
195 /* Look-Up Tables and Images */
196 wheelMatrix *wheelMtrx;
197 Pixmap wheelImg;
198 Pixmap selectionImg;
199 Pixmap selectionBackImg;
200 RImage *customPaletteImg;
201 char *lastBrowseDir;
203 /* Common Data Fields */
204 RColor color; /* Current color */
205 Bool colorSet; /* Is color already set ? */
206 RHSVColor hsvcolor; /* Backup HSV Color */
207 WMColorPanelMode mode; /* Current color selection mode */
208 WMColorPanelMode slidersmode;/* Current color sel. mode sliders panel */
209 WMColorPanelMode lastChanged;/* Panel that last changed the color */
210 int colx, coly; /* (x,y) of sel.-marker in WheelMode */
211 int palx, paly; /* (x,y) of sel.-marker in
212 CustomPaletteMode */
213 float palXRatio, palYRatio; /* Ratios in x & y between
214 original and scaled
215 palettesize */
216 int currentPalette;
217 char *configurationPath;
219 struct {
220 unsigned int continuous:1;
222 unsigned int dragging:1;
223 } flags;
224 } W_ColorPanel;
226 enum {
227 CPmenuNewFromFile,
228 CPmenuRename,
229 CPmenuRemove,
230 CPmenuCopy,
231 CPmenuNewFromClipboard
232 } customPaletteMenuItem;
234 enum {
235 CLmenuAdd,
236 CLmenuRename,
237 CLmenuRemove
238 } colorListMenuItem;
241 #define PWIDTH 194
242 #define PHEIGHT 266
243 #define colorWheelSize 150
244 #define customPaletteWidth 182
245 #define customPaletteHeight 106
246 #define knobThickness 8
248 #define SPECTRUM_WIDTH 511
249 #define SPECTRUM_HEIGHT 360
251 #define COLORWHEEL_PART 1
252 #define CUSTOMPALETTE_PART 2
253 #define BUFSIZE 1024
255 #undef EASTEREGG
257 #define RGBTXT "/usr/X11R6/lib/X11/rgb.txt"
258 #define MAX_LENGTH 1024
260 static int fetchFile(char* toPath, char *imageSrcFile,
261 char *imageDestFileName);
262 char *generateNewFilename(char *curName);
264 static void modeButtonCallback(WMWidget *w, void *data);
265 static int getPickerPart(W_ColorPanel *panel, int x, int y);
266 static void readConfiguration(W_ColorPanel *panel);
267 static void readXColors(W_ColorPanel *panel);
269 static void closeWindowCallback(WMWidget *w, void *data);
271 static Cursor magnifyGrabPointer(W_ColorPanel *panel);
272 static WMPoint magnifyInitialize(W_ColorPanel *panel);
273 static void magnifyPutCursor(WMWidget *w, void *data);
274 static Pixmap magnifyCreatePixmap(WMColorPanel *panel);
275 static Pixmap magnifyGetStorePixmap(W_ColorPanel *panel, int x1, int y1,
276 int x2, int y2);
277 static Pixmap magnifyGetImage(WMScreen *scr, int x, int y);
279 static wheelMatrix* wheelCreateMatrix(unsigned int width , unsigned int height);
280 static void wheelDestroyMatrix(wheelMatrix *matrix);
281 static wheelMatrix* wheelInitMatrix(W_ColorPanel *panel);
282 static void wheelRender(W_ColorPanel *panel);
283 static Bool wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs);
284 static void wheelPaint(W_ColorPanel *panel);
286 static void wheelHandleEvents(XEvent *event, void *data);
287 static void wheelHandleActionEvents(XEvent *event, void *data);
288 static void wheelBrightnessSliderCallback(WMWidget *w, void *data);
289 static void wheelUpdateSelection(W_ColorPanel *panel);
290 static void wheelUndrawSelection(W_ColorPanel *panel);
292 static void wheelPositionSelection(W_ColorPanel *panel, int x, int y);
293 static void wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y);
294 static void wheelUpdateBrightnessGradientFromHSV (W_ColorPanel *panel,
295 RHSVColor topColor);
296 static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel *panel);
297 static void wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor);
299 static void grayBrightnessSliderCallback(WMWidget *w, void *data);
300 static void grayPresetButtonCallback(WMWidget *w, void *data);
301 static void grayBrightnessTextFieldCallback(void *observerData,
302 WMNotification *notification);
304 static void rgbSliderCallback(WMWidget *w, void *data);
305 static void rgbTextFieldCallback(void *observerData,
306 WMNotification *notification);
308 static void cmykSliderCallback(WMWidget *w, void *data);
309 static void cmykTextFieldCallback(void *observerData,
310 WMNotification *notification);
312 static void hsbSliderCallback(WMWidget *w, void *data);
313 static void hsbTextFieldCallback(void *observerData,
314 WMNotification *notification);
315 static void hsbUpdateBrightnessGradient(W_ColorPanel *panel);
316 static void hsbUpdateSaturationGradient(W_ColorPanel *panel);
317 static void hsbUpdateHueGradient(W_ColorPanel *panel);
319 static void customRenderSpectrum(W_ColorPanel *panel);
320 static void customSetPalette(W_ColorPanel *panel);
321 static void customPaletteHandleEvents(XEvent *event, void *data);
322 static void customPaletteHandleActionEvents(XEvent *event, void *data);
323 static void customPalettePositionSelection(W_ColorPanel *panel, int x, int y);
324 static void customPalettePositionSelectionOutBounds(W_ColorPanel *panel,
325 int x, int y);
326 static void customPaletteMenuCallback(WMWidget *w, void *data);
327 static void customPaletteHistoryCallback(WMWidget *w, void *data);
329 static void customPaletteMenuNewFromFile(W_ColorPanel *panel);
330 static void customPaletteMenuRename(W_ColorPanel *panel);
331 static void customPaletteMenuRemove(W_ColorPanel *panel);
333 static void colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text,
334 int state, WMRect *rect);
335 static void colorListSelect(WMWidget *w, void *data);
336 static void colorListColorMenuCallback(WMWidget *w, void *data);
337 static void colorListListMenuCallback(WMWidget *w, void *data);
338 static void colorListListMenuNew(W_ColorPanel *panel);
340 static void wheelInit(W_ColorPanel *panel);
341 static void grayInit(W_ColorPanel *panel);
342 static void rgbInit(W_ColorPanel *panel);
343 static void cmykInit(W_ColorPanel *panel);
344 static void hsbInit(W_ColorPanel *panel);
348 void
349 WMSetColorPanelAction(WMColorPanel *panel, WMAction *action, void *data)
351 panel->action = action;
352 panel->clientData = data;
355 static WMColorPanel*
356 makeColorPanel(WMScreen *scrPtr, char *name)
358 WMColorPanel *panel;
359 RImage *image;
360 WMPixmap *pixmap;
361 RColor from;
362 RColor to;
363 WMColor *textcolor;
364 int i;
365 int x,y;
368 panel = wmalloc(sizeof(WMColorPanel));
369 memset(panel, 0, sizeof(WMColorPanel));
371 panel->colorSet = False; /* Color has not been set yet */
373 panel->font8 = WMSystemFontOfSize(scrPtr, 8);
374 panel->font12 = WMSystemFontOfSize(scrPtr, 12);
376 panel->win = WMCreateWindowWithStyle(scrPtr, name,
377 WMTitledWindowMask | WMClosableWindowMask | WMResizableWindowMask);
378 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
379 WMSetWindowTitle(panel->win, "Colors");
380 WMSetWindowCloseAction(panel->win, closeWindowCallback, panel);
383 /* Set Default ColorPanel Mode(s) */
384 panel->mode = WMWheelModeColorPanel;
385 panel->lastChanged = WMWheelModeColorPanel;
386 panel->slidersmode = WMRGBModeColorPanel;
387 panel->configurationPath = wstrappend(wusergnusteppath(),
388 "/Library/Colors/");
390 /* Some General Purpose Widgets */
391 panel->colorWell = WMCreateColorWell(panel->win);
392 WMResizeWidget(panel->colorWell, 134, 36);
393 WSetColorWellBordered(panel->colorWell, False);
394 WMMoveWidget(panel->colorWell, 56, 4);
396 panel->magnifyBtn = WMCreateCustomButton(panel->win,
397 WBBStateLightMask|WBBStateChangeMask);
398 WMResizeWidget(panel->magnifyBtn, 46, 36);
399 WMMoveWidget(panel->magnifyBtn, 6,4);
400 WMSetButtonAction(panel->magnifyBtn, magnifyPutCursor, panel);
401 WMSetButtonImagePosition(panel->magnifyBtn, WIPImageOnly);
402 WMSetButtonImage(panel->magnifyBtn, scrPtr->magnifyIcon);
404 panel->wheelBtn = WMCreateCustomButton(panel->win,
405 WBBStateLightMask|WBBStateChangeMask);
406 WMResizeWidget(panel->wheelBtn, 46, 32);
407 WMMoveWidget(panel->wheelBtn, 6, 44);
408 WMSetButtonAction(panel->wheelBtn, modeButtonCallback, panel);
409 WMSetButtonImagePosition(panel->wheelBtn, WIPImageOnly);
410 WMSetButtonImage(panel->wheelBtn, scrPtr->wheelIcon);
412 panel->slidersBtn = WMCreateCustomButton(panel->win,
413 WBBStateLightMask|WBBStateChangeMask);
414 WMResizeWidget(panel->slidersBtn, 46, 32);
415 WMMoveWidget(panel->slidersBtn, 52, 44);
416 WMSetButtonAction(panel->slidersBtn, modeButtonCallback, panel);
417 WMSetButtonImagePosition(panel->slidersBtn, WIPImageOnly);
418 WMSetButtonImage(panel->slidersBtn, scrPtr->rgbIcon);
420 panel->customPaletteBtn = WMCreateCustomButton(panel->win,
421 WBBStateLightMask|WBBStateChangeMask);
422 WMResizeWidget(panel->customPaletteBtn, 46, 32);
423 WMMoveWidget(panel->customPaletteBtn, 98, 44);
424 WMSetButtonAction(panel->customPaletteBtn, modeButtonCallback, panel);
425 WMSetButtonImagePosition(panel->customPaletteBtn, WIPImageOnly);
426 WMSetButtonImage(panel->customPaletteBtn, scrPtr->customPaletteIcon);
428 panel->colorListBtn = WMCreateCustomButton(panel->win,
429 WBBStateLightMask|WBBStateChangeMask);
430 WMResizeWidget(panel->colorListBtn, 46, 32);
431 WMMoveWidget(panel->colorListBtn, 144, 44);
432 WMSetButtonAction(panel->colorListBtn, modeButtonCallback, panel);
433 WMSetButtonImagePosition(panel->colorListBtn, WIPImageOnly);
434 WMSetButtonImage(panel->colorListBtn, scrPtr->colorListIcon);
436 /* Let's Group some of them together */
437 WMGroupButtons(panel->wheelBtn, panel->slidersBtn);
438 WMGroupButtons(panel->wheelBtn, panel->customPaletteBtn);
439 WMGroupButtons(panel->wheelBtn, panel->colorListBtn);
441 /* Widgets for the ColorWheel Panel */
442 panel->wheelFrm = WMCreateFrame(panel->win);
443 WMSetFrameRelief(panel->wheelFrm, WRFlat);
444 WMResizeWidget(panel->wheelFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
445 WMMoveWidget(panel->wheelFrm, 5, 80);
447 panel->wheelView = W_CreateView(W_VIEW(panel->wheelFrm));
448 /* XXX Can we create a view ? */
449 W_ResizeView(panel->wheelView, colorWheelSize+4, colorWheelSize+4);
450 W_MoveView(panel->wheelView, 0, 0);
452 /* Create an event handler to handle expose/click events in ColorWheel */
453 WMCreateEventHandler(panel->wheelView,
454 ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
455 LeaveWindowMask|ButtonMotionMask, wheelHandleActionEvents, panel);
457 WMCreateEventHandler(panel->wheelView, ExposureMask, wheelHandleEvents,
458 panel);
460 panel->wheelBrightnessS = WMCreateSlider(panel->wheelFrm);
461 WMResizeWidget(panel->wheelBrightnessS, 16, 153);
462 WMMoveWidget(panel->wheelBrightnessS, 5+colorWheelSize+14, 1);
463 WMSetSliderMinValue(panel->wheelBrightnessS, 0);
464 WMSetSliderMaxValue(panel->wheelBrightnessS, 255);
465 WMSetSliderAction(panel->wheelBrightnessS, wheelBrightnessSliderCallback,
466 panel);
467 WMSetSliderKnobThickness(panel->wheelBrightnessS, knobThickness);
470 /* Widgets for the Slider Panels */
471 panel->slidersFrm = WMCreateFrame(panel->win);
472 WMSetFrameRelief(panel->slidersFrm, WRFlat);
473 WMResizeWidget(panel->slidersFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
474 WMMoveWidget(panel->slidersFrm, 4, 80);
476 panel->seperatorFrm = WMCreateFrame(panel->slidersFrm);
477 WMSetFrameRelief(panel->seperatorFrm, WRPushed);
478 WMResizeWidget(panel->seperatorFrm, PWIDTH - 8, 2);
479 WMMoveWidget(panel->seperatorFrm, 0, 1);
481 panel->grayBtn = WMCreateCustomButton(panel->slidersFrm,
482 WBBStateLightMask|WBBStateChangeMask);
483 WMResizeWidget(panel->grayBtn, 46, 24);
484 WMMoveWidget(panel->grayBtn, 1, 8);
485 WMSetButtonAction(panel->grayBtn, modeButtonCallback, panel);
486 WMSetButtonImagePosition(panel->grayBtn, WIPImageOnly);
487 WMSetButtonImage(panel->grayBtn, scrPtr->grayIcon);
489 panel->rgbBtn = WMCreateCustomButton(panel->slidersFrm,
490 WBBStateLightMask|WBBStateChangeMask);
491 WMResizeWidget(panel->rgbBtn, 46, 24);
492 WMMoveWidget(panel->rgbBtn, 47, 8);
493 WMSetButtonAction(panel->rgbBtn, modeButtonCallback, panel);
494 WMSetButtonImagePosition(panel->rgbBtn, WIPImageOnly);
495 WMSetButtonImage(panel->rgbBtn, scrPtr->rgbIcon);
497 panel->cmykBtn = WMCreateCustomButton(panel->slidersFrm,
498 WBBStateLightMask|WBBStateChangeMask);
499 WMResizeWidget(panel->cmykBtn, 46, 24);
500 WMMoveWidget(panel->cmykBtn, 93, 8);
501 WMSetButtonAction(panel->cmykBtn, modeButtonCallback, panel);
502 WMSetButtonImagePosition(panel->cmykBtn, WIPImageOnly);
503 WMSetButtonImage(panel->cmykBtn, scrPtr->cmykIcon);
505 panel->hsbBtn = WMCreateCustomButton(panel->slidersFrm,
506 WBBStateLightMask|WBBStateChangeMask);
507 WMResizeWidget(panel->hsbBtn, 46, 24);
508 WMMoveWidget(panel->hsbBtn, 139, 8);
509 WMSetButtonAction(panel->hsbBtn, modeButtonCallback, panel);
510 WMSetButtonImagePosition(panel->hsbBtn, WIPImageOnly);
511 WMSetButtonImage(panel->hsbBtn, scrPtr->hsbIcon);
513 /* Let's Group the Slider Panel Buttons Together */
514 WMGroupButtons(panel->grayBtn, panel->rgbBtn);
515 WMGroupButtons(panel->grayBtn, panel->cmykBtn);
516 WMGroupButtons(panel->grayBtn, panel->hsbBtn);
518 textcolor = WMDarkGrayColor(scrPtr);
520 /* Widgets for GrayScale Panel */
521 panel->grayFrm = WMCreateFrame(panel->slidersFrm);
522 WMSetFrameRelief(panel->grayFrm, WRFlat);
523 WMResizeWidget(panel->grayFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
524 WMMoveWidget(panel->grayFrm, 0, 34);
526 panel->grayMinL = WMCreateLabel(panel->grayFrm);
527 WMResizeWidget(panel->grayMinL, 20, 10);
528 WMMoveWidget(panel->grayMinL, 2, 2);
529 WMSetLabelText(panel->grayMinL, "0");
530 WMSetLabelTextAlignment(panel->grayMinL, WALeft);
531 WMSetLabelTextColor(panel->grayMinL, textcolor);
532 WMSetLabelFont(panel->grayMinL, panel->font8);
534 panel->grayMaxL = WMCreateLabel(panel->grayFrm);
535 WMResizeWidget(panel->grayMaxL, 40, 10);
536 WMMoveWidget(panel->grayMaxL, 104, 2);
537 WMSetLabelText(panel->grayMaxL, "100");
538 WMSetLabelTextAlignment(panel->grayMaxL, WARight);
539 WMSetLabelTextColor(panel->grayMaxL, textcolor);
540 WMSetLabelFont(panel->grayMaxL, panel->font8);
542 panel->grayBrightnessS = WMCreateSlider(panel->grayFrm);
543 WMResizeWidget(panel->grayBrightnessS, 141, 16);
544 WMMoveWidget(panel->grayBrightnessS, 2, 14);
545 WMSetSliderMinValue(panel->grayBrightnessS, 0);
546 WMSetSliderMaxValue(panel->grayBrightnessS, 100);
547 WMSetSliderKnobThickness(panel->grayBrightnessS, knobThickness);
548 WMSetSliderAction(panel->grayBrightnessS, grayBrightnessSliderCallback,
549 panel);
551 from.red = 0;
552 from.green = 0;
553 from.blue = 0;
555 to.red = 255;
556 to.green = 255;
557 to.blue = 255;
559 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
560 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
561 RDestroyImage(image);
562 W_PaintText(W_VIEW(panel->grayBrightnessS), pixmap->pixmap,
563 panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->white),
564 False, "Brightness", strlen("Brightness"));
565 WMSetSliderImage(panel->grayBrightnessS, pixmap);
566 WMReleasePixmap(pixmap);
568 panel->grayBrightnessT = WMCreateTextField(panel->grayFrm);
569 WMResizeWidget(panel->grayBrightnessT, 40, 18);
570 WMMoveWidget(panel->grayBrightnessT, 146, 13);
571 WMSetTextFieldAlignment(panel->grayBrightnessT, WALeft);
572 WMAddNotificationObserver(grayBrightnessTextFieldCallback, panel,
573 WMTextDidEndEditingNotification, panel->grayBrightnessT);
575 image = RCreateImage(13,13,False);
576 for (i=0; i < 7; i++) {
577 for (x=0; x < 13; x++) {
578 for (y=0; y < 13; y++) {
579 image->data[0][y*13+x] = 255/6*i;
580 image->data[1][y*13+x] = 255/6*i;
581 image->data[2][y*13+x] = 255/6*i;
584 panel->grayPresetBtn[i] = WMCreateCommandButton(panel->grayFrm);
585 WMResizeWidget(panel->grayPresetBtn[i], 20, 24);
586 WMMoveWidget(panel->grayPresetBtn[i], 2+(i*20), 34);
587 WMSetButtonAction(panel->grayPresetBtn[i],
588 grayPresetButtonCallback, panel);
589 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
590 WMSetButtonImage(panel->grayPresetBtn[i], pixmap);
591 WMSetButtonImagePosition(panel->grayPresetBtn[i], WIPImageOnly);
592 WMReleasePixmap(pixmap);
594 RDestroyImage(image);
595 /* End of GrayScale Panel */
597 /* Widgets for RGB Panel */
598 panel->rgbFrm = WMCreateFrame(panel->slidersFrm);
599 WMSetFrameRelief(panel->rgbFrm, WRFlat);
600 WMResizeWidget(panel->rgbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
601 WMMoveWidget(panel->rgbFrm, 0, 34);
603 panel->rgbMinL = WMCreateLabel(panel->rgbFrm);
604 WMResizeWidget(panel->rgbMinL, 20, 10);
605 WMMoveWidget(panel->rgbMinL, 2, 2);
606 WMSetLabelText(panel->rgbMinL, "0");
607 WMSetLabelTextAlignment(panel->rgbMinL, WALeft);
608 WMSetLabelTextColor(panel->rgbMinL, textcolor);
609 WMSetLabelFont(panel->rgbMinL, panel->font8);
611 panel->rgbMaxL = WMCreateLabel(panel->rgbFrm);
612 WMResizeWidget(panel->rgbMaxL, 40, 10);
613 WMMoveWidget(panel->rgbMaxL, 104, 2);
614 WMSetLabelText(panel->rgbMaxL, "255");
615 WMSetLabelTextAlignment(panel->rgbMaxL, WARight);
616 WMSetLabelTextColor(panel->rgbMaxL, textcolor);
617 WMSetLabelFont(panel->rgbMaxL, panel->font8);
619 panel->rgbRedS = WMCreateSlider(panel->rgbFrm);
620 WMResizeWidget(panel->rgbRedS, 141, 16);
621 WMMoveWidget(panel->rgbRedS, 2, 14);
622 WMSetSliderMinValue(panel->rgbRedS, 0);
623 WMSetSliderMaxValue(panel->rgbRedS, 255);
624 WMSetSliderKnobThickness(panel->rgbRedS, knobThickness);
625 WMSetSliderAction(panel->rgbRedS, rgbSliderCallback, panel);
627 to.red = 255;
628 to.green = 0;
629 to.blue = 0;
631 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
632 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
633 W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12,
634 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Red",
635 strlen("Red"));
636 RDestroyImage(image);
637 WMSetSliderImage(panel->rgbRedS, pixmap);
638 WMReleasePixmap(pixmap);
640 panel->rgbRedT = WMCreateTextField(panel->rgbFrm);
641 WMResizeWidget(panel->rgbRedT, 40, 18);
642 WMMoveWidget(panel->rgbRedT, 146, 13);
643 WMSetTextFieldAlignment(panel->rgbRedT, WALeft);
644 WMAddNotificationObserver(rgbTextFieldCallback, panel,
645 WMTextDidEndEditingNotification, panel->rgbRedT);
648 panel->rgbGreenS = WMCreateSlider(panel->rgbFrm);
649 WMResizeWidget(panel->rgbGreenS, 141, 16);
650 WMMoveWidget(panel->rgbGreenS, 2, 36);
651 WMSetSliderMinValue(panel->rgbGreenS, 0);
652 WMSetSliderMaxValue(panel->rgbGreenS, 255);
653 WMSetSliderKnobThickness(panel->rgbGreenS, knobThickness);
654 WMSetSliderAction(panel->rgbGreenS, rgbSliderCallback, panel);
656 to.red = 0;
657 to.green = 255;
658 to.blue = 0;
660 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
661 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
662 W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12,
663 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Green",
664 strlen("Green"));
665 RDestroyImage(image);
666 WMSetSliderImage(panel->rgbGreenS, pixmap);
667 WMReleasePixmap(pixmap);
669 panel->rgbGreenT = WMCreateTextField(panel->rgbFrm);
670 WMResizeWidget(panel->rgbGreenT, 40, 18);
671 WMMoveWidget(panel->rgbGreenT, 146, 35);
672 WMSetTextFieldAlignment(panel->rgbGreenT, WALeft);
673 WMAddNotificationObserver(rgbTextFieldCallback, panel,
674 WMTextDidEndEditingNotification, panel->rgbGreenT);
677 panel->rgbBlueS = WMCreateSlider(panel->rgbFrm);
678 WMResizeWidget(panel->rgbBlueS, 141, 16);
679 WMMoveWidget(panel->rgbBlueS, 2, 58);
680 WMSetSliderMinValue(panel->rgbBlueS, 0);
681 WMSetSliderMaxValue(panel->rgbBlueS, 255);
682 WMSetSliderKnobThickness(panel->rgbBlueS, knobThickness);
683 WMSetSliderAction(panel->rgbBlueS, rgbSliderCallback, panel);
685 to.red = 0;
686 to.green = 0;
687 to.blue = 255;
689 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
690 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
691 W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12,
692 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Blue",
693 strlen("Blue"));
694 RDestroyImage(image);
695 WMSetSliderImage(panel->rgbBlueS, pixmap);
696 WMReleasePixmap(pixmap);
698 panel->rgbBlueT = WMCreateTextField(panel->rgbFrm);
699 WMResizeWidget(panel->rgbBlueT, 40, 18);
700 WMMoveWidget(panel->rgbBlueT, 146, 57);
701 WMSetTextFieldAlignment(panel->rgbBlueT, WALeft);
702 WMAddNotificationObserver(rgbTextFieldCallback, panel,
703 WMTextDidEndEditingNotification, panel->rgbBlueT);
704 /* End of RGB Panel */
706 /* Widgets for CMYK Panel */
707 panel->cmykFrm = WMCreateFrame(panel->slidersFrm);
708 WMSetFrameRelief(panel->cmykFrm, WRFlat);
709 WMResizeWidget(panel->cmykFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
710 WMMoveWidget(panel->cmykFrm, 0, 34);
712 panel->cmykMinL = WMCreateLabel(panel->cmykFrm);
713 WMResizeWidget(panel->cmykMinL, 20, 10);
714 WMMoveWidget(panel->cmykMinL, 2, 2);
715 WMSetLabelText(panel->cmykMinL, "0");
716 WMSetLabelTextAlignment(panel->cmykMinL, WALeft);
717 WMSetLabelTextColor(panel->cmykMinL, textcolor);
718 WMSetLabelFont(panel->cmykMinL, panel->font8);
720 panel->cmykMaxL = WMCreateLabel(panel->cmykFrm);
721 WMResizeWidget(panel->cmykMaxL, 40, 10);
722 WMMoveWidget(panel->cmykMaxL, 104, 2);
723 WMSetLabelText(panel->cmykMaxL, "100");
724 WMSetLabelTextAlignment(panel->cmykMaxL, WARight);
725 WMSetLabelTextColor(panel->cmykMaxL, textcolor);
726 WMSetLabelFont(panel->cmykMaxL, panel->font8);
728 panel->cmykCyanS = WMCreateSlider(panel->cmykFrm);
729 WMResizeWidget(panel->cmykCyanS, 141, 16);
730 WMMoveWidget(panel->cmykCyanS, 2, 14);
731 WMSetSliderMinValue(panel->cmykCyanS, 0);
732 WMSetSliderMaxValue(panel->cmykCyanS, 100);
733 WMSetSliderKnobThickness(panel->cmykCyanS, knobThickness);
734 WMSetSliderAction(panel->cmykCyanS, cmykSliderCallback, panel);
736 from.red = 255;
737 from.green = 255;
738 from.blue = 255;
740 to.red = 0;
741 to.green = 255;
742 to.blue = 255;
744 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
745 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
746 W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12,
747 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Cyan",
748 strlen("Cyan"));
749 RDestroyImage(image);
750 WMSetSliderImage(panel->cmykCyanS, pixmap);
751 WMReleasePixmap(pixmap);
753 panel->cmykCyanT = WMCreateTextField(panel->cmykFrm);
754 WMResizeWidget(panel->cmykCyanT, 40, 18);
755 WMMoveWidget(panel->cmykCyanT, 146, 13);
756 WMSetTextFieldAlignment(panel->cmykCyanT, WALeft);
757 WMAddNotificationObserver(cmykTextFieldCallback, panel,
758 WMTextDidEndEditingNotification, panel->cmykCyanT);
761 panel->cmykMagentaS = WMCreateSlider(panel->cmykFrm);
762 WMResizeWidget(panel->cmykMagentaS, 141, 16);
763 WMMoveWidget(panel->cmykMagentaS, 2, 36);
764 WMSetSliderMinValue(panel->cmykMagentaS, 0);
765 WMSetSliderMaxValue(panel->cmykMagentaS, 100);
766 WMSetSliderKnobThickness(panel->cmykMagentaS, knobThickness);
767 WMSetSliderAction(panel->cmykMagentaS, cmykSliderCallback, panel);
769 to.red = 255;
770 to.green = 0;
771 to.blue = 255;
773 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
774 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
775 W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12,
776 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Magenta",
777 strlen("Magenta"));
778 RDestroyImage(image);
779 WMSetSliderImage(panel->cmykMagentaS, pixmap);
780 WMReleasePixmap(pixmap);
782 panel->cmykMagentaT = WMCreateTextField(panel->cmykFrm);
783 WMResizeWidget(panel->cmykMagentaT, 40, 18);
784 WMMoveWidget(panel->cmykMagentaT, 146, 35);
785 WMSetTextFieldAlignment(panel->cmykMagentaT, WALeft);
786 WMAddNotificationObserver(cmykTextFieldCallback, panel,
787 WMTextDidEndEditingNotification, panel->cmykMagentaT);
790 panel->cmykYellowS = WMCreateSlider(panel->cmykFrm);
791 WMResizeWidget(panel->cmykYellowS, 141, 16);
792 WMMoveWidget(panel->cmykYellowS, 2, 58);
793 WMSetSliderMinValue(panel->cmykYellowS, 0);
794 WMSetSliderMaxValue(panel->cmykYellowS, 100);
795 WMSetSliderKnobThickness(panel->cmykYellowS, knobThickness);
796 WMSetSliderAction(panel->cmykYellowS, cmykSliderCallback, panel);
798 to.red = 255;
799 to.green = 255;
800 to.blue = 0;
802 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
803 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
804 W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12,
805 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Yellow",
806 strlen("Yellow"));
807 RDestroyImage(image);
808 WMSetSliderImage(panel->cmykYellowS, pixmap);
809 WMReleasePixmap(pixmap);
811 panel->cmykYellowT = WMCreateTextField(panel->cmykFrm);
812 WMResizeWidget(panel->cmykYellowT, 40, 18);
813 WMMoveWidget(panel->cmykYellowT, 146, 57);
814 WMSetTextFieldAlignment(panel->cmykYellowT, WALeft);
815 WMAddNotificationObserver(cmykTextFieldCallback, panel,
816 WMTextDidEndEditingNotification, panel->cmykYellowT);
819 panel->cmykBlackS = WMCreateSlider(panel->cmykFrm);
820 WMResizeWidget(panel->cmykBlackS, 141, 16);
821 WMMoveWidget(panel->cmykBlackS, 2, 80);
822 WMSetSliderMinValue(panel->cmykBlackS, 0);
823 WMSetSliderMaxValue(panel->cmykBlackS, 100);
824 WMSetSliderValue(panel->cmykBlackS, 0);
825 WMSetSliderKnobThickness(panel->cmykBlackS, knobThickness);
826 WMSetSliderAction(panel->cmykBlackS, cmykSliderCallback, panel);
828 to.red = 0;
829 to.green = 0;
830 to.blue = 0;
832 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
833 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
834 W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12,
835 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Black",
836 strlen("Black"));
837 RDestroyImage(image);
838 WMSetSliderImage(panel->cmykBlackS, pixmap);
839 WMReleasePixmap(pixmap);
841 panel->cmykBlackT = WMCreateTextField(panel->cmykFrm);
842 WMResizeWidget(panel->cmykBlackT, 40, 18);
843 WMMoveWidget(panel->cmykBlackT, 146, 79);
844 WMSetTextFieldAlignment(panel->cmykBlackT, WALeft);
845 WMAddNotificationObserver(cmykTextFieldCallback, panel,
846 WMTextDidEndEditingNotification, panel->cmykBlackT);
847 /* End of CMYK Panel */
849 /* Widgets for HSB Panel */
850 panel->hsbFrm = WMCreateFrame(panel->slidersFrm);
851 WMSetFrameRelief(panel->hsbFrm, WRFlat);
852 WMResizeWidget(panel->hsbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
853 WMMoveWidget(panel->hsbFrm, 0, 34);
855 panel->hsbHueS = WMCreateSlider(panel->hsbFrm);
856 WMResizeWidget(panel->hsbHueS, 141, 16);
857 WMMoveWidget(panel->hsbHueS, 2, 14);
858 WMSetSliderMinValue(panel->hsbHueS, 0);
859 WMSetSliderMaxValue(panel->hsbHueS, 359);
860 WMSetSliderKnobThickness(panel->hsbHueS, knobThickness);
861 WMSetSliderAction(panel->hsbHueS, hsbSliderCallback, panel);
863 panel->hsbHueT = WMCreateTextField(panel->hsbFrm);
864 WMResizeWidget(panel->hsbHueT, 40, 18);
865 WMMoveWidget(panel->hsbHueT, 146, 13);
866 WMSetTextFieldAlignment(panel->hsbHueT, WALeft);
867 WMAddNotificationObserver(hsbTextFieldCallback, panel,
868 WMTextDidEndEditingNotification, panel->hsbHueT);
871 panel->hsbSaturationS = WMCreateSlider(panel->hsbFrm);
872 WMResizeWidget(panel->hsbSaturationS, 141, 16);
873 WMMoveWidget(panel->hsbSaturationS, 2, 36);
874 WMSetSliderMinValue(panel->hsbSaturationS, 0);
875 WMSetSliderMaxValue(panel->hsbSaturationS, 100);
876 WMSetSliderKnobThickness(panel->hsbSaturationS, knobThickness);
877 WMSetSliderAction(panel->hsbSaturationS, hsbSliderCallback, panel);
879 panel->hsbSaturationT = WMCreateTextField(panel->hsbFrm);
880 WMResizeWidget(panel->hsbSaturationT, 40, 18);
881 WMMoveWidget(panel->hsbSaturationT, 146, 35);
882 WMSetTextFieldAlignment(panel->hsbSaturationT, WALeft);
883 WMAddNotificationObserver(hsbTextFieldCallback, panel,
884 WMTextDidEndEditingNotification, panel->hsbSaturationT);
887 panel->hsbBrightnessS = WMCreateSlider(panel->hsbFrm);
888 WMResizeWidget(panel->hsbBrightnessS, 141, 16);
889 WMMoveWidget(panel->hsbBrightnessS, 2, 58);
890 WMSetSliderMinValue(panel->hsbBrightnessS, 0);
891 WMSetSliderMaxValue(panel->hsbBrightnessS, 100);
892 WMSetSliderKnobThickness(panel->hsbBrightnessS, knobThickness);
893 WMSetSliderAction(panel->hsbBrightnessS, hsbSliderCallback, panel);
895 panel->hsbBrightnessT = WMCreateTextField(panel->hsbFrm);
896 WMResizeWidget(panel->hsbBrightnessT, 40, 18);
897 WMMoveWidget(panel->hsbBrightnessT, 146, 57);
898 WMSetTextFieldAlignment(panel->hsbBrightnessT, WALeft);
899 WMAddNotificationObserver(hsbTextFieldCallback, panel,
900 WMTextDidEndEditingNotification, panel->hsbBrightnessT);
901 /* End of HSB Panel */
904 WMReleaseColor(textcolor);
906 /* Widgets for the CustomPalette Panel */
907 panel->customPaletteFrm = WMCreateFrame(panel->win);
908 WMSetFrameRelief(panel->customPaletteFrm, WRFlat);
909 WMResizeWidget(panel->customPaletteFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
910 WMMoveWidget(panel->customPaletteFrm, 5, 80);
912 panel->customPaletteHistoryBtn = WMCreatePopUpButton(
913 panel->customPaletteFrm);
914 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, "Spectrum");
915 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
916 WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn)-1);
917 WMSetPopUpButtonAction(panel->customPaletteHistoryBtn,
918 customPaletteHistoryCallback, panel);
919 WMResizeWidget(panel->customPaletteHistoryBtn, PWIDTH - 8, 20);
920 WMMoveWidget(panel->customPaletteHistoryBtn, 0, 0);
922 panel->customPaletteContentFrm = WMCreateFrame(panel->customPaletteFrm);
923 WMSetFrameRelief(panel->customPaletteContentFrm, WRSunken);
924 WMResizeWidget(panel->customPaletteContentFrm, PWIDTH - 8, PHEIGHT - 156);
925 WMMoveWidget(panel->customPaletteContentFrm, 0, 23);
927 panel->customPaletteContentView = W_CreateView(
928 W_VIEW(panel->customPaletteContentFrm));
929 /* XXX Can we create a view ? */
930 W_ResizeView(panel->customPaletteContentView, customPaletteWidth,
931 customPaletteHeight);
932 W_MoveView(panel->customPaletteContentView, 2, 2);
934 /* Create event handler to handle expose/click events in CustomPalette */
935 WMCreateEventHandler(panel->customPaletteContentView,
936 ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
937 LeaveWindowMask|ButtonMotionMask, customPaletteHandleActionEvents,
938 panel);
940 WMCreateEventHandler(panel->customPaletteContentView, ExposureMask,
941 customPaletteHandleEvents, panel);
943 panel->customPaletteMenuBtn = WMCreatePopUpButton(panel->customPaletteFrm);
944 WMSetPopUpButtonPullsDown(panel->customPaletteMenuBtn, 1);
945 WMSetPopUpButtonText(panel->customPaletteMenuBtn, "Palette");
946 WMSetPopUpButtonAction(panel->customPaletteMenuBtn,
947 customPaletteMenuCallback, panel);
948 WMResizeWidget(panel->customPaletteMenuBtn, PWIDTH - 8, 20);
949 WMMoveWidget(panel->customPaletteMenuBtn, 0, PHEIGHT - 130);
951 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from File...");
952 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Rename...");
953 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Remove");
954 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Copy");
955 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from Clipboard");
957 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, 0);
958 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, 0);
959 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuCopy, 0);
960 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn,
961 CPmenuNewFromClipboard, 0);
963 customRenderSpectrum(panel);
964 panel->currentPalette = 0;
967 /* Widgets for the ColorList Panel */
968 panel->colorListFrm = WMCreateFrame(panel->win);
969 WMSetFrameRelief(panel->colorListFrm, WRFlat);
970 WMResizeWidget(panel->colorListFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
971 WMMoveWidget(panel->colorListFrm, 5, 80);
973 panel->colorListHistoryBtn = WMCreatePopUpButton(panel->colorListFrm);
974 WMAddPopUpButtonItem(panel->colorListHistoryBtn, "X11-Colors");
975 WMSetPopUpButtonSelectedItem(panel->colorListHistoryBtn,
976 WMGetPopUpButtonNumberOfItems(panel->colorListHistoryBtn)-1);
977 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
978 * colorListHistoryCallback, panel); */
979 WMResizeWidget(panel->colorListHistoryBtn, PWIDTH - 8, 20);
980 WMMoveWidget(panel->colorListHistoryBtn, 0, 0);
982 panel->colorListContentLst = WMCreateList(panel->colorListFrm);
983 WMSetListAction(panel->colorListContentLst, colorListSelect, panel);
984 WMSetListUserDrawProc(panel->colorListContentLst, colorListPaintItem);
985 WMResizeWidget(panel->colorListContentLst, PWIDTH - 8, PHEIGHT - 156);
986 WMMoveWidget(panel->colorListContentLst, 0, 23);
987 WMHangData(panel->colorListContentLst, panel);
989 panel->colorListColorMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
990 WMSetPopUpButtonPullsDown(panel->colorListColorMenuBtn, 1);
991 WMSetPopUpButtonText(panel->colorListColorMenuBtn, "Color");
992 WMSetPopUpButtonAction(panel->colorListColorMenuBtn,
993 colorListColorMenuCallback, panel);
994 WMResizeWidget(panel->colorListColorMenuBtn, (PWIDTH - 16)/2, 20);
995 WMMoveWidget(panel->colorListColorMenuBtn, 0, PHEIGHT - 130);
997 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Add...");
998 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Rename...");
999 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Remove");
1001 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuAdd, 0);
1002 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRename, 0);
1003 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRemove, 0);
1005 panel->colorListListMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
1006 WMSetPopUpButtonPullsDown(panel->colorListListMenuBtn, 1);
1007 WMSetPopUpButtonText(panel->colorListListMenuBtn, "List");
1008 WMSetPopUpButtonAction(panel->colorListListMenuBtn,
1009 colorListListMenuCallback, panel);
1010 WMResizeWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2, 20);
1011 WMMoveWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2 + 8,
1012 PHEIGHT - 130);
1014 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "New...");
1015 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Rename...");
1016 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Remove");
1018 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRename, 0);
1019 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRemove, 0);
1021 WMRealizeWidget(panel->win);
1022 WMMapSubwidgets(panel->win);
1024 WMMapSubwidgets(panel->wheelFrm);
1025 WMMapSubwidgets(panel->slidersFrm);
1026 WMMapSubwidgets(panel->grayFrm);
1027 WMMapSubwidgets(panel->rgbFrm);
1028 WMMapSubwidgets(panel->cmykFrm);
1029 WMMapSubwidgets(panel->hsbFrm);
1030 WMMapSubwidgets(panel->customPaletteFrm);
1031 WMMapSubwidgets(panel->customPaletteContentFrm);
1032 WMMapSubwidgets(panel->colorListFrm);
1034 readConfiguration(panel);
1035 readXColors(panel);
1037 return panel;
1041 WMColorPanel*
1042 WMGetColorPanel(WMScreen *scrPtr)
1044 WMColorPanel *panel;
1046 if (scrPtr->sharedColorPanel)
1047 return scrPtr->sharedColorPanel;
1049 panel = makeColorPanel(scrPtr, "colorPanel");
1051 scrPtr->sharedColorPanel = panel;
1053 return panel;
1057 void
1058 WMFreeColorPanel(WMColorPanel *panel)
1060 W_Screen *scr = WMWidgetScreen(panel->win);
1062 if (panel == scr->sharedColorPanel) {
1063 scr->sharedColorPanel = NULL;
1066 WMRemoveNotificationObserver(panel);
1068 WMUnmapWidget(panel->win);
1069 WMDestroyWidget(panel->win);
1071 /* fonts */
1072 if (panel->font8)
1073 WMReleaseFont(panel->font8);
1074 if (panel->font12)
1075 WMReleaseFont(panel->font12);
1077 /* pixmaps */
1078 if (panel->wheelMtrx)
1079 wheelDestroyMatrix(panel->wheelMtrx);
1080 if (panel->wheelImg)
1081 XFreePixmap(scr->display, panel->wheelImg);
1082 if (panel->selectionImg)
1083 XFreePixmap(scr->display, panel->selectionImg);
1084 if (panel->selectionBackImg)
1085 XFreePixmap(scr->display, panel->selectionBackImg);
1086 if (panel->customPaletteImg)
1087 RDestroyImage(panel->customPaletteImg);
1089 /* structs */
1090 if (panel->lastBrowseDir)
1091 free(panel->lastBrowseDir);
1092 if (panel->configurationPath)
1093 free(panel->configurationPath);
1095 free(panel);
1099 void
1100 WMCloseColorPanel(WMColorPanel *panel)
1102 WMCloseWindow(panel->win);
1103 WMFreeColorPanel(panel);
1107 void
1108 WMShowColorPanel(WMColorPanel *panel)
1110 WMScreen *scr = WMWidgetScreen(panel->win);
1111 WMColor *white = WMWhiteColor(scr);
1113 if (!panel->colorSet )
1114 WMSetColorPanelColor(panel, white);
1115 WMReleaseColor(white);
1117 WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel);
1118 wheelInit(panel);
1120 WMMapWidget(panel->win);
1124 static void
1125 closeWindowCallback(WMWidget *w, void *data)
1127 W_ColorPanel *panel = (W_ColorPanel*)data;
1129 WMCloseColorPanel(panel);
1133 static void
1134 readConfiguration(W_ColorPanel *panel)
1136 /* XXX Doesn't take care of "invalid" files */
1138 DIR *dPtr;
1139 struct dirent *dp;
1140 struct stat stat_buf;
1143 if (stat(panel->configurationPath, &stat_buf)!=0) {
1144 if (mkdir(panel->configurationPath,
1145 S_IRWXU|S_IRGRP|S_IROTH|S_IXGRP|S_IXOTH)!=0) {
1146 wsyserror("ColorPanel could not create directory %s needed"
1147 " to store configurations", panel->configurationPath);
1148 WMSetPopUpButtonEnabled(panel->customPaletteMenuBtn, False);
1149 WMSetPopUpButtonEnabled(panel->colorListColorMenuBtn, False);
1150 WMSetPopUpButtonEnabled(panel->colorListListMenuBtn, False);
1151 WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win,
1152 "File Error", "Could not create ColorPanel configuration"
1153 " directory", "OK", NULL, NULL);
1155 return;
1158 dPtr = opendir(panel->configurationPath);
1159 while ((dp = readdir(dPtr)) != NULL) {
1160 if (dp->d_name[0] != '.')
1161 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, dp->d_name);
1163 (void)closedir(dPtr);
1167 static void
1168 readXColors(W_ColorPanel *panel)
1170 struct stat stat_buf;
1171 FILE *rgbtxt;
1172 char line[MAX_LENGTH];
1173 int red, green, blue;
1174 char name[48];
1175 RColor *color;
1176 WMListItem *item;
1178 if (stat(RGBTXT, &stat_buf) != 0) {
1179 wwarning("Cannot find file %s", RGBTXT);
1180 return;
1182 else {
1183 rgbtxt = fopen(RGBTXT, "r");
1184 if (rgbtxt) {
1185 while (fgets(line, MAX_LENGTH, rgbtxt)) {
1186 if (sscanf(line, "%d%d%d %[^\n]", &red, &green, &blue, name)) {
1187 color = wmalloc(sizeof(RColor));
1188 color->red = (unsigned char)red;
1189 color->green = (unsigned char)green;
1190 color->blue = (unsigned char)blue;
1191 item = WMAddListItem(panel->colorListContentLst, name);
1192 item->clientData = (void *)color;
1195 fclose(rgbtxt);
1197 else {
1198 wsyserror("Unable to open file %s for reading", RGBTXT);
1204 void
1205 WMSetColorPanelPickerMode(WMColorPanel *panel, WMColorPanelMode mode)
1207 W_Screen *scr = WMWidgetScreen(panel->win);
1209 if (mode != WMWheelModeColorPanel) {
1210 WMUnmapWidget(panel->wheelFrm);
1211 if (panel->selectionBackImg) {
1212 XFreePixmap(WMWidgetScreen(panel->win)->display,
1213 panel->selectionBackImg);
1214 panel->selectionBackImg = None;
1217 if (mode != WMGrayModeColorPanel)
1218 WMUnmapWidget(panel->grayFrm);
1219 if (mode != WMRGBModeColorPanel)
1220 WMUnmapWidget(panel->rgbFrm);
1221 if (mode != WMCMYKModeColorPanel)
1222 WMUnmapWidget(panel->cmykFrm);
1223 if (mode != WMHSBModeColorPanel)
1224 WMUnmapWidget(panel->hsbFrm);
1225 if (mode != WMCustomPaletteModeColorPanel) {
1226 WMUnmapWidget(panel->customPaletteFrm);
1227 if (panel->selectionBackImg) {
1228 XFreePixmap(WMWidgetScreen(panel->win)->display,
1229 panel->selectionBackImg);
1230 panel->selectionBackImg = None;
1233 if (mode != WMColorListModeColorPanel)
1234 WMUnmapWidget(panel->colorListFrm);
1235 if ((mode != WMGrayModeColorPanel) && (mode != WMRGBModeColorPanel) &&
1236 (mode != WMCMYKModeColorPanel) && (mode != WMHSBModeColorPanel))
1237 WMUnmapWidget(panel->slidersFrm);
1238 else
1239 panel->slidersmode = mode;
1241 if (mode == WMWheelModeColorPanel) {
1242 WMMapWidget(panel->wheelFrm);
1243 WMSetButtonSelected(panel->wheelBtn, True);
1244 if (panel->lastChanged != WMWheelModeColorPanel)
1245 wheelInit(panel);
1246 wheelRender(panel);
1247 wheelPaint(panel);
1248 } else if (mode == WMGrayModeColorPanel) {
1249 WMMapWidget(panel->slidersFrm);
1250 WMSetButtonSelected(panel->slidersBtn, True);
1251 WMMapWidget(panel->grayFrm);
1252 WMSetButtonSelected(panel->grayBtn, True);
1253 WMSetButtonImage(panel->slidersBtn, scr->grayIcon);
1254 if (panel->lastChanged != WMGrayModeColorPanel)
1255 grayInit(panel);
1256 } else if (mode == WMRGBModeColorPanel) {
1257 WMMapWidget(panel->slidersFrm);
1258 WMSetButtonSelected(panel->slidersBtn, True);
1259 WMMapWidget(panel->rgbFrm);
1260 WMSetButtonSelected(panel->rgbBtn, True);
1261 WMSetButtonImage(panel->slidersBtn, scr->rgbIcon);
1262 if (panel->lastChanged != WMRGBModeColorPanel)
1263 rgbInit(panel);
1264 } else if (mode == WMCMYKModeColorPanel) {
1265 WMMapWidget(panel->slidersFrm);
1266 WMSetButtonSelected(panel->slidersBtn, True);
1267 WMMapWidget(panel->cmykFrm);
1268 WMSetButtonSelected(panel->cmykBtn, True);
1269 WMSetButtonImage(panel->slidersBtn, scr->cmykIcon);
1270 if (panel->lastChanged != WMCMYKModeColorPanel)
1271 cmykInit(panel);
1272 } else if (mode == WMHSBModeColorPanel) {
1273 WMMapWidget(panel->slidersFrm);
1274 WMSetButtonSelected(panel->slidersBtn, True);
1275 WMMapWidget(panel->hsbFrm);
1276 WMSetButtonSelected(panel->hsbBtn, True);
1277 WMSetButtonImage(panel->slidersBtn, scr->hsbIcon);
1278 if (panel->lastChanged != WMHSBModeColorPanel)
1279 hsbInit(panel);
1280 } else if (mode == WMCustomPaletteModeColorPanel) {
1281 WMMapWidget(panel->customPaletteFrm);
1282 WMSetButtonSelected(panel->customPaletteBtn, True);
1283 customSetPalette(panel);
1284 } else if (mode == WMColorListModeColorPanel) {
1285 WMMapWidget(panel->colorListFrm);
1286 WMSetButtonSelected(panel->colorListBtn, True);
1290 panel->mode = mode;
1293 void
1294 WMSetColorPanelColor(WMColorPanel *panel, WMColor *color)
1296 WMScreen *scr = WMWidgetScreen(panel->win);
1297 RHSVColor hsvcolor;
1298 RColor intcolor;
1299 GC bgc = WMColorGC(scr->black);
1300 GC wgc = WMColorGC(scr->white);
1301 int originalHue;
1303 WMSetColorWellColor(panel->colorWell, color);
1305 intcolor.red = color->color.red >> 8;
1306 intcolor.green = color->color.green >> 8;
1307 intcolor.blue = color->color.blue >> 8;
1309 panel->color = intcolor;
1310 panel->colorSet = True;
1312 /* If color was set by HSB-Panel do not convert back to hsv */
1313 if (panel->lastChanged != WMHSBModeColorPanel) {
1315 /* if color is black, hue is undetermined, so it must be restored */
1316 if ((panel->color.red == 0) &&
1317 (panel->color.green == 0) &&
1318 (panel->color.blue == 0) &&
1319 (panel->hsvcolor.hue <= 359))
1321 originalHue = panel->hsvcolor.hue;
1322 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1323 panel->hsvcolor.hue = originalHue;
1324 } else {
1325 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1329 panel->wheelMtrx = wheelInitMatrix(panel); /* Needs to be done After Color is set */
1331 /* Maybe put this in a sub-function ... Initialising selected images */
1332 RRGBtoHSV(&intcolor, &hsvcolor);
1333 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 +
1334 (hsvcolor.saturation/255.0) * cos( hsvcolor.hue*M_PI/180.0)));
1335 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 +
1336 (hsvcolor.saturation/255.0) * sin(-hsvcolor.hue*M_PI/180.0)));
1337 wheelUpdateBrightnessGradientFromHSV(panel, hsvcolor);
1338 WMSetSliderValue(panel->wheelBrightnessS, 255 - hsvcolor.value);
1340 panel->selectionImg = XCreatePixmap(scr->display,
1341 W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
1342 XFillRectangle(scr->display, panel->selectionImg, bgc, 0, 0, 4, 4);
1343 XFillRectangle(scr->display, panel->selectionImg, wgc, 1, 1, 2, 2);
1344 /* End of initialisation section */
1346 panel->palx = customPaletteWidth/2;
1347 panel->paly = customPaletteHeight/2;
1349 WMSetColorPanelPickerMode(panel, panel->mode);
1353 static void
1354 updateSwatch(WMColorPanel *panel, RColor color)
1356 WMScreen *scr = WMWidgetScreen(panel->win);
1357 WMColor *wellcolor;
1358 int originalHue;
1360 wellcolor = WMCreateRGBColor(scr, color.red << 8, color.green << 8,
1361 color.blue << 8, True);
1363 WMSetColorWellColor(panel->colorWell, wellcolor);
1364 WMReleaseColor(wellcolor);
1366 panel->color = color;
1368 /* If color was set by HSB-Panel do not convert back to hsv */
1369 if (panel->lastChanged != WMHSBModeColorPanel) {
1371 /* if color is black, hue is undetermined, so it must be restored */
1372 if ((panel->color.red == 0) &&
1373 (panel->color.green == 0) &&
1374 (panel->color.blue == 0) &&
1375 (panel->hsvcolor.hue <= 359))
1377 originalHue = panel->hsvcolor.hue;
1378 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1379 panel->hsvcolor.hue = originalHue;
1380 } else {
1381 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1385 if (panel->action && (!panel->flags.dragging || panel->flags.continuous)) {
1386 (*panel->action)(panel, panel->clientData);
1390 static void
1391 modeButtonCallback(WMWidget *w, void *data)
1393 W_ColorPanel *panel = (W_ColorPanel*)(data);
1395 if (w == panel->wheelBtn)
1396 WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel);
1397 else if (w == panel->slidersBtn)
1398 WMSetColorPanelPickerMode(panel, panel->slidersmode);
1399 else if (w == panel->customPaletteBtn)
1400 WMSetColorPanelPickerMode(panel, WMCustomPaletteModeColorPanel);
1401 else if (w == panel->colorListBtn)
1402 WMSetColorPanelPickerMode(panel, WMColorListModeColorPanel);
1403 else if (w == panel->grayBtn)
1404 WMSetColorPanelPickerMode(panel, WMGrayModeColorPanel);
1405 else if (w == panel->rgbBtn)
1406 WMSetColorPanelPickerMode(panel, WMRGBModeColorPanel);
1407 else if (w == panel->cmykBtn)
1408 WMSetColorPanelPickerMode(panel, WMCMYKModeColorPanel);
1409 else if (w == panel->hsbBtn)
1410 WMSetColorPanelPickerMode(panel, WMHSBModeColorPanel);
1414 /****************** Magnifying Cursor Functions *******************/
1415 static Pixmap
1416 magnifyGetImage(WMScreen *scr, int x, int y)
1418 XImage *image;
1419 Pixmap pixmap;
1420 int x0, y0, w0, h0;
1421 int displayWidth = DisplayWidth(scr->display, scr->screen);
1422 int displayHeight = DisplayHeight(scr->display, scr->screen);
1423 const int half_mask_width = (Cursor_mask_width +1)/2;
1424 const int half_mask_height = (Cursor_mask_height +1)/2;
1426 /* Coordinate correction for back pixmap
1427 * if magnifying glass is at screen-borders */
1428 x0 = 0; y0 = 0; w0 = Cursor_mask_width; h0 = Cursor_mask_height;
1430 if (x < half_mask_width) {
1431 if (x < 0) x = 0;
1432 x0 = half_mask_width - x;
1433 w0 = Cursor_mask_width - x0;
1436 if (x > displayWidth - half_mask_width) {
1437 if (x > displayWidth) x = displayWidth;
1438 w0 = Cursor_mask_width - (half_mask_width - (displayWidth - x));
1441 if (y < half_mask_height) {
1442 if (y < 0) y = 0;
1443 y0 = half_mask_height - y;
1444 h0 = Cursor_mask_height - y0;
1447 if (y > displayHeight - half_mask_height) {
1448 if (y > displayHeight) y = displayHeight;
1449 h0 = Cursor_mask_height - (half_mask_height - (displayHeight - y));
1451 /* end of coordinate correction */
1453 image = XGetImage(scr->display, scr->rootWin, x + x0 - Cursor_x_hot,
1454 y + y0 - Cursor_y_hot, w0, h0, AllPlanes, ZPixmap);
1456 pixmap = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1457 Cursor_mask_height, scr->depth);
1458 XPutImage(scr->display, pixmap, scr->copyGC, image, 0, 0, x0, y0, w0, h0);
1459 XDestroyImage(image);
1461 return pixmap;
1465 static Pixmap
1466 magnifyGetStorePixmap(WMColorPanel *panel, int x1, int y1, int x2, int y2)
1469 * (x1, y1) = topleft corner of existing rectangle
1470 * (x2, y2) = topleft corner of new position
1473 W_Screen *scr = WMWidgetScreen(panel->win);
1474 Pixmap pixmap;
1475 int xa, ya, xb, yb, w, h;
1477 if (x1 < x2) {
1478 xa = x2 - x1;
1479 xb = 0;
1480 } else {
1481 xa = 0;
1482 xb = x1 - x2;
1485 if (y1 < y2) {
1486 ya = y2 - y1;
1487 yb = 0;
1488 } else {
1489 ya = 0;
1490 yb = y1 - y2;
1493 w = Cursor_mask_width - abs(x1-x2);
1494 h = Cursor_mask_height - abs(y1-y2);
1496 /* Get pixmap from screen */
1497 pixmap = magnifyGetImage(scr, x2, y2);
1499 /* Copy previously stored pixmap on covered part of above pixmap */
1500 if (panel->magnifyGlass->valid)
1502 XCopyArea(scr->display, panel->magnifyGlass->pixmap, pixmap,
1503 scr->copyGC, xa, ya, w, h, xb, yb);
1505 /* Free it, so we can reuse it */
1506 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1509 return pixmap;
1513 static Pixmap
1514 magnifyCreatePixmap(WMColorPanel *panel)
1516 W_Screen *scr = WMWidgetScreen(panel->win);
1517 int u, v;
1518 int i, j;
1519 int ofs;
1520 Pixmap magPix;
1521 Pixmap backPix;
1522 RImage *pixelImg;
1523 const int half_mask_width = Cursor_mask_width/2;
1524 const int half_mask_height = Cursor_mask_height/2;
1528 * Get image
1531 /* Rectangle that's going to be the background */
1532 backPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1533 Cursor_mask_height , scr->depth);
1534 XCopyArea(scr->display, panel->magnifyGlass->pixmap, backPix, scr->copyGC,
1535 0, 0, Cursor_mask_width, Cursor_mask_height, 0, 0);
1538 * Magnify image
1541 magPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width +2,
1542 Cursor_mask_height +2, scr->depth);
1544 for (u=0; u<5+1; u++) /* Copy an area of 5x5 pixels from the center */
1545 for (v=0; v<5+1; v++)
1546 for (i=u*5; i < (u+1)*5; i++) /* magnify it 5 times */
1547 for (j=v*5; j < (v+1)*5; j++)
1548 XCopyArea(scr->display, backPix, magPix, scr->copyGC,
1549 u +9, v +9, 1, 1, i, j);
1551 /* Get color under hotspot */
1552 ofs = half_mask_width + half_mask_height * Cursor_mask_width;
1553 pixelImg = RCreateImageFromDrawable(scr->rcontext, backPix, backPix);
1554 panel->magnifyGlass->color.red = pixelImg->data[0][ofs];
1555 panel->magnifyGlass->color.green = pixelImg->data[1][ofs];
1556 panel->magnifyGlass->color.blue = pixelImg->data[2][ofs];
1557 RDestroyImage(pixelImg);
1559 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1560 XSetClipMask(scr->display, scr->clipGC, panel->magnifyGlass->mask);
1561 XSetClipOrigin(scr->display, scr->clipGC, 0, 0);
1563 XCopyArea(scr->display, magPix, backPix, scr->clipGC, 2, 2,
1564 Cursor_mask_width, Cursor_mask_height, 0, 0);
1565 /* (2,2) puts center pixel on center of glass */
1567 XFreePixmap(scr->display, magPix);
1569 return backPix;
1573 static WMView*
1574 magnifyCreateView(W_ColorPanel *panel)
1576 W_Screen *scr = WMWidgetScreen(panel->win);
1577 WMView *magView;
1579 magView = W_CreateTopView(scr);
1581 W_ResizeView(magView, Cursor_mask_width, Cursor_mask_height);
1583 magView->attribFlags |= CWOverrideRedirect | CWSaveUnder;
1584 magView->attribs.event_mask = StructureNotifyMask;
1585 magView->attribs.override_redirect = True;
1586 magView->attribs.save_under = True;
1588 W_RealizeView(magView);
1590 return magView;
1594 static Cursor
1595 magnifyGrabPointer(W_ColorPanel *panel)
1597 W_Screen *scr = WMWidgetScreen(panel->win);
1598 Pixmap magPixmap, magPixmap2;
1599 Cursor magCursor;
1600 XColor fgColor = {0, 0,0,0, DoRed|DoGreen|DoBlue};
1601 XColor bgColor = {0, 0xbf00, 0xa000, 0x5000, DoRed|DoGreen|DoBlue};
1603 /* Cursor creation stuff */
1604 magPixmap = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1605 Cursor_bits, Cursor_width, Cursor_height, 1, 0, 1);
1606 magPixmap2 = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1607 Cursor_shape_bits, Cursor_width, Cursor_height, 1, 0, 1);
1609 magCursor = XCreatePixmapCursor(scr->display, magPixmap, magPixmap2,
1610 &fgColor, &bgColor, Cursor_x_hot, Cursor_y_hot);
1612 XFreePixmap(scr->display, magPixmap);
1613 XFreePixmap(scr->display, magPixmap2);
1615 XRecolorCursor(scr->display, magCursor, &fgColor, &bgColor);
1617 /* Set up Pointer */
1618 XGrabPointer (scr->display, panel->magnifyGlass->view->window, True,
1619 PointerMotionMask | ButtonPressMask,
1620 GrabModeAsync, GrabModeAsync,
1621 scr->rootWin, magCursor, CurrentTime);
1623 return magCursor;
1627 static WMPoint
1628 magnifyInitialize(W_ColorPanel *panel)
1630 W_Screen *scr = WMWidgetScreen(panel->win);
1631 int x, y, u, v;
1632 unsigned int mask;
1633 Pixmap pixmap;
1634 WMPoint point;
1636 XQueryPointer(scr->display, scr->rootWin, &scr->rootWin,
1637 &W_VIEW(panel->win)->window, &x, &y, &u, &v, &mask);
1640 /* Clipmask to make magnified view-contents circular */
1641 panel->magnifyGlass->mask = XCreatePixmapFromBitmapData(scr->display,
1642 W_DRAWABLE(scr), Cursor_mask_bits,
1643 Cursor_mask_width, Cursor_mask_height, 1, 0, 1);
1645 /* Draw initial magnified part */
1646 panel->magnifyGlass->valid = False;
1647 /* also free's magnifyGlass->pixmap */
1648 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(panel, x, y, x, y);
1649 panel->magnifyGlass->valid = True;
1651 pixmap = magnifyCreatePixmap(panel);
1653 XSetWindowBackgroundPixmap(scr->display, panel->magnifyGlass->view->window,
1654 pixmap);
1655 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1656 XFlush(scr->display);
1658 XFreePixmap(scr->display, pixmap);
1660 point.x = x;
1661 point.y = y;
1663 return point;
1667 static void
1668 magnifyPutCursor(WMWidget *w, void *data)
1670 W_ColorPanel *panel = (W_ColorPanel*)(data);
1671 W_Screen *scr = WMWidgetScreen(panel->win);
1672 Cursor magCursor;
1673 int x, y;
1674 Pixmap pixmap;
1675 XEvent event;
1676 WMPoint initialPosition;
1678 /* Destroy wheelBackImg, so it'll update properly */
1679 if (panel->selectionBackImg) {
1680 XFreePixmap(WMWidgetScreen(panel->win)->display,
1681 panel->selectionBackImg);
1682 panel->selectionBackImg = None;
1685 /* Create magnifying glass */
1686 panel->magnifyGlass = wmalloc(sizeof(MovingView));
1687 panel->magnifyGlass->view = magnifyCreateView(panel);
1689 initialPosition = magnifyInitialize(panel);
1690 x = initialPosition.x;
1691 y = initialPosition.y;
1693 W_MoveView(panel->magnifyGlass->view,
1694 x - Cursor_x_hot +1,
1695 y - Cursor_y_hot +1);
1696 W_MapView(panel->magnifyGlass->view);
1698 magCursor = magnifyGrabPointer(panel);
1700 while(panel->magnifyGlass->valid)
1702 WMNextEvent(scr->display, &event);
1703 while (XCheckTypedEvent(scr->display, MotionNotify, &event)) {
1706 switch (event.type)
1708 case ButtonPress:
1709 if (event.xbutton.button == Button1) {
1710 updateSwatch(panel, panel->magnifyGlass->color);
1712 switch (panel->mode) {
1713 case WMWheelModeColorPanel:
1714 wheelInit(panel);
1715 wheelRender(panel);
1716 wheelPaint(panel);
1717 break;
1718 case WMGrayModeColorPanel:
1719 grayInit(panel);
1720 break;
1721 case WMRGBModeColorPanel:
1722 rgbInit(panel);
1723 break;
1724 case WMCMYKModeColorPanel:
1725 cmykInit(panel);
1726 break;
1727 case WMHSBModeColorPanel:
1728 hsbInit(panel);
1729 break;
1730 default:
1731 break;
1733 panel->lastChanged = panel->mode;
1734 panel->magnifyGlass->valid = False;
1735 WMSetButtonSelected(panel->magnifyBtn, False);
1736 break;
1738 case MotionNotify:
1739 /* Get a "dirty rectangle" */
1740 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(
1741 panel, x+1, y+1,
1742 event.xmotion.x_root+1, event.xmotion.y_root+1);
1743 /* also free's magnifyGlass->pixmap */
1745 /* Update coordinates */
1746 x = event.xmotion.x_root;
1747 y = event.xmotion.y_root;
1749 /* Move view */
1750 W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot +1,
1751 y - Cursor_y_hot +1);
1753 /* Put new image (with magn.) in view */
1754 pixmap = magnifyCreatePixmap(panel);
1755 XSetWindowBackgroundPixmap(scr->display,
1756 panel->magnifyGlass->view->window, pixmap);
1757 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1759 XFreePixmap(scr->display, pixmap);
1760 break;
1762 case FocusOut: /* fall through */
1763 case FocusIn:
1765 * Color Panel window (panel->win) lost or received focus.
1766 * We need to update the pixmap in the magnifying glass.
1768 XUngrabPointer(scr->display, CurrentTime);
1769 W_UnmapView(panel->magnifyGlass->view);
1771 magnifyInitialize(panel);
1773 W_MapView(panel->magnifyGlass->view);
1774 XGrabPointer (scr->display,
1775 panel->magnifyGlass->view->window,
1776 True,
1777 PointerMotionMask | ButtonPressMask,
1778 GrabModeAsync,
1779 GrabModeAsync,
1780 scr->rootWin,
1781 magCursor,
1782 CurrentTime);
1783 break;
1785 default:
1786 WMHandleEvent(&event);
1787 break;
1788 } /* of switch */
1790 panel->magnifyGlass->valid = False;
1792 XUngrabPointer(scr->display, CurrentTime);
1793 XFreeCursor(scr->display, magCursor);
1794 W_DestroyView(panel->magnifyGlass->view);
1796 XFreePixmap(scr->display, panel->magnifyGlass->mask);
1797 panel->magnifyGlass->mask = None;
1799 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1800 panel->magnifyGlass->pixmap = None;
1802 free(panel->magnifyGlass);
1807 /****************** WheelMatrix Functions ************************/
1809 static wheelMatrix*
1810 wheelCreateMatrix(unsigned int width, unsigned int height)
1812 wheelMatrix *matrix = NULL;
1813 int i;
1815 assert((width > 0) && (height > 0));
1817 matrix = malloc(sizeof(wheelMatrix));
1818 if (!matrix) {
1819 RErrorCode = RERR_NOMEMORY;
1820 return NULL;
1823 memset(matrix, 0, sizeof(wheelMatrix));
1824 matrix->width = width;
1825 matrix->height = height;
1826 for (i = 0; i < 3; i++) {
1827 matrix->data[i] = malloc(width*height*sizeof(unsigned char));
1828 if (!matrix->data[i])
1829 goto error;
1832 return matrix;
1834 error:
1835 for (i = 0; i < 3; i++) {
1836 if (matrix->data[i])
1837 free(matrix->data[i]);
1839 if (matrix)
1840 free(matrix);
1841 RErrorCode = RERR_NOMEMORY;
1842 return NULL;
1846 static void
1847 wheelDestroyMatrix(wheelMatrix *matrix)
1849 int i;
1851 assert (matrix!=NULL);
1853 for (i = 0; i < 3; i++) {
1854 if (matrix->data[i])
1855 free(matrix->data[i]);
1857 free(matrix);
1861 static wheelMatrix*
1862 wheelInitMatrix(W_ColorPanel *panel)
1864 int i;
1865 int x,y;
1866 wheelMatrix *matrix;
1867 unsigned char *rp, *gp, *bp;
1868 RHSVColor cur_hsv;
1869 RColor cur_rgb;
1870 long ofs[4];
1871 float hue;
1872 int sat;
1873 float xcor, ycor;
1874 int dhue[4];
1876 matrix = wheelCreateMatrix(colorWheelSize+4, colorWheelSize+4);
1877 if (!matrix)
1878 return NULL;
1880 RRGBtoHSV(&panel->color, &cur_hsv);
1882 for (i = 0; i < 256; i++)
1883 matrix->values[i] = (unsigned char)(rint(i*cur_hsv.value/255));
1885 cur_hsv.value = 255;
1887 ofs[0] = -1;
1888 ofs[1] = -(colorWheelSize + 4);
1889 /* ofs[2] = 0; superfluous
1890 ofs[3] = 0;
1892 for (y = 0; y < (colorWheelSize+4)/2; y++) {
1893 for (x = y; x < (colorWheelSize+4-y); x++) {
1894 xcor = ((float)(2.0*x - 4.0) / colorWheelSize) - 1;
1895 ycor = ((float)(2.0*y - 4.0) / colorWheelSize) - 1;
1897 sat = rint(255.0 * sqrt((xcor*xcor) + (ycor*ycor)));
1901 /* offsets are counterclockwise (in triangles) */
1903 /* top quarter */
1904 if (y < (colorWheelSize+4)/2)
1905 ofs[0]++;
1907 /* left quarter */
1908 ofs[1] += colorWheelSize + 4;
1910 /* bottom quarter */
1911 ofs[2] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[0];
1913 /* right quarter */
1914 ofs[3] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[1];
1916 if (sat < 256) {
1917 cur_hsv.saturation = (unsigned char)sat;
1919 if (xcor != 0)
1920 hue = atan(ycor/xcor);
1921 else {
1922 if (ycor > 0)
1923 hue = M_PI * 0.5;
1924 else
1925 hue = M_PI * 1.5;
1928 if (xcor < 0)
1929 hue += M_PI;
1930 if ((xcor > 0) && (ycor < 0))
1931 hue += M_PI * 2.0;
1933 hue = -hue; /* Reverse direction of ColorWheel */
1935 if (hue < 0)
1936 hue += M_PI * 2.0;
1938 dhue[0] = (hue*360) / (M_PI * 2.0);
1940 for (i = 0; i < 4; i++) {
1942 if (i > 0)
1943 dhue[i] = (dhue[i-1] + 90) % 360;
1945 if ((i == 1) || (i == 3))
1946 dhue[i] = 360 - dhue[i];
1948 if (i == 2)
1949 dhue[i] = 360 - dhue[i] + 180;
1951 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1952 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1953 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1955 cur_hsv.hue = dhue[i];
1956 RHSVtoRGB(&cur_hsv, &cur_rgb);
1958 *rp = (unsigned char)(cur_rgb.red);
1959 *gp = (unsigned char)(cur_rgb.green);
1960 *bp = (unsigned char)(cur_rgb.blue);
1963 else {
1964 for (i = 0; i < 4; i++) {
1965 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1966 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1967 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1969 *rp = (unsigned char)(0);
1970 *gp = (unsigned char)(0);
1971 *bp = (unsigned char)(0);
1975 if (y < (colorWheelSize+4)/2)
1976 ofs[0] += 2*y+1;
1978 ofs[1] += 1 - (colorWheelSize + 4) * (colorWheelSize + 4 - 1 - 2*y);
1981 return matrix;
1984 /****************** ColorWheel Functions *******************/
1986 static void
1987 wheelRender(W_ColorPanel *panel)
1989 W_Screen *scr = WMWidgetScreen(panel->win);
1990 int x,y;
1991 RImage *image;
1992 unsigned char *rp, *gp, *bp;
1993 RColor gray;
1994 unsigned long ofs;
1996 image = RCreateImage(colorWheelSize+4, colorWheelSize+4, False);
1997 if (!image)
1998 return;
2000 gray.red = gray.green = gray.blue = 0xaa;
2002 for (x = 0; x < colorWheelSize+4; x++) {
2003 for (y = 0; y < colorWheelSize+4; y++) {
2005 ofs = (y * image->width) + x;
2006 rp = image->data[0] + ofs;
2007 gp = image->data[1] + ofs;
2008 bp = image->data[2] + ofs;
2010 if (wheelInsideColorWheel(panel, ofs)) {
2011 *rp = (unsigned int)(panel->wheelMtrx->values[
2012 panel->wheelMtrx->data[0][ofs] ]);
2013 *gp = (unsigned int)(panel->wheelMtrx->values[
2014 panel->wheelMtrx->data[1][ofs] ]);
2015 *bp = (unsigned int)(panel->wheelMtrx->values[
2016 panel->wheelMtrx->data[2][ofs] ]);
2018 else {
2019 *rp = (unsigned char)(gray.red);
2020 *gp = (unsigned char)(gray.green);
2021 *bp = (unsigned char)(gray.blue);
2026 if (panel->wheelImg)
2027 XFreePixmap(scr->display, panel->wheelImg);
2029 panel->wheelImg = XCreatePixmap(scr->display, W_DRAWABLE(scr),
2030 colorWheelSize+4, colorWheelSize+4, scr->depth);
2031 RConvertImage(scr->rcontext, image, &panel->wheelImg);
2033 /* Check if backimage exists. If it doesn't, allocate and fill it */
2034 if (!panel->selectionBackImg) {
2035 panel->selectionBackImg = XCreatePixmap(scr->display,
2036 W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
2037 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg,
2038 scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0);
2039 /* -2 is hot spot correction */
2042 RDestroyImage(image);
2045 static Bool
2046 wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs)
2048 return ((panel->wheelMtrx->data[0][ofs] != 0) &&
2049 (panel->wheelMtrx->data[1][ofs] != 0) &&
2050 (panel->wheelMtrx->data[2][ofs] != 0));
2053 static void
2054 wheelPaint (W_ColorPanel *panel)
2056 W_Screen *scr = WMWidgetScreen(panel->win);
2058 XCopyArea(scr->display, panel->wheelImg, panel->wheelView->window,
2059 scr->copyGC, 0, 0, colorWheelSize+4, colorWheelSize+4, 0, 0);
2061 /* Draw selection image */
2062 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window,
2063 scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
2066 static void
2067 wheelHandleEvents(XEvent *event, void *data)
2069 W_ColorPanel *panel = (W_ColorPanel*)data;
2071 switch (event->type) {
2072 case Expose:
2073 if (event->xexpose.count != 0)
2074 break;
2075 wheelPaint(panel);
2076 break;
2080 static void
2081 wheelHandleActionEvents(XEvent *event, void *data)
2083 W_ColorPanel *panel = (W_ColorPanel*)data;
2085 switch (event->type) {
2086 case ButtonPress:
2087 if (getPickerPart(panel, event->xbutton.x, event->xbutton.y) ==
2088 COLORWHEEL_PART) {
2089 panel->flags.dragging = 1;
2090 wheelPositionSelection(panel, event->xbutton.x,
2091 event->xbutton.y);
2093 break;
2095 case ButtonRelease:
2096 panel->flags.dragging = 0;
2097 if (!panel->flags.continuous) {
2098 if (panel->action)
2099 (*panel->action)(panel->action, panel->clientData);
2101 break;
2103 case MotionNotify:
2104 if (panel->flags.dragging) {
2105 if (getPickerPart(panel, event->xmotion.x, event->xmotion.y) ==
2106 COLORWHEEL_PART) {
2107 wheelPositionSelection(panel, event->xmotion.x,
2108 event->xmotion.y);
2110 else
2111 wheelPositionSelectionOutBounds(panel, event->xmotion.x,
2112 event->xmotion.y);
2114 break;
2119 static int
2120 getPickerPart(W_ColorPanel *panel, int x, int y)
2122 int lx, ly;
2123 unsigned long ofs;
2125 lx = x;
2126 ly = y;
2128 if (panel->mode == WMWheelModeColorPanel) {
2129 if ((lx >= 2) && (lx <= 2+colorWheelSize) && (ly >= 2) &&
2130 (ly <= 2+colorWheelSize)) {
2132 ofs = ly*panel->wheelMtrx->width+lx;
2134 if (wheelInsideColorWheel(panel, ofs))
2135 return COLORWHEEL_PART;
2139 if (panel->mode == WMCustomPaletteModeColorPanel) {
2140 if ((lx >= 2) && (lx < customPaletteWidth-2) && (ly >= 2) &&
2141 (ly < customPaletteHeight-2)) {
2142 return CUSTOMPALETTE_PART;
2146 return 0;
2150 static void
2151 wheelBrightnessSliderCallback(WMWidget *w, void *data)
2153 int i;
2154 unsigned int v;
2155 int value;
2156 unsigned long ofs;
2157 RColor cur_rgb;
2159 W_ColorPanel *panel = (W_ColorPanel*)data;
2161 value = 255-WMGetSliderValue(panel->wheelBrightnessS);
2163 for (i = 0; i < 256; i++) {
2164 /* We divide by 128 in advance, and check whether that number divides
2165 * by 2 properly. If not, we add one to round the number correctly
2167 v = (i*value) >> 7;
2168 #ifdef EASTEREGG
2169 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + v);
2170 #else
2171 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) +(v & 0x01));
2172 #endif
2175 ofs = (panel->coly * panel->wheelMtrx->width) + panel->colx;
2177 if (!wheelInsideColorWheel(panel, ofs)) {
2178 panel->hsvcolor.saturation = 255;
2179 panel->hsvcolor.value = value;
2180 RHSVtoRGB(&panel->hsvcolor, &cur_rgb);
2182 panel->color = cur_rgb;
2184 else {
2185 panel->color.red = panel->wheelMtrx->values[
2186 panel->wheelMtrx->data[0][ofs] ];
2187 panel->color.green = panel->wheelMtrx->values[
2188 panel->wheelMtrx->data[1][ofs] ];
2189 panel->color.blue = panel->wheelMtrx->values[
2190 panel->wheelMtrx->data[2][ofs] ];
2193 wheelRender(panel);
2194 wheelPaint(panel);
2195 wheelUpdateSelection(panel);
2199 static void
2200 wheelUpdateSelection(W_ColorPanel *panel)
2202 W_Screen *scr = WMWidgetScreen(panel->win);
2204 updateSwatch(panel, panel->color);
2205 panel->lastChanged = WMWheelModeColorPanel;
2207 /* Redraw color selector (and make a backup of the part it will cover) */
2208 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg,
2209 scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0);
2210 /* "-2" is correction for hotspot location */
2211 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window,
2212 scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
2213 /* see above */
2216 static void
2217 wheelUndrawSelection(W_ColorPanel *panel)
2219 W_Screen *scr = WMWidgetScreen(panel->win);
2221 XCopyArea(scr->display, panel->selectionBackImg, panel->wheelView->window,
2222 scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
2223 /* see above */
2226 static void
2227 wheelPositionSelection(W_ColorPanel *panel, int x, int y)
2229 unsigned long ofs = (y * panel->wheelMtrx->width)+ x;
2232 panel->color.red = panel->wheelMtrx->values[
2233 panel->wheelMtrx->data[0][ofs] ];
2234 panel->color.green = panel->wheelMtrx->values[
2235 panel->wheelMtrx->data[1][ofs] ];
2236 panel->color.blue = panel->wheelMtrx->values[
2237 panel->wheelMtrx->data[2][ofs] ];
2239 wheelUndrawSelection(panel);
2241 panel->colx = x;
2242 panel->coly = y;
2244 wheelUpdateSelection(panel);
2245 wheelUpdateBrightnessGradientFromLocation(panel);
2248 static void
2249 wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2251 RHSVColor cur_hsv;
2252 float hue;
2253 float xcor, ycor;
2255 xcor = ((x*2.0) / (colorWheelSize+4)) - 1.0;
2256 ycor = ((y*2.0) / (colorWheelSize+4)) - 1.0;
2258 cur_hsv.saturation = 255;
2259 cur_hsv.value = 255 - WMGetSliderValue(panel->wheelBrightnessS);
2261 if (xcor != 0)
2262 hue = atan(ycor/xcor);
2263 else {
2264 if (ycor > 0)
2265 hue = M_PI * 0.5;
2266 else
2267 hue = M_PI * 1.5;
2270 if (xcor < 0)
2271 hue += M_PI;
2272 if ((xcor > 0) && (ycor < 0))
2273 hue += M_PI * 2.0;
2275 hue = -hue;
2277 if (hue < 0)
2278 hue += M_PI * 2.0;
2280 cur_hsv.hue = (hue*180.0)/(M_PI);
2281 RHSVtoRGB(&cur_hsv, &panel->color);
2283 wheelUndrawSelection(panel);
2285 panel->colx = 2 + rint((colorWheelSize * (1.0 +
2286 cos( cur_hsv.hue*M_PI/180))) /2.0);
2287 /* "+2" because of "colorWheelSize + 4" */
2288 panel->coly = 2 + rint((colorWheelSize * (1.0 +
2289 sin(-cur_hsv.hue*M_PI/180))) /2.0);
2291 wheelUpdateSelection(panel);
2292 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
2295 static void
2296 wheelUpdateBrightnessGradientFromHSV(W_ColorPanel *panel, RHSVColor topColor)
2298 RColor from;
2300 /* Update Brightness-Slider */
2301 topColor.value = 255;
2302 RHSVtoRGB(&topColor, &from);
2304 wheelUpdateBrightnessGradient(panel, from);
2307 static void
2308 wheelUpdateBrightnessGradientFromLocation(W_ColorPanel *panel)
2310 RColor from;
2311 unsigned long ofs;
2313 ofs = panel->coly * panel->wheelMtrx->width + panel->colx;
2315 from.red = panel->wheelMtrx->data[0][ofs];
2316 from.green = panel->wheelMtrx->data[1][ofs];
2317 from.blue = panel->wheelMtrx->data[2][ofs];
2319 wheelUpdateBrightnessGradient(panel, from);
2322 static void
2323 wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor)
2325 RColor to;
2326 RImage *sliderImg;
2327 WMPixmap *sliderPxmp;
2329 to.red = to.green = to.blue = 0;
2331 sliderImg = RRenderGradient(16, 153, &topColor, &to, RGRD_VERTICAL);
2332 sliderPxmp = WMCreatePixmapFromRImage(WMWidgetScreen(panel->win),
2333 sliderImg, 0);
2334 RDestroyImage(sliderImg);
2335 WMSetSliderImage(panel->wheelBrightnessS, sliderPxmp);
2336 WMReleasePixmap(sliderPxmp);
2339 /****************** Grayscale Panel Functions ***************/
2341 static void
2342 grayBrightnessSliderCallback(WMWidget *w, void *data)
2344 RColor color;
2345 int value;
2346 char tmp[4];
2348 W_ColorPanel *panel = (W_ColorPanel*)data;
2350 value = WMGetSliderValue(panel->grayBrightnessS);
2352 sprintf(tmp, "%d", value);
2354 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2355 color.red = color.green = color.blue = rint(2.55*value);
2357 updateSwatch(panel, color);
2358 panel->lastChanged = WMGrayModeColorPanel;
2361 static void
2362 grayPresetButtonCallback(WMWidget *w, void *data)
2364 RColor color;
2365 char tmp[4];
2366 int value;
2367 int i=0;
2369 W_ColorPanel *panel = (W_ColorPanel*)data;
2371 while (i < 7) {
2372 if (w == panel->grayPresetBtn[i])
2373 break;
2374 i++;
2377 value = rint(100.0/6.0*i);
2378 sprintf(tmp, "%d", value);
2380 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2381 color.red = color.green = color.blue = rint(255.0*i/6.0);
2383 WMSetSliderValue(panel->grayBrightnessS, rint(100.0*i/6.0));
2385 updateSwatch(panel, color);
2386 panel->lastChanged = WMGrayModeColorPanel;
2389 static void
2390 grayBrightnessTextFieldCallback(void *observerData,
2391 WMNotification *notification)
2393 RColor color;
2394 char tmp[4];
2395 int value;
2396 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2398 value = atoi(WMGetTextFieldText(panel->grayBrightnessT));
2399 if (value > 100)
2400 value = 100;
2401 if (value < 0)
2402 value = 0;
2404 sprintf(tmp, "%d", value);
2405 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2406 WMSetSliderValue(panel->grayBrightnessS, value);
2408 color.red = color.green = color.blue = rint(255.0*value/100.0);
2409 updateSwatch(panel, color);
2410 panel->lastChanged = WMGrayModeColorPanel;
2413 /******************* RGB Panel Functions *****************/
2415 static void
2416 rgbSliderCallback(WMWidget *w, void *data)
2418 RColor color;
2419 int value[3];
2420 char tmp[4];
2422 W_ColorPanel *panel = (W_ColorPanel*)data;
2424 value[0] = WMGetSliderValue(panel->rgbRedS);
2425 value[1] = WMGetSliderValue(panel->rgbGreenS);
2426 value[2] = WMGetSliderValue(panel->rgbBlueS);
2428 sprintf(tmp, "%d", value[0]);
2429 WMSetTextFieldText(panel->rgbRedT, tmp);
2430 sprintf(tmp, "%d", value[1]);
2431 WMSetTextFieldText(panel->rgbGreenT, tmp);
2432 sprintf(tmp, "%d", value[2]);
2433 WMSetTextFieldText(panel->rgbBlueT, tmp);
2435 color.red = value[0];
2436 color.green = value[1];
2437 color.blue = value[2];
2439 updateSwatch(panel, color);
2440 panel->lastChanged = WMRGBModeColorPanel;
2443 static void
2444 rgbTextFieldCallback(void *observerData, WMNotification *notification)
2446 RColor color;
2447 int value[3];
2448 char tmp[4];
2449 int n;
2450 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2452 value[0] = atoi(WMGetTextFieldText(panel->rgbRedT));
2453 value[1] = atoi(WMGetTextFieldText(panel->rgbGreenT));
2454 value[2] = atoi(WMGetTextFieldText(panel->rgbBlueT));
2456 for (n=0; n < 3; n++) {
2457 if (value[n] > 255)
2458 value[n] = 255;
2459 if (value[n] < 0)
2460 value[n] = 0;
2463 sprintf(tmp, "%d", value[0]);
2464 WMSetTextFieldText(panel->rgbRedT, tmp);
2465 sprintf(tmp, "%d", value[1]);
2466 WMSetTextFieldText(panel->rgbGreenT, tmp);
2467 sprintf(tmp, "%d", value[2]);
2468 WMSetTextFieldText(panel->rgbBlueT, tmp);
2470 WMSetSliderValue(panel->rgbRedS, value[0]);
2471 WMSetSliderValue(panel->rgbGreenS, value[1]);
2472 WMSetSliderValue(panel->rgbBlueS, value[2]);
2474 color.red = value[0];
2475 color.green = value[1];
2476 color.blue = value[2];
2478 updateSwatch(panel, color);
2479 panel->lastChanged = WMRGBModeColorPanel;
2483 /******************* CMYK Panel Functions *****************/
2485 static void
2486 cmykSliderCallback(WMWidget *w, void *data)
2488 RColor color;
2489 int value[4];
2490 char tmp[4];
2492 W_ColorPanel *panel = (W_ColorPanel*)data;
2494 value[0] = WMGetSliderValue(panel->cmykCyanS);
2495 value[1] = WMGetSliderValue(panel->cmykMagentaS);
2496 value[2] = WMGetSliderValue(panel->cmykYellowS);
2497 value[3] = WMGetSliderValue(panel->cmykBlackS);
2499 sprintf(tmp, "%d", value[0]);
2500 WMSetTextFieldText(panel->cmykCyanT, tmp);
2501 sprintf(tmp, "%d", value[1]);
2502 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2503 sprintf(tmp, "%d", value[2]);
2504 WMSetTextFieldText(panel->cmykYellowT, tmp);
2505 sprintf(tmp, "%d", value[3]);
2506 WMSetTextFieldText(panel->cmykBlackT, tmp);
2508 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2509 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3]/100.0)));
2510 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] /100.0)));
2512 updateSwatch(panel, color);
2513 panel->lastChanged = WMCMYKModeColorPanel;
2516 static void
2517 cmykTextFieldCallback(void *observerData, WMNotification *notification)
2519 RColor color;
2520 int value[4];
2521 char tmp[4];
2522 int n;
2523 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2525 value[0] = atoi(WMGetTextFieldText(panel->cmykCyanT));
2526 value[1] = atoi(WMGetTextFieldText(panel->cmykMagentaT));
2527 value[2] = atoi(WMGetTextFieldText(panel->cmykYellowT));
2528 value[3] = atoi(WMGetTextFieldText(panel->cmykBlackT));
2530 for (n=0; n < 4; n++) {
2531 if (value[n] > 100)
2532 value[n] = 100;
2533 if (value[n] < 0)
2534 value[n] = 0;
2537 sprintf(tmp, "%d", value[0]);
2538 WMSetTextFieldText(panel->cmykCyanT, tmp);
2539 sprintf(tmp, "%d", value[1]);
2540 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2541 sprintf(tmp, "%d", value[2]);
2542 WMSetTextFieldText(panel->cmykYellowT, tmp);
2543 sprintf(tmp, "%d", value[3]);
2544 WMSetTextFieldText(panel->cmykBlackT, tmp);
2546 WMSetSliderValue(panel->cmykCyanS, value[0]);
2547 WMSetSliderValue(panel->cmykMagentaS, value[1]);
2548 WMSetSliderValue(panel->cmykYellowS, value[2]);
2549 WMSetSliderValue(panel->cmykBlackS, value[3]);
2551 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2552 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3]/100.0)));
2553 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] /100.0)));
2555 updateSwatch(panel, color);
2556 panel->lastChanged = WMCMYKModeColorPanel;
2559 /********************** HSB Panel Functions ***********************/
2561 static void
2562 hsbSliderCallback(WMWidget *w, void *data)
2564 RColor color;
2565 int value[3];
2566 char tmp[4];
2568 W_ColorPanel *panel = (W_ColorPanel*)data;
2570 value[0] = WMGetSliderValue(panel->hsbHueS);
2571 value[1] = WMGetSliderValue(panel->hsbSaturationS);
2572 value[2] = WMGetSliderValue(panel->hsbBrightnessS);
2574 sprintf(tmp, "%d", value[0]);
2575 WMSetTextFieldText(panel->hsbHueT, tmp);
2576 sprintf(tmp, "%d", value[1]);
2577 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2578 sprintf(tmp, "%d", value[2]);
2579 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2581 panel->hsvcolor.hue = value[0];
2582 panel->hsvcolor.saturation = value[1]*2.55;
2583 panel->hsvcolor.value = value[2]*2.55;
2585 RHSVtoRGB(&panel->hsvcolor, &color);
2587 panel->lastChanged = WMHSBModeColorPanel;
2588 updateSwatch(panel, color);
2590 if (w != panel->hsbBrightnessS)
2591 hsbUpdateBrightnessGradient(panel);
2592 if (w != panel->hsbSaturationS)
2593 hsbUpdateSaturationGradient(panel);
2594 if (w != panel->hsbHueS)
2595 hsbUpdateHueGradient(panel);
2598 static void
2599 hsbTextFieldCallback(void *observerData, WMNotification *notification)
2601 RColor color;
2602 int value[3];
2603 char tmp[4];
2604 int n;
2605 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2607 value[0] = atoi(WMGetTextFieldText(panel->hsbHueT));
2608 value[1] = atoi(WMGetTextFieldText(panel->hsbSaturationT));
2609 value[2] = atoi(WMGetTextFieldText(panel->hsbBrightnessT));
2611 if (value[0] > 359)
2612 value[0] = 359;
2613 if (value[0] < 0)
2614 value[0] = 0;
2616 for (n=1; n < 3; n++) {
2617 if (value[n] > 100)
2618 value[n] = 100;
2619 if (value[n] < 0)
2620 value[n] = 0;
2623 sprintf(tmp, "%d", value[0]);
2624 WMSetTextFieldText(panel->hsbHueT, tmp);
2625 sprintf(tmp, "%d", value[1]);
2626 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2627 sprintf(tmp, "%d", value[2]);
2628 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2630 WMSetSliderValue(panel->hsbHueS, value[0]);
2631 WMSetSliderValue(panel->hsbSaturationS, value[1]);
2632 WMSetSliderValue(panel->hsbBrightnessS, value[2]);
2634 panel->hsvcolor.hue = value[0];
2635 panel->hsvcolor.saturation = value[1]*2.55;
2636 panel->hsvcolor.value = value[2]*2.55;
2638 RHSVtoRGB(&panel->hsvcolor, &color);
2640 panel->lastChanged = WMHSBModeColorPanel;
2641 updateSwatch(panel, color);
2643 hsbUpdateBrightnessGradient(panel);
2644 hsbUpdateSaturationGradient(panel);
2645 hsbUpdateHueGradient(panel);
2648 static void
2649 hsbUpdateBrightnessGradient(W_ColorPanel *panel)
2651 W_Screen *scr = WMWidgetScreen(panel->win);
2652 RColor from;
2653 RColor to;
2654 RHSVColor hsvcolor;
2655 RImage *sliderImg;
2656 WMPixmap *sliderPxmp;
2658 from.red = from.green = from.blue = 0;
2659 hsvcolor = panel->hsvcolor;
2660 hsvcolor.value = 255;
2662 RHSVtoRGB(&hsvcolor, &to);
2664 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2665 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2666 RDestroyImage(sliderImg);
2667 W_PaintText(W_VIEW(panel->hsbBrightnessS), sliderPxmp->pixmap,
2668 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
2669 "Brightness", strlen("Brightness"));
2670 WMSetSliderImage(panel->hsbBrightnessS, sliderPxmp);
2671 WMReleasePixmap(sliderPxmp);
2674 static void
2675 hsbUpdateSaturationGradient(W_ColorPanel *panel)
2677 W_Screen *scr = WMWidgetScreen(panel->win);
2678 RColor from;
2679 RColor to;
2680 RHSVColor hsvcolor;
2681 RImage *sliderImg;
2682 WMPixmap *sliderPxmp;
2684 hsvcolor = panel->hsvcolor;
2685 hsvcolor.saturation = 0;
2686 RHSVtoRGB(&hsvcolor, &from);
2688 hsvcolor.saturation = 255;
2689 RHSVtoRGB(&hsvcolor, &to);
2691 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2692 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2693 RDestroyImage(sliderImg);
2694 if (hsvcolor.value < 128)
2695 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap,
2696 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
2697 "Saturation", strlen("Saturation"));
2698 else
2699 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap,
2700 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False,
2701 "Saturation", strlen("Saturation"));
2703 WMSetSliderImage(panel->hsbSaturationS, sliderPxmp);
2704 WMReleasePixmap(sliderPxmp);
2707 static void
2708 hsbUpdateHueGradient(W_ColorPanel *panel)
2710 W_Screen *scr = WMWidgetScreen(panel->win);
2711 RColor **colors = NULL;
2712 RHSVColor hsvcolor;
2713 RImage *sliderImg;
2714 WMPixmap *sliderPxmp;
2715 int i;
2717 hsvcolor = panel->hsvcolor;
2719 colors = malloc(sizeof(RColor*)*(8));
2720 for (i=0; i<7; i++) {
2721 hsvcolor.hue = (360*i)/6;
2722 colors[i] = malloc(sizeof(RColor));
2723 RHSVtoRGB(&hsvcolor, colors[i]);
2725 colors[7] = NULL;
2727 sliderImg = RRenderMultiGradient(141, 16, colors, RGRD_HORIZONTAL);
2728 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2729 RDestroyImage(sliderImg);
2730 if (hsvcolor.value < 128)
2731 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap,
2732 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
2733 "Hue", strlen("Hue"));
2734 else
2735 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap,
2736 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False,
2737 "Hue", strlen("Hue"));
2739 WMSetSliderImage(panel->hsbHueS, sliderPxmp);
2740 WMReleasePixmap(sliderPxmp);
2742 for (i=0; i<7; i++) {
2743 if (colors[i])
2744 free(colors[i]);
2746 if (colors)
2747 free(colors);
2750 /*************** Custom Palette Functions ****************/
2752 static void
2753 customRenderSpectrum(W_ColorPanel *panel)
2755 RImage *spectrum;
2756 int hue, sat, val;
2757 int x,y;
2758 unsigned long ofs;
2759 unsigned char *rp, *gp, *bp;
2760 RColor color;
2761 RHSVColor cur_hsv;
2763 spectrum = RCreateImage(SPECTRUM_WIDTH, SPECTRUM_HEIGHT, 0);
2765 for (y=0; y<360; y++) {
2766 val = 255;
2767 sat = 0;
2768 hue = y;
2769 for (x=0; x<511; x++) {
2770 ofs = (y * 511) + x;
2772 cur_hsv.hue = hue;
2773 cur_hsv.saturation = sat;
2774 cur_hsv.value = val;
2776 RHSVtoRGB (&cur_hsv, &color);
2778 rp = spectrum->data[0] + ofs;
2779 gp = spectrum->data[1] + ofs;
2780 bp = spectrum->data[2] + ofs;
2782 *rp = (unsigned char)color.red;
2783 *gp = (unsigned char)color.green;
2784 *bp = (unsigned char)color.blue;
2786 if (x<255)
2787 sat++;
2789 if (x>255)
2790 val--;
2793 if (panel->customPaletteImg) {
2794 RDestroyImage(panel->customPaletteImg);
2795 panel->customPaletteImg = NULL;
2797 panel->customPaletteImg = spectrum;
2802 static void
2803 customSetPalette(W_ColorPanel *panel)
2805 W_Screen *scr = WMWidgetScreen(panel->win);
2806 RImage *scaledImg;
2807 Pixmap image;
2808 int item;
2810 image = XCreatePixmap(scr->display, W_DRAWABLE(scr), customPaletteWidth,
2811 customPaletteHeight, scr->depth);
2813 scaledImg = RScaleImage(panel->customPaletteImg, customPaletteWidth,
2814 customPaletteHeight);
2815 RConvertImage(scr->rcontext, scaledImg, &image);
2816 RDestroyImage(scaledImg);
2818 XCopyArea(scr->display, image, panel->customPaletteContentView->window,
2819 scr->copyGC, 0, 0, customPaletteWidth, customPaletteHeight, 0, 0);
2821 /* Check backimage exists. If it doesn't, allocate and fill it */
2822 if (!panel->selectionBackImg) {
2823 panel->selectionBackImg = XCreatePixmap(scr->display,
2824 panel->customPaletteContentView->window, 4, 4, scr->depth);
2827 XCopyArea(scr->display, image, panel->selectionBackImg, scr->copyGC,
2828 panel->palx-2, panel->paly-2, 4, 4, 0, 0);
2829 XCopyArea(scr->display, panel->selectionImg,
2830 panel->customPaletteContentView->window, scr->copyGC, 0 , 0, 4, 4,
2831 panel->palx-2, panel->paly-2);
2832 XFreePixmap(scr->display, image);
2834 panel->palXRatio = (float)(panel->customPaletteImg->width) /
2835 (float)(customPaletteWidth);
2836 panel->palYRatio = (float)(panel->customPaletteImg->height) /
2837 (float)(customPaletteHeight);
2839 item = WMGetPopUpButtonSelectedItem (panel->customPaletteHistoryBtn);
2841 /* if palette != "Spectrum", we are allowed to rename and remove it */
2842 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename,
2843 (item > 0) );
2844 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove,
2845 (item > 0) );
2849 static void
2850 customPalettePositionSelection(W_ColorPanel *panel, int x, int y)
2852 W_Screen *scr = WMWidgetScreen(panel->win);
2853 unsigned long ofs;
2856 /* undraw selection */
2857 XCopyArea(scr->display, panel->selectionBackImg,
2858 panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4,
2859 panel->palx-2, panel->paly-2);
2861 panel->palx = x;
2862 panel->paly = y;
2864 ofs = rint(x * panel->palXRatio) + rint(y * panel->palYRatio) *
2865 panel->customPaletteImg->width;
2867 panel->color.red = panel->customPaletteImg->data[0][ofs];
2868 panel->color.green = panel->customPaletteImg->data[1][ofs];
2869 panel->color.blue = panel->customPaletteImg->data[2][ofs];
2871 updateSwatch(panel, panel->color);
2872 panel->lastChanged = WMCustomPaletteModeColorPanel;
2874 /* Redraw color selector (and make a backup of the part it will cover) */
2875 XCopyArea(scr->display, panel->customPaletteContentView->window,
2876 panel->selectionBackImg, scr->copyGC, panel->palx-2, panel->paly-2,
2877 4, 4, 0, 0); /* "-2" is correction for hotspot location */
2878 XCopyArea(scr->display, panel->selectionImg,
2879 panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4,
2880 panel->palx-2, panel->paly-2); /* see above */
2884 static void
2885 customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2887 if (x < 2)
2888 x = 2;
2889 if (y < 2)
2890 y = 2;
2891 if (x >= customPaletteWidth)
2892 x = customPaletteWidth -2;
2893 if (y >= customPaletteHeight)
2894 y = customPaletteHeight -2;
2896 customPalettePositionSelection(panel, x, y);
2900 static void
2901 customPaletteHandleEvents(XEvent *event, void *data)
2903 W_ColorPanel *panel = (W_ColorPanel*)data;
2905 switch (event->type) {
2906 case Expose:
2907 if (event->xexpose.count != 0)
2908 break;
2909 customSetPalette(panel);
2910 break;
2914 static void
2915 customPaletteHandleActionEvents(XEvent *event, void *data)
2917 W_ColorPanel *panel = (W_ColorPanel*)data;
2918 int x, y;
2920 switch (event->type) {
2921 case ButtonPress:
2922 x = event->xbutton.x;
2923 y = event->xbutton.y;
2925 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2926 panel->flags.dragging = 1;
2927 customPalettePositionSelection(panel, x, y);
2929 break;
2931 case ButtonRelease:
2932 panel->flags.dragging = 0;
2933 if (!panel->flags.continuous) {
2934 if (panel->action)
2935 (*panel->action)(panel->action, panel->clientData);
2937 break;
2939 case MotionNotify:
2940 x = event->xmotion.x;
2941 y = event->xmotion.y;
2943 if (panel->flags.dragging) {
2944 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2945 customPalettePositionSelection(panel, x, y);
2947 else
2948 customPalettePositionSelectionOutBounds(panel, x, y);
2950 break;
2955 static void
2956 customPaletteMenuCallback(WMWidget *w, void *data)
2958 W_ColorPanel *panel = (W_ColorPanel*)data;
2959 int item = WMGetPopUpButtonSelectedItem(panel->customPaletteMenuBtn);
2961 switch (item) {
2962 case CPmenuNewFromFile:
2963 customPaletteMenuNewFromFile(panel);
2964 break;
2965 case CPmenuRename:
2966 customPaletteMenuRename(panel);
2967 break;
2968 case CPmenuRemove:
2969 customPaletteMenuRemove(panel);
2970 break;
2971 case CPmenuCopy:
2972 break;
2973 case CPmenuNewFromClipboard:
2974 break;
2979 static void
2980 customPaletteMenuNewFromFile(W_ColorPanel *panel)
2982 W_Screen *scr = WMWidgetScreen(panel->win);
2983 WMOpenPanel *browseP;
2984 char *filepath;
2985 char *filename = NULL;
2986 char *spath;
2987 char *tmp;
2988 int i;
2989 RImage *tmpImg = NULL;
2991 if ((!panel->lastBrowseDir) || (strcmp(panel->lastBrowseDir,"\0") == 0))
2992 spath = wexpandpath(wgethomedir());
2993 else
2994 spath = wexpandpath(panel->lastBrowseDir);
2996 browseP = WMGetOpenPanel(scr);
2997 WMSetFilePanelCanChooseDirectories(browseP, 0);
2998 WMSetFilePanelCanChooseFiles(browseP, 1);
3000 /* Get a filename */
3001 if (WMRunModalFilePanelForDirectory(browseP, panel->win, spath,
3002 "Open Palette",
3003 RSupportedFileFormats()) ) {
3004 filepath = WMGetFilePanelFileName(browseP);
3006 /* Get seperation position between path and filename */
3007 i = strrchr(filepath, '/') - filepath + 1;
3008 if (i > strlen(filepath))
3009 i = strlen(filepath);
3011 /* Store last browsed path */
3012 if (panel->lastBrowseDir)
3013 free(panel->lastBrowseDir);
3014 panel->lastBrowseDir = wmalloc((i+1)*sizeof(char));
3015 strncpy(panel->lastBrowseDir, filepath, i);
3016 panel->lastBrowseDir[i] = '\0';
3018 /* Get filename from path */
3019 filename = wstrdup(filepath + i);
3021 /* Check for duplicate files, and rename it if there are any */
3022 tmp = wstrappend(panel->configurationPath, filename);
3023 while (access (tmp, F_OK) == 0) {
3024 char *newName;
3026 free(tmp);
3028 newName = generateNewFilename(filename);
3029 free(filename);
3030 filename = newName;
3032 tmp = wstrappend(panel->configurationPath, filename);
3034 free(tmp);
3036 /* Copy image to $(gnustepdir)/Library/Colors/ &
3037 * Add filename to history menu */
3038 if (fetchFile (panel->configurationPath, filepath, filename) == 0) {
3040 /* filepath is a "local" path now the file has been copied */
3041 free(filepath);
3042 filepath = wstrappend(panel->configurationPath, filename);
3044 /* load the image & add menu entries */
3045 tmpImg = RLoadImage(scr->rcontext, filepath, 0);
3046 if (tmpImg) {
3047 if (panel->customPaletteImg)
3048 RDestroyImage(panel->customPaletteImg);
3049 panel->customPaletteImg = tmpImg;
3051 customSetPalette(panel);
3052 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, filename);
3054 panel->currentPalette = WMGetPopUpButtonNumberOfItems(
3055 panel->customPaletteHistoryBtn)-1;
3057 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
3058 panel->currentPalette);
3061 else
3063 tmp = wstrappend(panel->configurationPath, filename);
3065 i = remove(tmp); /* Delete the file, it doesn't belong here */
3066 WMRunAlertPanel(scr, panel->win, "File Error",
3067 "Invalid file format !", "OK", NULL, NULL);
3068 if (i != 0) {
3069 wsyserror("can't remove file %s", tmp);
3070 WMRunAlertPanel(scr, panel->win, "File Error",
3071 "Couldn't remove file from Configuration Directory !",
3072 "OK", NULL, NULL);
3074 free(tmp);
3076 free(filepath);
3077 free(filename);
3079 WMFreeFilePanel(browseP);
3081 free(spath);
3085 static void
3086 customPaletteMenuRename(W_ColorPanel *panel)
3088 W_Screen *scr = WMWidgetScreen(panel->win);
3089 char *toName = NULL;
3090 char *fromName;
3091 char *toPath, *fromPath;
3092 int item;
3093 int index;
3095 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
3096 fromName = WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item);
3098 toName = WMRunInputPanel(scr, panel->win, "Rename", "Rename palette to:",
3099 fromName, "OK", "Cancel");
3101 if (toName) {
3103 /* As some people do certain stupid things... */
3104 if (strcmp(toName, fromName) == 0) {
3105 free(toName);
3106 return;
3109 /* For normal people */
3110 fromPath = wstrappend(panel->configurationPath, fromName);
3111 toPath = wstrappend(panel->configurationPath, toName);
3113 if (access (toPath, F_OK) == 0) {
3114 /* Careful, this palette exists already */
3115 if (WMRunAlertPanel(scr, panel->win, "Warning",
3116 "Palette already exists !\n\nOverwrite ?", "No", "Yes",
3117 NULL) == 1) {
3118 /* "No" = 0, "Yes" = 1 */
3119 int items = WMGetPopUpButtonNumberOfItems(
3120 panel->customPaletteHistoryBtn);
3122 remove(toPath);
3124 /* Remove from History list too */
3125 index = 1;
3126 while ((index < items) && (strcmp(WMGetPopUpButtonItem(
3127 panel->customPaletteHistoryBtn, index),
3128 toName) != 0 ))
3129 index++;
3131 if (index < items) {
3132 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn,
3133 index);
3134 if (index < item)
3135 item--;
3138 } else {
3139 free(fromPath);
3140 free(toName);
3141 free(toPath);
3143 return;
3147 if ( rename(fromPath, toPath) != 0)
3148 wsyserror("Couldn't rename palette %s to %s\n", fromName, toName);
3149 else {
3150 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
3151 WMInsertPopUpButtonItem(panel->customPaletteHistoryBtn, item,
3152 toName);
3154 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item);
3156 free(fromPath);
3157 free(toPath);
3158 free(toName);
3163 static void
3164 customPaletteMenuRemove(W_ColorPanel *panel)
3166 W_Screen *scr = WMWidgetScreen(panel->win);
3167 char *text;
3168 char *tmp;
3169 int choice;
3170 int item;
3172 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
3174 tmp = wstrappend( "This will permanently remove the palette ",
3175 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
3176 text = wstrappend( tmp, ".\n\nAre you sure you want to remove this"
3177 " palette ?");
3178 free(tmp);
3180 choice = WMRunAlertPanel(scr, panel->win, NULL, text, "Yes", "No", NULL);
3181 /* returns 0 (= "Yes") or 1 (="No") */
3182 free(text);
3184 if (choice == 0) {
3186 tmp = wstrappend(panel->configurationPath,
3187 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
3189 if ( remove(tmp) != 0)
3190 wsyserror("Couldn't remove palette %s\n", tmp);
3191 free(tmp);
3193 /* item -1 always exists */
3194 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item-1);
3196 customPaletteHistoryCallback(panel->customPaletteHistoryBtn, panel);
3197 customSetPalette(panel);
3199 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
3204 static void
3205 customPaletteHistoryCallback(WMWidget *w, void *data)
3207 W_ColorPanel *panel = (W_ColorPanel*)data;
3208 W_Screen *scr = WMWidgetScreen(panel->win);
3209 int item;
3210 char *filename;
3211 RImage *tmp = NULL;
3213 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
3214 if (item == panel->currentPalette)
3215 return;
3217 if (item == 0)
3218 customRenderSpectrum(panel);
3219 else {
3220 /* Load file from configpath */
3221 filename = wstrappend( panel->configurationPath,
3222 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item) );
3224 /* XXX To do: Check existence of file and remove it from the history
3225 * if it doesn't exist */
3227 tmp = RLoadImage(scr->rcontext, filename, 0);
3228 if (tmp) {
3229 if (panel->customPaletteImg) {
3230 RDestroyImage(panel->customPaletteImg);
3231 panel->customPaletteImg = NULL;
3233 panel->customPaletteImg = tmp;
3235 free(filename);
3237 customSetPalette(panel);
3239 panel->currentPalette = item;
3243 /*************** Panel Initialisation Functions *****************/
3245 static void
3246 wheelInit(W_ColorPanel *panel)
3248 RHSVColor cur_hsv;
3249 int i;
3250 int v;
3252 RRGBtoHSV(&panel->color, &cur_hsv);
3254 WMSetSliderValue(panel->wheelBrightnessS, 255-cur_hsv.value);
3255 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
3257 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 + (
3258 cur_hsv.saturation/255.0) * cos( cur_hsv.hue*M_PI/180.0)));
3259 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 + (
3260 cur_hsv.saturation/255.0) * sin(-cur_hsv.hue*M_PI/180.0)));
3262 for (i = 0; i < 256; i++) {
3263 /* We divide by 128 in advance, and check whether that number divides
3264 * by 2 properly. If not, we add one to round the number correctly
3266 v = (i*cur_hsv.value) >> 7;
3267 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + (v & 1));
3271 static void
3272 grayInit(W_ColorPanel *panel)
3274 RHSVColor cur_hsv;
3275 int value;
3276 char tmp[4];
3278 RRGBtoHSV(&panel->color, &cur_hsv);
3280 value = rint(cur_hsv.value/2.55);
3281 WMSetSliderValue(panel->grayBrightnessS, value);
3283 sprintf(tmp, "%d", value);
3284 WMSetTextFieldText(panel->grayBrightnessT, tmp);
3287 static void
3288 rgbInit(W_ColorPanel *panel)
3290 char tmp[4];
3292 WMSetSliderValue(panel->rgbRedS,panel->color.red);
3293 WMSetSliderValue(panel->rgbGreenS,panel->color.green);
3294 WMSetSliderValue(panel->rgbBlueS,panel->color.blue);
3296 sprintf(tmp, "%d", panel->color.red);
3297 WMSetTextFieldText(panel->rgbRedT, tmp);
3298 sprintf(tmp, "%d", panel->color.green);
3299 WMSetTextFieldText(panel->rgbGreenT, tmp);
3300 sprintf(tmp, "%d", panel->color.blue);
3301 WMSetTextFieldText(panel->rgbBlueT, tmp);
3304 static void
3305 cmykInit(W_ColorPanel *panel)
3307 int value[3];
3308 char tmp[4];
3310 value[0] = rint((255-panel->color.red)/2.55);
3311 value[1] = rint((255-panel->color.green)/2.55);
3312 value[2] = rint((255-panel->color.blue)/2.55);
3314 WMSetSliderValue(panel->cmykCyanS, value[0]);
3315 WMSetSliderValue(panel->cmykMagentaS, value[1]);
3316 WMSetSliderValue(panel->cmykYellowS, value[2]);
3317 WMSetSliderValue(panel->cmykBlackS, 0);
3319 sprintf(tmp, "%d", value[0]);
3320 WMSetTextFieldText(panel->cmykCyanT, tmp);
3321 sprintf(tmp, "%d", value[1]);
3322 WMSetTextFieldText(panel->cmykMagentaT, tmp);
3323 sprintf(tmp, "%d", value[2]);
3324 WMSetTextFieldText(panel->cmykYellowT, tmp);
3325 WMSetTextFieldText(panel->cmykBlackT, "0");
3328 static void
3329 hsbInit(W_ColorPanel *panel)
3331 int value[3];
3332 char tmp[4];
3334 value[0] = panel->hsvcolor.hue;
3335 value[1] = rint(panel->hsvcolor.saturation/2.55);
3336 value[2] = rint(panel->hsvcolor.value/2.55);
3338 WMSetSliderValue(panel->hsbHueS,value[0]);
3339 WMSetSliderValue(panel->hsbSaturationS,value[1]);
3340 WMSetSliderValue(panel->hsbBrightnessS,value[2]);
3342 sprintf(tmp, "%d", value[0]);
3343 WMSetTextFieldText(panel->hsbHueT, tmp);
3344 sprintf(tmp, "%d", value[1]);
3345 WMSetTextFieldText(panel->hsbSaturationT, tmp);
3346 sprintf(tmp, "%d", value[2]);
3347 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
3349 hsbUpdateBrightnessGradient(panel);
3350 hsbUpdateSaturationGradient(panel);
3351 hsbUpdateHueGradient(panel);
3357 /************************* ColorList Panel Functions **********************/
3359 static void
3360 colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text,
3361 int state, WMRect *rect)
3363 int width, height, x, y;
3364 RColor color = *((RColor *)WMGetListItem(lPtr, index)->clientData);
3365 WMScreen *scr = WMWidgetScreen(lPtr);
3366 Display *dpy = WMScreenDisplay(scr);
3367 W_ColorPanel *panel = WMGetHangedData(lPtr);
3368 WMColor *white = WMWhiteColor(scr);
3369 WMColor *black = WMBlackColor(scr);
3370 WMColor *fillColor;
3372 width = rect->size.width;
3373 height = rect->size.height;
3374 x = rect->pos.x;
3375 y = rect->pos.y;
3377 if (state & WLDSSelected)
3378 WMPaintColorSwatch(white, d, x +15, y, width -15, height);
3379 else
3380 XClearArea(dpy, d, x +15, y, width -15, height, False);
3382 fillColor = WMCreateRGBColor(scr, color.red*256, color.green*256,
3383 color.blue*256, False);
3385 WMSetColorInGC(fillColor, WMColorGC(fillColor));
3386 WMPaintColorSwatch(fillColor, d, x, y, 15, 15);
3387 WMReleaseColor(fillColor);
3389 WMDrawString(scr, d, WMColorGC(black), panel->font12, x+18, y, text,
3390 strlen(text));
3392 WMReleaseColor(white);
3393 WMReleaseColor(black);
3397 static void
3398 colorListSelect(WMWidget *w, void *data)
3400 W_ColorPanel *panel = (W_ColorPanel *)data;
3401 RColor color = *((RColor *)WMGetListSelectedItem(w)->clientData);
3403 panel->lastChanged = WMColorListModeColorPanel;
3404 updateSwatch(panel, color);
3408 static void
3409 colorListColorMenuCallback(WMWidget *w, void *data)
3411 W_ColorPanel *panel = (W_ColorPanel *)data;
3412 int item = WMGetPopUpButtonSelectedItem(panel->colorListColorMenuBtn);
3414 switch (item) {
3415 case CLmenuAdd:
3416 break;
3417 case CLmenuRename:
3418 break;
3419 case CLmenuRemove:
3420 break;
3425 static void
3426 colorListListMenuCallback(WMWidget *w, void *data)
3428 W_ColorPanel *panel = (W_ColorPanel *)data;
3429 int item = WMGetPopUpButtonSelectedItem(panel->colorListListMenuBtn);
3431 switch (item) {
3432 case CLmenuAdd:
3433 /* New Color List */
3434 colorListListMenuNew(panel);
3435 break;
3436 case CLmenuRename:
3437 break;
3438 case CLmenuRemove:
3439 break;
3444 static void
3445 colorListListMenuNew(W_ColorPanel *panel)
3451 /************************** Common utility functions ************************/
3453 static int
3454 fetchFile(char *toPath, char *srcFile, char *destFile)
3456 int src, dest;
3457 int n;
3458 char *tmp;
3459 char buf[BUFSIZE];
3461 if ((src = open(srcFile, O_RDONLY)) == 0) {
3462 wsyserror("Could not open %s", srcFile);
3463 return -1;
3466 tmp = wstrappend(toPath, destFile);
3467 if ((dest = open( tmp, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))
3468 == 0) {
3469 wsyserror("Could not create %s", tmp);
3470 free(tmp);
3471 return -1;
3473 free(tmp);
3476 /* Copy the file */
3477 while ((n = read(src, buf, BUFSIZE)) > 0)
3479 if (write (dest, buf, n) != n) {
3480 wsyserror("Write error on file %s", destFile);
3481 return -1;
3485 return 0;
3489 char*
3490 generateNewFilename(char *curName)
3492 int n;
3493 char c;
3494 int baseLen;
3495 char *ptr;
3496 char *newName;
3499 assert(curName);
3501 ptr = curName;
3503 if (
3504 ((ptr = strrchr(ptr, '{')) == 0) ||
3505 sscanf(ptr, "{%i}%c", &n, &c) != 1
3507 return wstrappend(curName, " {1}");
3509 baseLen = ptr - curName -1;
3511 newName = wmalloc(baseLen + 16);
3512 strncpy(newName, curName, baseLen);
3513 newName[baseLen] = 0;
3515 sprintf(&newName[baseLen], " {%i}", n+1);
3517 return newName;