Packing motion notify to speed the running glass up.
[wmaker-crm.git] / WINGs / wcolorpanel.c
blob3ba23c2c19879fc1d51de1f9bf57be4e7e6e29c8
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 #include "WINGsP.h"
21 #include <math.h>
22 #include <unistd.h>
23 #include <ctype.h>
24 #include <fcntl.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <dirent.h>
28 #include <errno.h>
31 #ifndef PATH_MAX
32 # define PATH_MAX 1024
33 #endif
37 * Bitmaps for magnifying glass cursor
40 /* Cursor */
41 #define Cursor_x_hot 11
42 #define Cursor_y_hot 11
43 #define Cursor_width 32
44 #define Cursor_height 32
45 static unsigned char Cursor_bits[] = {
46 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
47 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
48 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
49 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
50 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
51 0x00,0x08,0x00,0x50,0x00,0x10,0x00,0x88,0x00,0x20,0x00,0x5c,0x01,0xc0,0x81,
52 0x3b,0x02,0x00,0x7e,0x70,0x05,0x00,0x00,0xe0,0x08,0x00,0x00,0xc0,0x15,0x00,
53 0x00,0x80,0x23,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x5c,
54 0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x70};
56 /* Cursor shape-mask */
57 #define Cursor_shape_width 32
58 #define Cursor_shape_height 32
59 static unsigned char Cursor_shape_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,0x70,0x00,0x10,0x00,0xf8,0x00,0x20,0x00,0xfc,0x01,0xc0,0x81,
66 0xfb,0x03,0x00,0x7e,0xf0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x1f,0x00,
67 0x00,0x80,0x3f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfc,
68 0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70};
70 /* Clip-mask for magnified pixels */
71 #define Cursor_mask_width 22
72 #define Cursor_mask_height 22
73 static unsigned char Cursor_mask_bits[] = {
74 0x00,0x3f,0x00,0xe0,0xff,0x01,0xf0,0xff,0x03,0xf8,0xff,0x07,0xfc,0xff,0x0f,
75 0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xff,0xff,0x3f,0xff,0xff,0x3f,
76 0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xfe,0xff,0x1f,
77 0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfc,0xff,0x0f,0xf8,0xff,0x07,0xf0,0xff,0x03,
78 0xe0,0xff,0x01,0x00,0x3f,0x00};
81 typedef struct MovingView {
82 WMView *view; /* The view this is all about */
83 Pixmap pixmap; /* What's under the view */
84 Pixmap mask; /* Pixmap mask for view-contents */
85 int valid; /* Are contents still valid ? */
86 RColor color; /* Color of a pixel in the image */
87 } MovingView;
89 typedef struct WheelMatrix {
90 unsigned int width, height; /* Size of the colorwheel */
91 unsigned char *data[3]; /* Wheel data (R,G,B) */
92 unsigned char values[256]; /* Precalculated values R,G & B = 0-255 */
93 } wheelMatrix;
95 typedef struct W_ColorPanel {
96 WMWindow *win;
97 WMFont *font8;
98 WMFont *font12;
100 void *clientData;
101 WMAction *action;
103 /* Common Stuff */
104 WMColorWell *colorWell;
105 WMButton *magnifyBtn;
106 WMButton *wheelBtn;
107 WMButton *slidersBtn;
108 WMButton *customPaletteBtn;
109 WMButton *colorListBtn;
111 /* Magnifying Glass */
112 MovingView *magnifyGlass;
114 /* ColorWheel Panel */
115 WMFrame *wheelFrm;
116 WMSlider *wheelBrightnessS;
117 WMView *wheelView;
119 /* Slider Panels */
120 WMFrame *slidersFrm;
121 WMFrame *seperatorFrm;
122 WMButton *grayBtn;
123 WMButton *rgbBtn;
124 WMButton *cmykBtn;
125 WMButton *hsbBtn;
126 /* Gray Scale Panel */
127 WMFrame *grayFrm;
128 WMLabel *grayMinL;
129 WMLabel *grayMaxL;
130 WMSlider *grayBrightnessS;
131 WMTextField *grayBrightnessT;
132 WMButton *grayPresetBtn[7];
134 /* RGB Panel */
135 WMFrame *rgbFrm;
136 WMLabel *rgbMinL;
137 WMLabel *rgbMaxL;
138 WMSlider *rgbRedS;
139 WMSlider *rgbGreenS;
140 WMSlider *rgbBlueS;
141 WMTextField *rgbRedT;
142 WMTextField *rgbGreenT;
143 WMTextField *rgbBlueT;
145 /* CMYK Panel */
146 WMFrame *cmykFrm;
147 WMLabel *cmykMinL;
148 WMLabel *cmykMaxL;
149 WMSlider *cmykCyanS;
150 WMSlider *cmykMagentaS;
151 WMSlider *cmykYellowS;
152 WMSlider *cmykBlackS;
153 WMTextField *cmykCyanT;
154 WMTextField *cmykMagentaT;
155 WMTextField *cmykYellowT;
156 WMTextField *cmykBlackT;
158 /* HSB Panel */
159 WMFrame *hsbFrm;
160 WMSlider *hsbHueS;
161 WMSlider *hsbSaturationS;
162 WMSlider *hsbBrightnessS;
163 WMTextField *hsbHueT;
164 WMTextField *hsbSaturationT;
165 WMTextField *hsbBrightnessT;
167 /* Custom Palette Panel*/
168 WMFrame *customPaletteFrm;
169 WMPopUpButton *customPaletteHistoryBtn;
170 WMFrame *customPaletteContentFrm;
171 WMPopUpButton *customPaletteMenuBtn;
172 WMView *customPaletteContentView;
174 /* Color List Panel */
175 WMFrame *colorListFrm;
176 WMPopUpButton *colorListHistoryBtn;
177 WMList *colorListContentLst;
178 WMPopUpButton *colorListColorMenuBtn;
179 WMPopUpButton *colorListListMenuBtn;
181 /* Look-Up Tables and Images */
182 wheelMatrix *wheelMtrx;
183 Pixmap wheelImg;
184 Pixmap selectionImg;
185 Pixmap selectionBackImg;
186 RImage *customPaletteImg;
187 char *lastBrowseDir;
189 /* Common Data Fields */
190 RColor color; /* Current color */
191 Bool colorSet; /* Is color already set ? */
192 RHSVColor hsvcolor; /* Backup HSV Color */
193 WMColorPanelMode mode; /* Current color selection mode */
194 WMColorPanelMode slidersmode;/* Current color sel. mode sliders panel */
195 WMColorPanelMode lastChanged;/* Panel that last changed the color */
196 int colx, coly; /* (x,y) of sel.-marker in WheelMode */
197 int palx, paly; /* (x,y) of sel.-marker in
198 CustomPaletteMode */
199 float palXRatio, palYRatio; /* Ratios in x & y between
200 original and scaled
201 palettesize */
202 int currentPalette;
203 char *configurationPath;
205 struct {
206 unsigned int continuous:1;
208 unsigned int dragging:1;
209 } flags;
210 } W_ColorPanel;
212 enum {
213 CPmenuNewFromFile,
214 CPmenuRename,
215 CPmenuRemove,
216 CPmenuCopy,
217 CPmenuNewFromClipboard
218 } customPaletteMenuItem;
220 enum {
221 CLmenuAdd,
222 CLmenuRename,
223 CLmenuRemove
224 } colorListMenuItem;
227 #define PWIDTH 194
228 #define PHEIGHT 266
229 #define colorWheelSize 150
230 #define customPaletteWidth 182
231 #define customPaletteHeight 106
232 #define knobThickness 8
234 #define SPECTRUM_WIDTH 511
235 #define SPECTRUM_HEIGHT 360
237 #define COLORWHEEL_PART 1
238 #define CUSTOMPALETTE_PART 2
239 #define BUFSIZE 1024
241 #undef EASTEREGG
243 #define RGBTXT "/usr/X11R6/lib/X11/rgb.txt"
244 #define MAX_LENGTH 1024
246 static int fetchFile(char* toPath, char *imageSrcFile,
247 char *imageDestFileName);
248 char *generateNewFilename(char *curName);
250 static void modeButtonCallback(WMWidget *w, void *data);
251 static int getPickerPart(W_ColorPanel *panel, int x, int y);
252 static void readConfiguration(W_ColorPanel *panel);
253 static void readXColors(W_ColorPanel *panel);
255 static void closeWindowCallback(WMWidget *w, void *data);
257 static Cursor magnifyGrabPointer(W_ColorPanel *panel);
258 static WMPoint magnifyInitialize(W_ColorPanel *panel);
259 static void magnifyPutCursor(WMWidget *w, void *data);
260 static Pixmap magnifyCreatePixmap(WMColorPanel *panel);
261 static Pixmap magnifyGetStorePixmap(W_ColorPanel *panel, int x1, int y1,
262 int x2, int y2);
263 static Pixmap magnifyGetImage(WMScreen *scr, int x, int y);
265 static wheelMatrix* wheelCreateMatrix(unsigned int width , unsigned int height);
266 static void wheelDestroyMatrix(wheelMatrix *matrix);
267 static wheelMatrix* wheelInitMatrix(W_ColorPanel *panel);
268 static void wheelRender(W_ColorPanel *panel);
269 static Bool wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs);
270 static void wheelPaint(W_ColorPanel *panel);
272 static void wheelHandleEvents(XEvent *event, void *data);
273 static void wheelHandleActionEvents(XEvent *event, void *data);
274 static void wheelBrightnessSliderCallback(WMWidget *w, void *data);
275 static void wheelUpdateSelection(W_ColorPanel *panel);
276 static void wheelUndrawSelection(W_ColorPanel *panel);
278 static void wheelPositionSelection(W_ColorPanel *panel, int x, int y);
279 static void wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y);
280 static void wheelUpdateBrightnessGradientFromHSV (W_ColorPanel *panel,
281 RHSVColor topColor);
282 static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel *panel);
283 static void wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor);
285 static void grayBrightnessSliderCallback(WMWidget *w, void *data);
286 static void grayPresetButtonCallback(WMWidget *w, void *data);
287 static void grayBrightnessTextFieldCallback(void *observerData,
288 WMNotification *notification);
290 static void rgbSliderCallback(WMWidget *w, void *data);
291 static void rgbTextFieldCallback(void *observerData,
292 WMNotification *notification);
294 static void cmykSliderCallback(WMWidget *w, void *data);
295 static void cmykTextFieldCallback(void *observerData,
296 WMNotification *notification);
298 static void hsbSliderCallback(WMWidget *w, void *data);
299 static void hsbTextFieldCallback(void *observerData,
300 WMNotification *notification);
301 static void hsbUpdateBrightnessGradient(W_ColorPanel *panel);
302 static void hsbUpdateSaturationGradient(W_ColorPanel *panel);
303 static void hsbUpdateHueGradient(W_ColorPanel *panel);
305 static void customRenderSpectrum(W_ColorPanel *panel);
306 static void customSetPalette(W_ColorPanel *panel);
307 static void customPaletteHandleEvents(XEvent *event, void *data);
308 static void customPaletteHandleActionEvents(XEvent *event, void *data);
309 static void customPalettePositionSelection(W_ColorPanel *panel, int x, int y);
310 static void customPalettePositionSelectionOutBounds(W_ColorPanel *panel,
311 int x, int y);
312 static void customPaletteMenuCallback(WMWidget *w, void *data);
313 static void customPaletteHistoryCallback(WMWidget *w, void *data);
315 static void customPaletteMenuNewFromFile(W_ColorPanel *panel);
316 static void customPaletteMenuRename(W_ColorPanel *panel);
317 static void customPaletteMenuRemove(W_ColorPanel *panel);
319 static void colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text,
320 int state, WMRect *rect);
321 static void colorListSelect(WMWidget *w, void *data);
322 static void colorListColorMenuCallback(WMWidget *w, void *data);
323 static void colorListListMenuCallback(WMWidget *w, void *data);
324 static void colorListListMenuNew(W_ColorPanel *panel);
326 static void wheelInit(W_ColorPanel *panel);
327 static void grayInit(W_ColorPanel *panel);
328 static void rgbInit(W_ColorPanel *panel);
329 static void cmykInit(W_ColorPanel *panel);
330 static void hsbInit(W_ColorPanel *panel);
334 void
335 WMSetColorPanelAction(WMColorPanel *panel, WMAction *action, void *data)
337 panel->action = action;
338 panel->clientData = data;
341 static WMColorPanel*
342 makeColorPanel(WMScreen *scrPtr, char *name)
344 WMColorPanel *panel;
345 RImage *image;
346 WMPixmap *pixmap;
347 RColor from;
348 RColor to;
349 WMColor *textcolor;
350 int i;
351 int x,y;
354 panel = wmalloc(sizeof(WMColorPanel));
355 memset(panel, 0, sizeof(WMColorPanel));
357 panel->colorSet = False; /* Color has not been set yet */
359 panel->font8 = WMSystemFontOfSize(scrPtr, 8);
360 panel->font12 = WMSystemFontOfSize(scrPtr, 12);
362 panel->win = WMCreateWindowWithStyle(scrPtr, name,
363 WMTitledWindowMask | WMClosableWindowMask | WMResizableWindowMask);
364 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
365 WMSetWindowTitle(panel->win, "Colors");
366 WMSetWindowCloseAction(panel->win, closeWindowCallback, panel);
369 /* Set Default ColorPanel Mode(s) */
370 panel->mode = WMWheelModeColorPanel;
371 panel->lastChanged = WMWheelModeColorPanel;
372 panel->slidersmode = WMRGBModeColorPanel;
373 panel->configurationPath = wstrappend(wusergnusteppath(),
374 "/Library/Colors/");
376 /* Some General Purpose Widgets */
377 panel->colorWell = WMCreateColorWell(panel->win);
378 WMResizeWidget(panel->colorWell, 134, 36);
379 WSetColorWellBordered(panel->colorWell, False);
380 WMMoveWidget(panel->colorWell, 56, 4);
382 panel->magnifyBtn = WMCreateCustomButton(panel->win,
383 WBBStateLightMask|WBBStateChangeMask);
384 WMResizeWidget(panel->magnifyBtn, 46, 36);
385 WMMoveWidget(panel->magnifyBtn, 6,4);
386 WMSetButtonAction(panel->magnifyBtn, magnifyPutCursor, panel);
387 WMSetButtonImagePosition(panel->magnifyBtn, WIPImageOnly);
388 WMSetButtonImage(panel->magnifyBtn, scrPtr->magnifyIcon);
390 panel->wheelBtn = WMCreateCustomButton(panel->win,
391 WBBStateLightMask|WBBStateChangeMask);
392 WMResizeWidget(panel->wheelBtn, 46, 32);
393 WMMoveWidget(panel->wheelBtn, 6, 44);
394 WMSetButtonAction(panel->wheelBtn, modeButtonCallback, panel);
395 WMSetButtonImagePosition(panel->wheelBtn, WIPImageOnly);
396 WMSetButtonImage(panel->wheelBtn, scrPtr->wheelIcon);
398 panel->slidersBtn = WMCreateCustomButton(panel->win,
399 WBBStateLightMask|WBBStateChangeMask);
400 WMResizeWidget(panel->slidersBtn, 46, 32);
401 WMMoveWidget(panel->slidersBtn, 52, 44);
402 WMSetButtonAction(panel->slidersBtn, modeButtonCallback, panel);
403 WMSetButtonImagePosition(panel->slidersBtn, WIPImageOnly);
404 WMSetButtonImage(panel->slidersBtn, scrPtr->rgbIcon);
406 panel->customPaletteBtn = WMCreateCustomButton(panel->win,
407 WBBStateLightMask|WBBStateChangeMask);
408 WMResizeWidget(panel->customPaletteBtn, 46, 32);
409 WMMoveWidget(panel->customPaletteBtn, 98, 44);
410 WMSetButtonAction(panel->customPaletteBtn, modeButtonCallback, panel);
411 WMSetButtonImagePosition(panel->customPaletteBtn, WIPImageOnly);
412 WMSetButtonImage(panel->customPaletteBtn, scrPtr->customPaletteIcon);
414 panel->colorListBtn = WMCreateCustomButton(panel->win,
415 WBBStateLightMask|WBBStateChangeMask);
416 WMResizeWidget(panel->colorListBtn, 46, 32);
417 WMMoveWidget(panel->colorListBtn, 144, 44);
418 WMSetButtonAction(panel->colorListBtn, modeButtonCallback, panel);
419 WMSetButtonImagePosition(panel->colorListBtn, WIPImageOnly);
420 WMSetButtonImage(panel->colorListBtn, scrPtr->colorListIcon);
422 /* Let's Group some of them together */
423 WMGroupButtons(panel->wheelBtn, panel->slidersBtn);
424 WMGroupButtons(panel->wheelBtn, panel->customPaletteBtn);
425 WMGroupButtons(panel->wheelBtn, panel->colorListBtn);
427 /* Widgets for the ColorWheel Panel */
428 panel->wheelFrm = WMCreateFrame(panel->win);
429 WMSetFrameRelief(panel->wheelFrm, WRFlat);
430 WMResizeWidget(panel->wheelFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
431 WMMoveWidget(panel->wheelFrm, 5, 80);
433 panel->wheelView = W_CreateView(W_VIEW(panel->wheelFrm));
434 /* XXX Can we create a view ? */
435 W_ResizeView(panel->wheelView, colorWheelSize+4, colorWheelSize+4);
436 W_MoveView(panel->wheelView, 0, 0);
438 /* Create an event handler to handle expose/click events in ColorWheel */
439 WMCreateEventHandler(panel->wheelView,
440 ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
441 LeaveWindowMask|ButtonMotionMask, wheelHandleActionEvents, panel);
443 WMCreateEventHandler(panel->wheelView, ExposureMask, wheelHandleEvents,
444 panel);
446 panel->wheelBrightnessS = WMCreateSlider(panel->wheelFrm);
447 WMResizeWidget(panel->wheelBrightnessS, 16, 153);
448 WMMoveWidget(panel->wheelBrightnessS, 5+colorWheelSize+14, 1);
449 WMSetSliderMinValue(panel->wheelBrightnessS, 0);
450 WMSetSliderMaxValue(panel->wheelBrightnessS, 255);
451 WMSetSliderAction(panel->wheelBrightnessS, wheelBrightnessSliderCallback,
452 panel);
453 WMSetSliderKnobThickness(panel->wheelBrightnessS, knobThickness);
456 /* Widgets for the Slider Panels */
457 panel->slidersFrm = WMCreateFrame(panel->win);
458 WMSetFrameRelief(panel->slidersFrm, WRFlat);
459 WMResizeWidget(panel->slidersFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
460 WMMoveWidget(panel->slidersFrm, 4, 80);
462 panel->seperatorFrm = WMCreateFrame(panel->slidersFrm);
463 WMSetFrameRelief(panel->seperatorFrm, WRPushed);
464 WMResizeWidget(panel->seperatorFrm, PWIDTH - 8, 2);
465 WMMoveWidget(panel->seperatorFrm, 0, 1);
467 panel->grayBtn = WMCreateCustomButton(panel->slidersFrm,
468 WBBStateLightMask|WBBStateChangeMask);
469 WMResizeWidget(panel->grayBtn, 46, 24);
470 WMMoveWidget(panel->grayBtn, 1, 8);
471 WMSetButtonAction(panel->grayBtn, modeButtonCallback, panel);
472 WMSetButtonImagePosition(panel->grayBtn, WIPImageOnly);
473 WMSetButtonImage(panel->grayBtn, scrPtr->grayIcon);
475 panel->rgbBtn = WMCreateCustomButton(panel->slidersFrm,
476 WBBStateLightMask|WBBStateChangeMask);
477 WMResizeWidget(panel->rgbBtn, 46, 24);
478 WMMoveWidget(panel->rgbBtn, 47, 8);
479 WMSetButtonAction(panel->rgbBtn, modeButtonCallback, panel);
480 WMSetButtonImagePosition(panel->rgbBtn, WIPImageOnly);
481 WMSetButtonImage(panel->rgbBtn, scrPtr->rgbIcon);
483 panel->cmykBtn = WMCreateCustomButton(panel->slidersFrm,
484 WBBStateLightMask|WBBStateChangeMask);
485 WMResizeWidget(panel->cmykBtn, 46, 24);
486 WMMoveWidget(panel->cmykBtn, 93, 8);
487 WMSetButtonAction(panel->cmykBtn, modeButtonCallback, panel);
488 WMSetButtonImagePosition(panel->cmykBtn, WIPImageOnly);
489 WMSetButtonImage(panel->cmykBtn, scrPtr->cmykIcon);
491 panel->hsbBtn = WMCreateCustomButton(panel->slidersFrm,
492 WBBStateLightMask|WBBStateChangeMask);
493 WMResizeWidget(panel->hsbBtn, 46, 24);
494 WMMoveWidget(panel->hsbBtn, 139, 8);
495 WMSetButtonAction(panel->hsbBtn, modeButtonCallback, panel);
496 WMSetButtonImagePosition(panel->hsbBtn, WIPImageOnly);
497 WMSetButtonImage(panel->hsbBtn, scrPtr->hsbIcon);
499 /* Let's Group the Slider Panel Buttons Together */
500 WMGroupButtons(panel->grayBtn, panel->rgbBtn);
501 WMGroupButtons(panel->grayBtn, panel->cmykBtn);
502 WMGroupButtons(panel->grayBtn, panel->hsbBtn);
504 textcolor = WMDarkGrayColor(scrPtr);
506 /* Widgets for GrayScale Panel */
507 panel->grayFrm = WMCreateFrame(panel->slidersFrm);
508 WMSetFrameRelief(panel->grayFrm, WRFlat);
509 WMResizeWidget(panel->grayFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
510 WMMoveWidget(panel->grayFrm, 0, 34);
512 panel->grayMinL = WMCreateLabel(panel->grayFrm);
513 WMResizeWidget(panel->grayMinL, 20, 10);
514 WMMoveWidget(panel->grayMinL, 2, 2);
515 WMSetLabelText(panel->grayMinL, "0");
516 WMSetLabelTextAlignment(panel->grayMinL, WALeft);
517 WMSetLabelTextColor(panel->grayMinL, textcolor);
518 WMSetLabelFont(panel->grayMinL, panel->font8);
520 panel->grayMaxL = WMCreateLabel(panel->grayFrm);
521 WMResizeWidget(panel->grayMaxL, 40, 10);
522 WMMoveWidget(panel->grayMaxL, 104, 2);
523 WMSetLabelText(panel->grayMaxL, "100");
524 WMSetLabelTextAlignment(panel->grayMaxL, WARight);
525 WMSetLabelTextColor(panel->grayMaxL, textcolor);
526 WMSetLabelFont(panel->grayMaxL, panel->font8);
528 panel->grayBrightnessS = WMCreateSlider(panel->grayFrm);
529 WMResizeWidget(panel->grayBrightnessS, 141, 16);
530 WMMoveWidget(panel->grayBrightnessS, 2, 14);
531 WMSetSliderMinValue(panel->grayBrightnessS, 0);
532 WMSetSliderMaxValue(panel->grayBrightnessS, 100);
533 WMSetSliderKnobThickness(panel->grayBrightnessS, knobThickness);
534 WMSetSliderAction(panel->grayBrightnessS, grayBrightnessSliderCallback,
535 panel);
537 from.red = 0;
538 from.green = 0;
539 from.blue = 0;
541 to.red = 255;
542 to.green = 255;
543 to.blue = 255;
545 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
546 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
547 RDestroyImage(image);
548 W_PaintText(W_VIEW(panel->grayBrightnessS), pixmap->pixmap,
549 panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->white),
550 False, "Brightness", strlen("Brightness"));
551 WMSetSliderImage(panel->grayBrightnessS, pixmap);
552 WMReleasePixmap(pixmap);
554 panel->grayBrightnessT = WMCreateTextField(panel->grayFrm);
555 WMResizeWidget(panel->grayBrightnessT, 40, 18);
556 WMMoveWidget(panel->grayBrightnessT, 146, 13);
557 WMSetTextFieldAlignment(panel->grayBrightnessT, WALeft);
558 WMAddNotificationObserver(grayBrightnessTextFieldCallback, panel,
559 WMTextDidEndEditingNotification, panel->grayBrightnessT);
561 image = RCreateImage(13,13,False);
562 for (i=0; i < 7; i++) {
563 for (x=0; x < 13; x++) {
564 for (y=0; y < 13; y++) {
565 image->data[0][y*13+x] = 255/6*i;
566 image->data[1][y*13+x] = 255/6*i;
567 image->data[2][y*13+x] = 255/6*i;
570 panel->grayPresetBtn[i] = WMCreateCommandButton(panel->grayFrm);
571 WMResizeWidget(panel->grayPresetBtn[i], 20, 24);
572 WMMoveWidget(panel->grayPresetBtn[i], 2+(i*20), 34);
573 WMSetButtonAction(panel->grayPresetBtn[i],
574 grayPresetButtonCallback, panel);
575 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
576 WMSetButtonImage(panel->grayPresetBtn[i], pixmap);
577 WMSetButtonImagePosition(panel->grayPresetBtn[i], WIPImageOnly);
578 WMReleasePixmap(pixmap);
580 RDestroyImage(image);
581 /* End of GrayScale Panel */
583 /* Widgets for RGB Panel */
584 panel->rgbFrm = WMCreateFrame(panel->slidersFrm);
585 WMSetFrameRelief(panel->rgbFrm, WRFlat);
586 WMResizeWidget(panel->rgbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
587 WMMoveWidget(panel->rgbFrm, 0, 34);
589 panel->rgbMinL = WMCreateLabel(panel->rgbFrm);
590 WMResizeWidget(panel->rgbMinL, 20, 10);
591 WMMoveWidget(panel->rgbMinL, 2, 2);
592 WMSetLabelText(panel->rgbMinL, "0");
593 WMSetLabelTextAlignment(panel->rgbMinL, WALeft);
594 WMSetLabelTextColor(panel->rgbMinL, textcolor);
595 WMSetLabelFont(panel->rgbMinL, panel->font8);
597 panel->rgbMaxL = WMCreateLabel(panel->rgbFrm);
598 WMResizeWidget(panel->rgbMaxL, 40, 10);
599 WMMoveWidget(panel->rgbMaxL, 104, 2);
600 WMSetLabelText(panel->rgbMaxL, "255");
601 WMSetLabelTextAlignment(panel->rgbMaxL, WARight);
602 WMSetLabelTextColor(panel->rgbMaxL, textcolor);
603 WMSetLabelFont(panel->rgbMaxL, panel->font8);
605 panel->rgbRedS = WMCreateSlider(panel->rgbFrm);
606 WMResizeWidget(panel->rgbRedS, 141, 16);
607 WMMoveWidget(panel->rgbRedS, 2, 14);
608 WMSetSliderMinValue(panel->rgbRedS, 0);
609 WMSetSliderMaxValue(panel->rgbRedS, 255);
610 WMSetSliderKnobThickness(panel->rgbRedS, knobThickness);
611 WMSetSliderAction(panel->rgbRedS, rgbSliderCallback, panel);
613 to.red = 255;
614 to.green = 0;
615 to.blue = 0;
617 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
618 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
619 W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12,
620 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Red",
621 strlen("Red"));
622 RDestroyImage(image);
623 WMSetSliderImage(panel->rgbRedS, pixmap);
624 WMReleasePixmap(pixmap);
626 panel->rgbRedT = WMCreateTextField(panel->rgbFrm);
627 WMResizeWidget(panel->rgbRedT, 40, 18);
628 WMMoveWidget(panel->rgbRedT, 146, 13);
629 WMSetTextFieldAlignment(panel->rgbRedT, WALeft);
630 WMAddNotificationObserver(rgbTextFieldCallback, panel,
631 WMTextDidEndEditingNotification, panel->rgbRedT);
634 panel->rgbGreenS = WMCreateSlider(panel->rgbFrm);
635 WMResizeWidget(panel->rgbGreenS, 141, 16);
636 WMMoveWidget(panel->rgbGreenS, 2, 36);
637 WMSetSliderMinValue(panel->rgbGreenS, 0);
638 WMSetSliderMaxValue(panel->rgbGreenS, 255);
639 WMSetSliderKnobThickness(panel->rgbGreenS, knobThickness);
640 WMSetSliderAction(panel->rgbGreenS, rgbSliderCallback, panel);
642 to.red = 0;
643 to.green = 255;
644 to.blue = 0;
646 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
647 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
648 W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12,
649 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Green",
650 strlen("Green"));
651 RDestroyImage(image);
652 WMSetSliderImage(panel->rgbGreenS, pixmap);
653 WMReleasePixmap(pixmap);
655 panel->rgbGreenT = WMCreateTextField(panel->rgbFrm);
656 WMResizeWidget(panel->rgbGreenT, 40, 18);
657 WMMoveWidget(panel->rgbGreenT, 146, 35);
658 WMSetTextFieldAlignment(panel->rgbGreenT, WALeft);
659 WMAddNotificationObserver(rgbTextFieldCallback, panel,
660 WMTextDidEndEditingNotification, panel->rgbGreenT);
663 panel->rgbBlueS = WMCreateSlider(panel->rgbFrm);
664 WMResizeWidget(panel->rgbBlueS, 141, 16);
665 WMMoveWidget(panel->rgbBlueS, 2, 58);
666 WMSetSliderMinValue(panel->rgbBlueS, 0);
667 WMSetSliderMaxValue(panel->rgbBlueS, 255);
668 WMSetSliderKnobThickness(panel->rgbBlueS, knobThickness);
669 WMSetSliderAction(panel->rgbBlueS, rgbSliderCallback, panel);
671 to.red = 0;
672 to.green = 0;
673 to.blue = 255;
675 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
676 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
677 W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12,
678 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Blue",
679 strlen("Blue"));
680 RDestroyImage(image);
681 WMSetSliderImage(panel->rgbBlueS, pixmap);
682 WMReleasePixmap(pixmap);
684 panel->rgbBlueT = WMCreateTextField(panel->rgbFrm);
685 WMResizeWidget(panel->rgbBlueT, 40, 18);
686 WMMoveWidget(panel->rgbBlueT, 146, 57);
687 WMSetTextFieldAlignment(panel->rgbBlueT, WALeft);
688 WMAddNotificationObserver(rgbTextFieldCallback, panel,
689 WMTextDidEndEditingNotification, panel->rgbBlueT);
690 /* End of RGB Panel */
692 /* Widgets for CMYK Panel */
693 panel->cmykFrm = WMCreateFrame(panel->slidersFrm);
694 WMSetFrameRelief(panel->cmykFrm, WRFlat);
695 WMResizeWidget(panel->cmykFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
696 WMMoveWidget(panel->cmykFrm, 0, 34);
698 panel->cmykMinL = WMCreateLabel(panel->cmykFrm);
699 WMResizeWidget(panel->cmykMinL, 20, 10);
700 WMMoveWidget(panel->cmykMinL, 2, 2);
701 WMSetLabelText(panel->cmykMinL, "0");
702 WMSetLabelTextAlignment(panel->cmykMinL, WALeft);
703 WMSetLabelTextColor(panel->cmykMinL, textcolor);
704 WMSetLabelFont(panel->cmykMinL, panel->font8);
706 panel->cmykMaxL = WMCreateLabel(panel->cmykFrm);
707 WMResizeWidget(panel->cmykMaxL, 40, 10);
708 WMMoveWidget(panel->cmykMaxL, 104, 2);
709 WMSetLabelText(panel->cmykMaxL, "100");
710 WMSetLabelTextAlignment(panel->cmykMaxL, WARight);
711 WMSetLabelTextColor(panel->cmykMaxL, textcolor);
712 WMSetLabelFont(panel->cmykMaxL, panel->font8);
714 panel->cmykCyanS = WMCreateSlider(panel->cmykFrm);
715 WMResizeWidget(panel->cmykCyanS, 141, 16);
716 WMMoveWidget(panel->cmykCyanS, 2, 14);
717 WMSetSliderMinValue(panel->cmykCyanS, 0);
718 WMSetSliderMaxValue(panel->cmykCyanS, 100);
719 WMSetSliderKnobThickness(panel->cmykCyanS, knobThickness);
720 WMSetSliderAction(panel->cmykCyanS, cmykSliderCallback, panel);
722 from.red = 255;
723 from.green = 255;
724 from.blue = 255;
726 to.red = 0;
727 to.green = 255;
728 to.blue = 255;
730 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
731 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
732 W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12,
733 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Cyan",
734 strlen("Cyan"));
735 RDestroyImage(image);
736 WMSetSliderImage(panel->cmykCyanS, pixmap);
737 WMReleasePixmap(pixmap);
739 panel->cmykCyanT = WMCreateTextField(panel->cmykFrm);
740 WMResizeWidget(panel->cmykCyanT, 40, 18);
741 WMMoveWidget(panel->cmykCyanT, 146, 13);
742 WMSetTextFieldAlignment(panel->cmykCyanT, WALeft);
743 WMAddNotificationObserver(cmykTextFieldCallback, panel,
744 WMTextDidEndEditingNotification, panel->cmykCyanT);
747 panel->cmykMagentaS = WMCreateSlider(panel->cmykFrm);
748 WMResizeWidget(panel->cmykMagentaS, 141, 16);
749 WMMoveWidget(panel->cmykMagentaS, 2, 36);
750 WMSetSliderMinValue(panel->cmykMagentaS, 0);
751 WMSetSliderMaxValue(panel->cmykMagentaS, 100);
752 WMSetSliderKnobThickness(panel->cmykMagentaS, knobThickness);
753 WMSetSliderAction(panel->cmykMagentaS, cmykSliderCallback, panel);
755 to.red = 255;
756 to.green = 0;
757 to.blue = 255;
759 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
760 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
761 W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12,
762 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Magenta",
763 strlen("Magenta"));
764 RDestroyImage(image);
765 WMSetSliderImage(panel->cmykMagentaS, pixmap);
766 WMReleasePixmap(pixmap);
768 panel->cmykMagentaT = WMCreateTextField(panel->cmykFrm);
769 WMResizeWidget(panel->cmykMagentaT, 40, 18);
770 WMMoveWidget(panel->cmykMagentaT, 146, 35);
771 WMSetTextFieldAlignment(panel->cmykMagentaT, WALeft);
772 WMAddNotificationObserver(cmykTextFieldCallback, panel,
773 WMTextDidEndEditingNotification, panel->cmykMagentaT);
776 panel->cmykYellowS = WMCreateSlider(panel->cmykFrm);
777 WMResizeWidget(panel->cmykYellowS, 141, 16);
778 WMMoveWidget(panel->cmykYellowS, 2, 58);
779 WMSetSliderMinValue(panel->cmykYellowS, 0);
780 WMSetSliderMaxValue(panel->cmykYellowS, 100);
781 WMSetSliderKnobThickness(panel->cmykYellowS, knobThickness);
782 WMSetSliderAction(panel->cmykYellowS, cmykSliderCallback, panel);
784 to.red = 255;
785 to.green = 255;
786 to.blue = 0;
788 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
789 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
790 W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12,
791 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Yellow",
792 strlen("Yellow"));
793 RDestroyImage(image);
794 WMSetSliderImage(panel->cmykYellowS, pixmap);
795 WMReleasePixmap(pixmap);
797 panel->cmykYellowT = WMCreateTextField(panel->cmykFrm);
798 WMResizeWidget(panel->cmykYellowT, 40, 18);
799 WMMoveWidget(panel->cmykYellowT, 146, 57);
800 WMSetTextFieldAlignment(panel->cmykYellowT, WALeft);
801 WMAddNotificationObserver(cmykTextFieldCallback, panel,
802 WMTextDidEndEditingNotification, panel->cmykYellowT);
805 panel->cmykBlackS = WMCreateSlider(panel->cmykFrm);
806 WMResizeWidget(panel->cmykBlackS, 141, 16);
807 WMMoveWidget(panel->cmykBlackS, 2, 80);
808 WMSetSliderMinValue(panel->cmykBlackS, 0);
809 WMSetSliderMaxValue(panel->cmykBlackS, 100);
810 WMSetSliderValue(panel->cmykBlackS, 0);
811 WMSetSliderKnobThickness(panel->cmykBlackS, knobThickness);
812 WMSetSliderAction(panel->cmykBlackS, cmykSliderCallback, panel);
814 to.red = 0;
815 to.green = 0;
816 to.blue = 0;
818 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
819 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
820 W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12,
821 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Black",
822 strlen("Black"));
823 RDestroyImage(image);
824 WMSetSliderImage(panel->cmykBlackS, pixmap);
825 WMReleasePixmap(pixmap);
827 panel->cmykBlackT = WMCreateTextField(panel->cmykFrm);
828 WMResizeWidget(panel->cmykBlackT, 40, 18);
829 WMMoveWidget(panel->cmykBlackT, 146, 79);
830 WMSetTextFieldAlignment(panel->cmykBlackT, WALeft);
831 WMAddNotificationObserver(cmykTextFieldCallback, panel,
832 WMTextDidEndEditingNotification, panel->cmykBlackT);
833 /* End of CMYK Panel */
835 /* Widgets for HSB Panel */
836 panel->hsbFrm = WMCreateFrame(panel->slidersFrm);
837 WMSetFrameRelief(panel->hsbFrm, WRFlat);
838 WMResizeWidget(panel->hsbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
839 WMMoveWidget(panel->hsbFrm, 0, 34);
841 panel->hsbHueS = WMCreateSlider(panel->hsbFrm);
842 WMResizeWidget(panel->hsbHueS, 141, 16);
843 WMMoveWidget(panel->hsbHueS, 2, 14);
844 WMSetSliderMinValue(panel->hsbHueS, 0);
845 WMSetSliderMaxValue(panel->hsbHueS, 359);
846 WMSetSliderKnobThickness(panel->hsbHueS, knobThickness);
847 WMSetSliderAction(panel->hsbHueS, hsbSliderCallback, panel);
849 panel->hsbHueT = WMCreateTextField(panel->hsbFrm);
850 WMResizeWidget(panel->hsbHueT, 40, 18);
851 WMMoveWidget(panel->hsbHueT, 146, 13);
852 WMSetTextFieldAlignment(panel->hsbHueT, WALeft);
853 WMAddNotificationObserver(hsbTextFieldCallback, panel,
854 WMTextDidEndEditingNotification, panel->hsbHueT);
857 panel->hsbSaturationS = WMCreateSlider(panel->hsbFrm);
858 WMResizeWidget(panel->hsbSaturationS, 141, 16);
859 WMMoveWidget(panel->hsbSaturationS, 2, 36);
860 WMSetSliderMinValue(panel->hsbSaturationS, 0);
861 WMSetSliderMaxValue(panel->hsbSaturationS, 100);
862 WMSetSliderKnobThickness(panel->hsbSaturationS, knobThickness);
863 WMSetSliderAction(panel->hsbSaturationS, hsbSliderCallback, panel);
865 panel->hsbSaturationT = WMCreateTextField(panel->hsbFrm);
866 WMResizeWidget(panel->hsbSaturationT, 40, 18);
867 WMMoveWidget(panel->hsbSaturationT, 146, 35);
868 WMSetTextFieldAlignment(panel->hsbSaturationT, WALeft);
869 WMAddNotificationObserver(hsbTextFieldCallback, panel,
870 WMTextDidEndEditingNotification, panel->hsbSaturationT);
873 panel->hsbBrightnessS = WMCreateSlider(panel->hsbFrm);
874 WMResizeWidget(panel->hsbBrightnessS, 141, 16);
875 WMMoveWidget(panel->hsbBrightnessS, 2, 58);
876 WMSetSliderMinValue(panel->hsbBrightnessS, 0);
877 WMSetSliderMaxValue(panel->hsbBrightnessS, 100);
878 WMSetSliderKnobThickness(panel->hsbBrightnessS, knobThickness);
879 WMSetSliderAction(panel->hsbBrightnessS, hsbSliderCallback, panel);
881 panel->hsbBrightnessT = WMCreateTextField(panel->hsbFrm);
882 WMResizeWidget(panel->hsbBrightnessT, 40, 18);
883 WMMoveWidget(panel->hsbBrightnessT, 146, 57);
884 WMSetTextFieldAlignment(panel->hsbBrightnessT, WALeft);
885 WMAddNotificationObserver(hsbTextFieldCallback, panel,
886 WMTextDidEndEditingNotification, panel->hsbBrightnessT);
887 /* End of HSB Panel */
890 WMReleaseColor(textcolor);
892 /* Widgets for the CustomPalette Panel */
893 panel->customPaletteFrm = WMCreateFrame(panel->win);
894 WMSetFrameRelief(panel->customPaletteFrm, WRFlat);
895 WMResizeWidget(panel->customPaletteFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
896 WMMoveWidget(panel->customPaletteFrm, 5, 80);
898 panel->customPaletteHistoryBtn = WMCreatePopUpButton(
899 panel->customPaletteFrm);
900 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, "Spectrum");
901 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
902 WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn)-1);
903 WMSetPopUpButtonAction(panel->customPaletteHistoryBtn,
904 customPaletteHistoryCallback, panel);
905 WMResizeWidget(panel->customPaletteHistoryBtn, PWIDTH - 8, 20);
906 WMMoveWidget(panel->customPaletteHistoryBtn, 0, 0);
908 panel->customPaletteContentFrm = WMCreateFrame(panel->customPaletteFrm);
909 WMSetFrameRelief(panel->customPaletteContentFrm, WRSunken);
910 WMResizeWidget(panel->customPaletteContentFrm, PWIDTH - 8, PHEIGHT - 156);
911 WMMoveWidget(panel->customPaletteContentFrm, 0, 23);
913 panel->customPaletteContentView = W_CreateView(
914 W_VIEW(panel->customPaletteContentFrm));
915 /* XXX Can we create a view ? */
916 W_ResizeView(panel->customPaletteContentView, customPaletteWidth,
917 customPaletteHeight);
918 W_MoveView(panel->customPaletteContentView, 2, 2);
920 /* Create event handler to handle expose/click events in CustomPalette */
921 WMCreateEventHandler(panel->customPaletteContentView,
922 ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
923 LeaveWindowMask|ButtonMotionMask, customPaletteHandleActionEvents,
924 panel);
926 WMCreateEventHandler(panel->customPaletteContentView, ExposureMask,
927 customPaletteHandleEvents, panel);
929 panel->customPaletteMenuBtn = WMCreatePopUpButton(panel->customPaletteFrm);
930 WMSetPopUpButtonPullsDown(panel->customPaletteMenuBtn, 1);
931 WMSetPopUpButtonText(panel->customPaletteMenuBtn, "Palette");
932 WMSetPopUpButtonAction(panel->customPaletteMenuBtn,
933 customPaletteMenuCallback, panel);
934 WMResizeWidget(panel->customPaletteMenuBtn, PWIDTH - 8, 20);
935 WMMoveWidget(panel->customPaletteMenuBtn, 0, PHEIGHT - 130);
937 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from File...");
938 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Rename...");
939 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Remove");
940 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Copy");
941 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from Clipboard");
943 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, 0);
944 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, 0);
945 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuCopy, 0);
946 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn,
947 CPmenuNewFromClipboard, 0);
949 customRenderSpectrum(panel);
950 panel->currentPalette = 0;
953 /* Widgets for the ColorList Panel */
954 panel->colorListFrm = WMCreateFrame(panel->win);
955 WMSetFrameRelief(panel->colorListFrm, WRFlat);
956 WMResizeWidget(panel->colorListFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
957 WMMoveWidget(panel->colorListFrm, 5, 80);
959 panel->colorListHistoryBtn = WMCreatePopUpButton(panel->colorListFrm);
960 WMAddPopUpButtonItem(panel->colorListHistoryBtn, "X11-Colors");
961 WMSetPopUpButtonSelectedItem(panel->colorListHistoryBtn,
962 WMGetPopUpButtonNumberOfItems(panel->colorListHistoryBtn)-1);
963 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
964 * colorListHistoryCallback, panel); */
965 WMResizeWidget(panel->colorListHistoryBtn, PWIDTH - 8, 20);
966 WMMoveWidget(panel->colorListHistoryBtn, 0, 0);
968 panel->colorListContentLst = WMCreateList(panel->colorListFrm);
969 WMSetListAction(panel->colorListContentLst, colorListSelect, panel);
970 WMSetListUserDrawProc(panel->colorListContentLst, colorListPaintItem);
971 WMResizeWidget(panel->colorListContentLst, PWIDTH - 8, PHEIGHT - 156);
972 WMMoveWidget(panel->colorListContentLst, 0, 23);
973 WMHangData(panel->colorListContentLst, panel);
975 panel->colorListColorMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
976 WMSetPopUpButtonPullsDown(panel->colorListColorMenuBtn, 1);
977 WMSetPopUpButtonText(panel->colorListColorMenuBtn, "Color");
978 WMSetPopUpButtonAction(panel->colorListColorMenuBtn,
979 colorListColorMenuCallback, panel);
980 WMResizeWidget(panel->colorListColorMenuBtn, (PWIDTH - 16)/2, 20);
981 WMMoveWidget(panel->colorListColorMenuBtn, 0, PHEIGHT - 130);
983 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Add...");
984 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Rename...");
985 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Remove");
987 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuAdd, 0);
988 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRename, 0);
989 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRemove, 0);
991 panel->colorListListMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
992 WMSetPopUpButtonPullsDown(panel->colorListListMenuBtn, 1);
993 WMSetPopUpButtonText(panel->colorListListMenuBtn, "List");
994 WMSetPopUpButtonAction(panel->colorListListMenuBtn,
995 colorListListMenuCallback, panel);
996 WMResizeWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2, 20);
997 WMMoveWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2 + 8,
998 PHEIGHT - 130);
1000 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "New...");
1001 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Rename...");
1002 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Remove");
1004 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRename, 0);
1005 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRemove, 0);
1007 WMRealizeWidget(panel->win);
1008 WMMapSubwidgets(panel->win);
1010 WMMapSubwidgets(panel->wheelFrm);
1011 WMMapSubwidgets(panel->slidersFrm);
1012 WMMapSubwidgets(panel->grayFrm);
1013 WMMapSubwidgets(panel->rgbFrm);
1014 WMMapSubwidgets(panel->cmykFrm);
1015 WMMapSubwidgets(panel->hsbFrm);
1016 WMMapSubwidgets(panel->customPaletteFrm);
1017 WMMapSubwidgets(panel->customPaletteContentFrm);
1018 WMMapSubwidgets(panel->colorListFrm);
1020 readConfiguration(panel);
1021 readXColors(panel);
1023 return panel;
1027 WMColorPanel*
1028 WMGetColorPanel(WMScreen *scrPtr)
1030 WMColorPanel *panel;
1032 if (scrPtr->sharedColorPanel)
1033 return scrPtr->sharedColorPanel;
1035 panel = makeColorPanel(scrPtr, "colorPanel");
1037 scrPtr->sharedColorPanel = panel;
1039 return panel;
1043 void
1044 WMFreeColorPanel(WMColorPanel *panel)
1046 W_Screen *scr = WMWidgetScreen(panel->win);
1048 if (panel == scr->sharedColorPanel) {
1049 scr->sharedColorPanel = NULL;
1052 WMRemoveNotificationObserver(panel);
1054 WMUnmapWidget(panel->win);
1055 WMDestroyWidget(panel->win);
1057 /* fonts */
1058 if (panel->font8)
1059 WMReleaseFont(panel->font8);
1060 if (panel->font12)
1061 WMReleaseFont(panel->font12);
1063 /* pixmaps */
1064 if (panel->wheelMtrx)
1065 wheelDestroyMatrix(panel->wheelMtrx);
1066 if (panel->wheelImg)
1067 XFreePixmap(scr->display, panel->wheelImg);
1068 if (panel->selectionImg)
1069 XFreePixmap(scr->display, panel->selectionImg);
1070 if (panel->selectionBackImg)
1071 XFreePixmap(scr->display, panel->selectionBackImg);
1072 if (panel->customPaletteImg)
1073 RDestroyImage(panel->customPaletteImg);
1075 /* structs */
1076 if (panel->lastBrowseDir)
1077 free(panel->lastBrowseDir);
1078 if (panel->configurationPath)
1079 free(panel->configurationPath);
1081 free(panel);
1085 void
1086 WMCloseColorPanel(WMColorPanel *panel)
1088 WMCloseWindow(panel->win);
1089 WMFreeColorPanel(panel);
1093 void
1094 WMShowColorPanel(WMColorPanel *panel)
1096 WMScreen *scr = WMWidgetScreen(panel->win);
1097 WMColor *white = WMWhiteColor(scr);
1099 if (!panel->colorSet )
1100 WMSetColorPanelColor(panel, white);
1101 WMReleaseColor(white);
1103 WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel);
1104 wheelInit(panel);
1106 WMMapWidget(panel->win);
1110 static void
1111 closeWindowCallback(WMWidget *w, void *data)
1113 W_ColorPanel *panel = (W_ColorPanel*)data;
1115 WMCloseColorPanel(panel);
1116 /* WMUnmapWidget(panel->win); */
1120 static void
1121 readConfiguration(W_ColorPanel *panel)
1123 /* XXX Doesn't take care of "invalid" files */
1125 DIR *dPtr;
1126 struct dirent *dp;
1127 struct stat stat_buf;
1130 if (stat(panel->configurationPath, &stat_buf)!=0) {
1131 if (mkdir(panel->configurationPath,
1132 S_IRWXU|S_IRGRP|S_IROTH|S_IXGRP|S_IXOTH)!=0) {
1133 wsyserror("ColorPanel could not create directory %s needed"
1134 " to store configurations", panel->configurationPath);
1135 WMSetPopUpButtonEnabled(panel->customPaletteMenuBtn, False);
1136 WMSetPopUpButtonEnabled(panel->colorListColorMenuBtn, False);
1137 WMSetPopUpButtonEnabled(panel->colorListListMenuBtn, False);
1138 WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win,
1139 "File Error", "Could not create ColorPanel configuration"
1140 " directory", "OK", NULL, NULL);
1142 return;
1145 dPtr = opendir(panel->configurationPath);
1146 while ((dp = readdir(dPtr)) != NULL) {
1147 if (dp->d_name[0] != '.')
1148 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, dp->d_name);
1150 (void)closedir(dPtr);
1154 static void
1155 readXColors(W_ColorPanel *panel)
1157 struct stat stat_buf;
1158 FILE *rgbtxt;
1159 char line[MAX_LENGTH];
1160 int red, green, blue;
1161 char name[48];
1162 RColor *color;
1163 WMListItem *item;
1165 if (stat(RGBTXT, &stat_buf) != 0) {
1166 wwarning("Cannot find file %s", RGBTXT);
1167 return;
1169 else {
1170 rgbtxt = fopen(RGBTXT, "r");
1171 if (rgbtxt) {
1172 while (fgets(line, MAX_LENGTH, rgbtxt)) {
1173 if (sscanf(line, "%d%d%d %[^\n]", &red, &green, &blue, name)) {
1174 color = wmalloc(sizeof(RColor));
1175 color->red = (unsigned char)red;
1176 color->green = (unsigned char)green;
1177 color->blue = (unsigned char)blue;
1178 item = WMAddListItem(panel->colorListContentLst, name);
1179 item->clientData = (void *)color;
1182 fclose(rgbtxt);
1184 else {
1185 wsyserror("Unable to open file %s for reading", RGBTXT);
1191 void
1192 WMSetColorPanelPickerMode(WMColorPanel *panel, WMColorPanelMode mode)
1194 W_Screen *scr = WMWidgetScreen(panel->win);
1196 if (mode != WMWheelModeColorPanel) {
1197 WMUnmapWidget(panel->wheelFrm);
1198 if (panel->selectionBackImg) {
1199 XFreePixmap(WMWidgetScreen(panel->win)->display,
1200 panel->selectionBackImg);
1201 panel->selectionBackImg = None;
1204 if (mode != WMGrayModeColorPanel)
1205 WMUnmapWidget(panel->grayFrm);
1206 if (mode != WMRGBModeColorPanel)
1207 WMUnmapWidget(panel->rgbFrm);
1208 if (mode != WMCMYKModeColorPanel)
1209 WMUnmapWidget(panel->cmykFrm);
1210 if (mode != WMHSBModeColorPanel)
1211 WMUnmapWidget(panel->hsbFrm);
1212 if (mode != WMCustomPaletteModeColorPanel) {
1213 WMUnmapWidget(panel->customPaletteFrm);
1214 if (panel->selectionBackImg) {
1215 XFreePixmap(WMWidgetScreen(panel->win)->display,
1216 panel->selectionBackImg);
1217 panel->selectionBackImg = None;
1220 if (mode != WMColorListModeColorPanel)
1221 WMUnmapWidget(panel->colorListFrm);
1222 if ((mode != WMGrayModeColorPanel) && (mode != WMRGBModeColorPanel) &&
1223 (mode != WMCMYKModeColorPanel) && (mode != WMHSBModeColorPanel))
1224 WMUnmapWidget(panel->slidersFrm);
1225 else
1226 panel->slidersmode = mode;
1228 if (mode == WMWheelModeColorPanel) {
1229 WMMapWidget(panel->wheelFrm);
1230 WMSetButtonSelected(panel->wheelBtn, True);
1231 if (panel->lastChanged != WMWheelModeColorPanel)
1232 wheelInit(panel);
1233 wheelRender(panel);
1234 wheelPaint(panel);
1235 } else if (mode == WMGrayModeColorPanel) {
1236 WMMapWidget(panel->slidersFrm);
1237 WMSetButtonSelected(panel->slidersBtn, True);
1238 WMMapWidget(panel->grayFrm);
1239 WMSetButtonSelected(panel->grayBtn, True);
1240 WMSetButtonImage(panel->slidersBtn, scr->grayIcon);
1241 if (panel->lastChanged != WMGrayModeColorPanel)
1242 grayInit(panel);
1243 } else if (mode == WMRGBModeColorPanel) {
1244 WMMapWidget(panel->slidersFrm);
1245 WMSetButtonSelected(panel->slidersBtn, True);
1246 WMMapWidget(panel->rgbFrm);
1247 WMSetButtonSelected(panel->rgbBtn, True);
1248 WMSetButtonImage(panel->slidersBtn, scr->rgbIcon);
1249 if (panel->lastChanged != WMRGBModeColorPanel)
1250 rgbInit(panel);
1251 } else if (mode == WMCMYKModeColorPanel) {
1252 WMMapWidget(panel->slidersFrm);
1253 WMSetButtonSelected(panel->slidersBtn, True);
1254 WMMapWidget(panel->cmykFrm);
1255 WMSetButtonSelected(panel->cmykBtn, True);
1256 WMSetButtonImage(panel->slidersBtn, scr->cmykIcon);
1257 if (panel->lastChanged != WMCMYKModeColorPanel)
1258 cmykInit(panel);
1259 } else if (mode == WMHSBModeColorPanel) {
1260 WMMapWidget(panel->slidersFrm);
1261 WMSetButtonSelected(panel->slidersBtn, True);
1262 WMMapWidget(panel->hsbFrm);
1263 WMSetButtonSelected(panel->hsbBtn, True);
1264 WMSetButtonImage(panel->slidersBtn, scr->hsbIcon);
1265 if (panel->lastChanged != WMHSBModeColorPanel)
1266 hsbInit(panel);
1267 } else if (mode == WMCustomPaletteModeColorPanel) {
1268 WMMapWidget(panel->customPaletteFrm);
1269 WMSetButtonSelected(panel->customPaletteBtn, True);
1270 customSetPalette(panel);
1271 } else if (mode == WMColorListModeColorPanel) {
1272 WMMapWidget(panel->colorListFrm);
1273 WMSetButtonSelected(panel->colorListBtn, True);
1277 panel->mode = mode;
1280 void
1281 WMSetColorPanelColor(WMColorPanel *panel, WMColor *color)
1283 WMScreen *scr = WMWidgetScreen(panel->win);
1284 RHSVColor hsvcolor;
1285 RColor intcolor;
1286 GC bgc = WMColorGC(scr->black);
1287 GC wgc = WMColorGC(scr->white);
1288 int originalHue;
1290 WMSetColorWellColor(panel->colorWell, color);
1292 intcolor.red = color->color.red >> 8;
1293 intcolor.green = color->color.green >> 8;
1294 intcolor.blue = color->color.blue >> 8;
1296 panel->color = intcolor;
1297 panel->colorSet = True;
1299 /* If color was set by HSB-Panel do not convert back to hsv */
1300 if (panel->lastChanged != WMHSBModeColorPanel) {
1302 /* if color is black, hue is undetermined, so it must be restored */
1303 if ((panel->color.red == 0) &&
1304 (panel->color.green == 0) &&
1305 (panel->color.blue == 0) &&
1306 (panel->hsvcolor.hue <= 359))
1308 originalHue = panel->hsvcolor.hue;
1309 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1310 panel->hsvcolor.hue = originalHue;
1311 } else {
1312 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1316 panel->wheelMtrx = wheelInitMatrix(panel); /* Needs to be done After Color is set */
1318 /* Maybe put this in a sub-function ... Initialising selected images */
1319 RRGBtoHSV(&intcolor, &hsvcolor);
1320 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 +
1321 (hsvcolor.saturation/255.0) * cos( hsvcolor.hue*M_PI/180.0)));
1322 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 +
1323 (hsvcolor.saturation/255.0) * sin(-hsvcolor.hue*M_PI/180.0)));
1324 wheelUpdateBrightnessGradientFromHSV(panel, hsvcolor);
1325 WMSetSliderValue(panel->wheelBrightnessS, 255 - hsvcolor.value);
1327 panel->selectionImg = XCreatePixmap(scr->display,
1328 W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
1329 XFillRectangle(scr->display, panel->selectionImg, bgc, 0, 0, 4, 4);
1330 XFillRectangle(scr->display, panel->selectionImg, wgc, 1, 1, 2, 2);
1331 /* End of initialisation section */
1333 panel->palx = customPaletteWidth/2;
1334 panel->paly = customPaletteHeight/2;
1336 WMSetColorPanelPickerMode(panel, panel->mode);
1340 static void
1341 updateSwatch(WMColorPanel *panel, RColor color)
1343 WMScreen *scr = WMWidgetScreen(panel->win);
1344 WMColor *wellcolor;
1345 int originalHue;
1347 wellcolor = WMCreateRGBColor(scr, color.red << 8, color.green << 8,
1348 color.blue << 8, True);
1350 WMSetColorWellColor(panel->colorWell, wellcolor);
1351 WMReleaseColor(wellcolor);
1353 panel->color = color;
1355 /* If color was set by HSB-Panel do not convert back to hsv */
1356 if (panel->lastChanged != WMHSBModeColorPanel) {
1358 /* if color is black, hue is undetermined, so it must be restored */
1359 if ((panel->color.red == 0) &&
1360 (panel->color.green == 0) &&
1361 (panel->color.blue == 0) &&
1362 (panel->hsvcolor.hue <= 359))
1364 originalHue = panel->hsvcolor.hue;
1365 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1366 panel->hsvcolor.hue = originalHue;
1367 } else {
1368 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1372 if (panel->action && (!panel->flags.dragging || panel->flags.continuous)) {
1373 (*panel->action)(panel, panel->clientData);
1377 static void
1378 modeButtonCallback(WMWidget *w, void *data)
1380 W_ColorPanel *panel = (W_ColorPanel*)(data);
1382 if (w == panel->wheelBtn)
1383 WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel);
1384 else if (w == panel->slidersBtn)
1385 WMSetColorPanelPickerMode(panel, panel->slidersmode);
1386 else if (w == panel->customPaletteBtn)
1387 WMSetColorPanelPickerMode(panel, WMCustomPaletteModeColorPanel);
1388 else if (w == panel->colorListBtn)
1389 WMSetColorPanelPickerMode(panel, WMColorListModeColorPanel);
1390 else if (w == panel->grayBtn)
1391 WMSetColorPanelPickerMode(panel, WMGrayModeColorPanel);
1392 else if (w == panel->rgbBtn)
1393 WMSetColorPanelPickerMode(panel, WMRGBModeColorPanel);
1394 else if (w == panel->cmykBtn)
1395 WMSetColorPanelPickerMode(panel, WMCMYKModeColorPanel);
1396 else if (w == panel->hsbBtn)
1397 WMSetColorPanelPickerMode(panel, WMHSBModeColorPanel);
1401 /****************** Magnifying Cursor Functions *******************/
1402 static Pixmap
1403 magnifyGetImage(WMScreen *scr, int x, int y)
1405 XImage *image;
1406 Pixmap pixmap;
1407 int x0, y0, w0, h0;
1408 int displayWidth = DisplayWidth(scr->display, scr->screen);
1409 int displayHeight = DisplayHeight(scr->display, scr->screen);
1410 const int half_mask_width = (Cursor_mask_width +1)/2;
1411 const int half_mask_height = (Cursor_mask_height +1)/2;
1413 /* Coordinate correction for back pixmap
1414 * if magnifying glass is at screen-borders */
1415 x0 = 0; y0 = 0; w0 = Cursor_mask_width; h0 = Cursor_mask_height;
1417 if (x < half_mask_width) {
1418 if (x < 0) x = 0;
1419 x0 = half_mask_width - x;
1420 w0 = Cursor_mask_width - x0;
1423 if (x > displayWidth - half_mask_width) {
1424 if (x > displayWidth) x = displayWidth;
1425 w0 = Cursor_mask_width - (half_mask_width - (displayWidth - x));
1428 if (y < half_mask_height) {
1429 if (y < 0) y = 0;
1430 y0 = half_mask_height - y;
1431 h0 = Cursor_mask_height - y0;
1434 if (y > displayHeight - half_mask_height) {
1435 if (y > displayHeight) y = displayHeight;
1436 h0 = Cursor_mask_height - (half_mask_height - (displayHeight - y));
1438 /* end of coordinate correction */
1440 image = XGetImage(scr->display, scr->rootWin, x + x0 - Cursor_x_hot,
1441 y + y0 - Cursor_y_hot, w0, h0, AllPlanes, ZPixmap);
1443 pixmap = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1444 Cursor_mask_height, scr->depth);
1445 XPutImage(scr->display, pixmap, scr->copyGC, image, 0, 0, x0, y0, w0, h0);
1446 XDestroyImage(image);
1448 return pixmap;
1452 static Pixmap
1453 magnifyGetStorePixmap(WMColorPanel *panel, int x1, int y1, int x2, int y2)
1456 * (x1, y1) = topleft corner of existing rectangle
1457 * (x2, y2) = topleft corner of new position
1460 W_Screen *scr = WMWidgetScreen(panel->win);
1461 Pixmap pixmap;
1462 int xa, ya, xb, yb, w, h;
1464 if (x1 < x2) {
1465 xa = x2 - x1;
1466 xb = 0;
1467 } else {
1468 xa = 0;
1469 xb = x1 - x2;
1472 if (y1 < y2) {
1473 ya = y2 - y1;
1474 yb = 0;
1475 } else {
1476 ya = 0;
1477 yb = y1 - y2;
1480 w = Cursor_mask_width - abs(x1-x2);
1481 h = Cursor_mask_height - abs(y1-y2);
1483 /* Get pixmap from screen */
1484 pixmap = magnifyGetImage(scr, x2, y2);
1486 /* Copy previously stored pixmap on covered part of above pixmap */
1487 if (panel->magnifyGlass->valid)
1489 XCopyArea(scr->display, panel->magnifyGlass->pixmap, pixmap,
1490 scr->copyGC, xa, ya, w, h, xb, yb);
1492 /* Free it, so we can reuse it */
1493 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1496 return pixmap;
1500 static Pixmap
1501 magnifyCreatePixmap(WMColorPanel *panel)
1503 W_Screen *scr = WMWidgetScreen(panel->win);
1504 int u, v;
1505 int i, j;
1506 int ofs;
1507 Pixmap magPix;
1508 Pixmap backPix;
1509 RImage *pixelImg;
1510 const int half_mask_width = Cursor_mask_width/2;
1511 const int half_mask_height = Cursor_mask_height/2;
1515 * Get image
1518 /* Rectangle that's going to be the background */
1519 backPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1520 Cursor_mask_height , scr->depth);
1521 XCopyArea(scr->display, panel->magnifyGlass->pixmap, backPix, scr->copyGC,
1522 0, 0, Cursor_mask_width, Cursor_mask_height, 0, 0);
1525 * Magnify image
1528 magPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width +2,
1529 Cursor_mask_height +2, scr->depth);
1531 for (u=0; u<5+1; u++) /* Copy an area of 5x5 pixels from the center */
1532 for (v=0; v<5+1; v++)
1533 for (i=u*5; i < (u+1)*5; i++) /* magnify it 5 times */
1534 for (j=v*5; j < (v+1)*5; j++)
1535 XCopyArea(scr->display, backPix, magPix, scr->copyGC,
1536 u +9, v +9, 1, 1, i, j);
1538 /* Get color under hotspot */
1539 ofs = half_mask_width + half_mask_height * Cursor_mask_width;
1540 pixelImg = RCreateImageFromDrawable(scr->rcontext, backPix, backPix);
1541 panel->magnifyGlass->color.red = pixelImg->data[0][ofs];
1542 panel->magnifyGlass->color.green = pixelImg->data[1][ofs];
1543 panel->magnifyGlass->color.blue = pixelImg->data[2][ofs];
1544 RDestroyImage(pixelImg);
1546 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1547 XSetClipMask(scr->display, scr->clipGC, panel->magnifyGlass->mask);
1548 XSetClipOrigin(scr->display, scr->clipGC, 0, 0);
1550 XCopyArea(scr->display, magPix, backPix, scr->clipGC, 2, 2,
1551 Cursor_mask_width, Cursor_mask_height, 0, 0);
1552 /* (2,2) puts center pixel on center of glass */
1554 XFreePixmap(scr->display, magPix);
1556 return backPix;
1560 static WMView*
1561 magnifyCreateView(W_ColorPanel *panel)
1563 W_Screen *scr = WMWidgetScreen(panel->win);
1564 WMView *magView;
1566 magView = W_CreateTopView(scr);
1567 magView->self = panel;
1569 W_ResizeView(magView, Cursor_mask_width, Cursor_mask_height);
1571 magView->attribFlags |= CWOverrideRedirect | CWSaveUnder;
1572 magView->attribs.event_mask = StructureNotifyMask;
1573 magView->attribs.override_redirect = True;
1574 magView->attribs.save_under = True;
1576 W_RealizeView(magView);
1578 return magView;
1582 static Cursor
1583 magnifyGrabPointer(W_ColorPanel *panel)
1585 W_Screen *scr = WMWidgetScreen(panel->win);
1586 Pixmap magPixmap, magPixmap2;
1587 Cursor magCursor;
1588 XColor fgColor = {0, 0,0,0, DoRed|DoGreen|DoBlue};
1589 XColor bgColor = {0, 0xbf00, 0xa000, 0x5000, DoRed|DoGreen|DoBlue};
1591 /* Cursor creation stuff */
1592 magPixmap = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1593 Cursor_bits, Cursor_width, Cursor_height, 1, 0, 1);
1594 magPixmap2 = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1595 Cursor_shape_bits, Cursor_width, Cursor_height, 1, 0, 1);
1597 magCursor = XCreatePixmapCursor(scr->display, magPixmap, magPixmap2,
1598 &fgColor, &bgColor, Cursor_x_hot, Cursor_y_hot);
1600 XFreePixmap(scr->display, magPixmap);
1601 XFreePixmap(scr->display, magPixmap2);
1603 XRecolorCursor(scr->display, magCursor, &fgColor, &bgColor);
1605 /* Set up Pointer */
1606 XGrabPointer (scr->display, panel->magnifyGlass->view->window, True,
1607 PointerMotionMask | ButtonPressMask,
1608 GrabModeAsync, GrabModeAsync,
1609 scr->rootWin, magCursor, CurrentTime);
1611 return magCursor;
1615 static WMPoint
1616 magnifyInitialize(W_ColorPanel *panel)
1618 W_Screen *scr = WMWidgetScreen(panel->win);
1619 int x, y, u, v;
1620 unsigned int mask;
1621 Pixmap pixmap;
1622 WMPoint point;
1624 XQueryPointer(scr->display, scr->rootWin, &scr->rootWin,
1625 &W_VIEW(panel->win)->window, &x, &y, &u, &v, &mask);
1628 /* Clipmask to make magnified view-contents circular */
1629 panel->magnifyGlass->mask = XCreatePixmapFromBitmapData(scr->display,
1630 W_DRAWABLE(scr), Cursor_mask_bits,
1631 Cursor_mask_width, Cursor_mask_height, 1, 0, 1);
1633 /* Draw initial magnified part */
1634 panel->magnifyGlass->valid = False;
1635 /* also free's magnifyGlass->pixmap */
1636 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(panel, x, y, x, y);
1637 panel->magnifyGlass->valid = True;
1639 pixmap = magnifyCreatePixmap(panel);
1641 XSetWindowBackgroundPixmap(scr->display, panel->magnifyGlass->view->window,
1642 pixmap);
1643 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1644 XFlush(scr->display);
1646 XFreePixmap(scr->display, pixmap);
1648 point.x = x;
1649 point.y = y;
1651 return point;
1655 static void
1656 magnifyPutCursor(WMWidget *w, void *data)
1658 W_ColorPanel *panel = (W_ColorPanel*)(data);
1659 W_Screen *scr = WMWidgetScreen(panel->win);
1660 Cursor magCursor;
1661 int x, y;
1662 Pixmap pixmap;
1663 XEvent event;
1664 WMPoint initialPosition;
1666 /* Destroy wheelBackImg, so it'll update properly */
1667 if (panel->selectionBackImg) {
1668 XFreePixmap(WMWidgetScreen(panel->win)->display,
1669 panel->selectionBackImg);
1670 panel->selectionBackImg = None;
1673 /* Create magnifying glass */
1674 panel->magnifyGlass = wmalloc(sizeof(MovingView));
1675 panel->magnifyGlass->view = magnifyCreateView(panel);
1677 initialPosition = magnifyInitialize(panel);
1678 x = initialPosition.x;
1679 y = initialPosition.y;
1681 W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot +1,
1682 y - Cursor_y_hot +1);
1683 W_MapView(panel->magnifyGlass->view);
1685 magCursor = magnifyGrabPointer(panel);
1687 while(panel->magnifyGlass->valid)
1689 WMNextEvent(scr->display, &event);
1690 while (XCheckTypedEvent(scr->display, MotionNotify, &event)) {
1693 switch (event.type)
1695 case ButtonPress:
1696 if (event.xbutton.button == Button1) {
1697 updateSwatch(panel, panel->magnifyGlass->color);
1698 switch (panel->mode) {
1699 case WMWheelModeColorPanel:
1700 wheelInit(panel);
1701 wheelRender(panel);
1702 wheelPaint(panel);
1703 break;
1704 case WMGrayModeColorPanel:
1705 grayInit(panel);
1706 break;
1707 case WMRGBModeColorPanel:
1708 rgbInit(panel);
1709 break;
1710 case WMCMYKModeColorPanel:
1711 cmykInit(panel);
1712 break;
1713 case WMHSBModeColorPanel:
1714 hsbInit(panel);
1715 break;
1716 default:
1717 break;
1719 panel->lastChanged = panel->mode;
1722 panel->magnifyGlass->valid = False;
1723 WMSetButtonSelected(panel->magnifyBtn, False);
1724 break;
1726 case MotionNotify:
1727 /* Get a "dirty rectangle" */
1728 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(
1729 panel, x+1, y+1,
1730 event.xmotion.x_root+1, event.xmotion.y_root+1);
1731 /* also free's magnifyGlass->pixmap */
1733 /* Update coordinates */
1734 x = event.xmotion.x_root;
1735 y = event.xmotion.y_root;
1737 /* Move view */
1738 W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot +1,
1739 y - Cursor_y_hot +1);
1741 /* Put new image (with magn.) in view */
1742 pixmap = magnifyCreatePixmap(panel);
1743 XSetWindowBackgroundPixmap(scr->display,
1744 panel->magnifyGlass->view->window, pixmap);
1745 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1747 XFreePixmap(scr->display, pixmap);
1748 break;
1750 case FocusOut: /* fall through */
1751 case FocusIn:
1753 * Color Panel window (panel->win) lost or received focus.
1754 * We need to update the pixmap in the magnifying glass.
1756 XUngrabPointer(scr->display, CurrentTime);
1757 W_UnmapView(panel->magnifyGlass->view);
1759 magnifyInitialize(panel);
1761 W_MapView(panel->magnifyGlass->view);
1762 XGrabPointer (scr->display,
1763 panel->magnifyGlass->view->window,
1764 True,
1765 PointerMotionMask | ButtonPressMask,
1766 GrabModeAsync,
1767 GrabModeAsync,
1768 scr->rootWin,
1769 magCursor,
1770 CurrentTime);
1771 break;
1773 default:
1774 WMHandleEvent(&event);
1775 break;
1776 } /* of switch */
1778 panel->magnifyGlass->valid = False;
1780 XUngrabPointer(scr->display, CurrentTime);
1781 XFreeCursor(scr->display, magCursor);
1782 W_DestroyView(panel->magnifyGlass->view);
1784 XFreePixmap(scr->display, panel->magnifyGlass->mask);
1785 panel->magnifyGlass->mask = None;
1787 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1788 panel->magnifyGlass->pixmap = None;
1790 free(panel->magnifyGlass);
1795 /****************** WheelMatrix Functions ************************/
1797 static wheelMatrix*
1798 wheelCreateMatrix(unsigned int width, unsigned int height)
1800 wheelMatrix *matrix = NULL;
1801 int i;
1803 assert((width > 0) && (height > 0));
1805 matrix = malloc(sizeof(wheelMatrix));
1806 if (!matrix) {
1807 RErrorCode = RERR_NOMEMORY;
1808 return NULL;
1811 memset(matrix, 0, sizeof(wheelMatrix));
1812 matrix->width = width;
1813 matrix->height = height;
1814 for (i = 0; i < 3; i++) {
1815 matrix->data[i] = malloc(width*height*sizeof(unsigned char));
1816 if (!matrix->data[i])
1817 goto error;
1820 return matrix;
1822 error:
1823 for (i = 0; i < 3; i++) {
1824 if (matrix->data[i])
1825 free(matrix->data[i]);
1827 if (matrix)
1828 free(matrix);
1829 RErrorCode = RERR_NOMEMORY;
1830 return NULL;
1834 static void
1835 wheelDestroyMatrix(wheelMatrix *matrix)
1837 int i;
1839 assert (matrix!=NULL);
1841 for (i = 0; i < 3; i++) {
1842 if (matrix->data[i])
1843 free(matrix->data[i]);
1845 free(matrix);
1849 static wheelMatrix*
1850 wheelInitMatrix(W_ColorPanel *panel)
1852 int i;
1853 int x,y;
1854 wheelMatrix *matrix;
1855 unsigned char *rp, *gp, *bp;
1856 RHSVColor cur_hsv;
1857 RColor cur_rgb;
1858 long ofs[4];
1859 float hue;
1860 int sat;
1861 float xcor, ycor;
1862 int dhue[4];
1864 matrix = wheelCreateMatrix(colorWheelSize+4, colorWheelSize+4);
1865 if (!matrix)
1866 return NULL;
1868 RRGBtoHSV(&panel->color, &cur_hsv);
1870 for (i = 0; i < 256; i++)
1871 matrix->values[i] = (unsigned char)(rint(i*cur_hsv.value/255));
1873 cur_hsv.value = 255;
1875 ofs[0] = -1;
1876 ofs[1] = -(colorWheelSize + 4);
1877 /* ofs[2] = 0; superfluous
1878 ofs[3] = 0;
1880 for (y = 0; y < (colorWheelSize+4)/2; y++) {
1881 for (x = y; x < (colorWheelSize+4-y); x++) {
1882 xcor = ((float)(2.0*x - 4.0) / colorWheelSize) - 1;
1883 ycor = ((float)(2.0*y - 4.0) / colorWheelSize) - 1;
1885 sat = rint(255.0 * sqrt((xcor*xcor) + (ycor*ycor)));
1889 /* offsets are counterclockwise (in triangles) */
1891 /* top quarter */
1892 if (y < (colorWheelSize+4)/2)
1893 ofs[0]++;
1895 /* left quarter */
1896 ofs[1] += colorWheelSize + 4;
1898 /* bottom quarter */
1899 ofs[2] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[0];
1901 /* right quarter */
1902 ofs[3] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[1];
1904 if (sat < 256) {
1905 cur_hsv.saturation = (unsigned char)sat;
1907 if (xcor != 0)
1908 hue = atan(ycor/xcor);
1909 else {
1910 if (ycor > 0)
1911 hue = M_PI * 0.5;
1912 else
1913 hue = M_PI * 1.5;
1916 if (xcor < 0)
1917 hue += M_PI;
1918 if ((xcor > 0) && (ycor < 0))
1919 hue += M_PI * 2.0;
1921 hue = -hue; /* Reverse direction of ColorWheel */
1923 if (hue < 0)
1924 hue += M_PI * 2.0;
1926 dhue[0] = (hue*360) / (M_PI * 2.0);
1928 for (i = 0; i < 4; i++) {
1930 if (i > 0)
1931 dhue[i] = (dhue[i-1] + 90) % 360;
1933 if ((i == 1) || (i == 3))
1934 dhue[i] = 360 - dhue[i];
1936 if (i == 2)
1937 dhue[i] = 360 - dhue[i] + 180;
1939 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1940 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1941 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1943 cur_hsv.hue = dhue[i];
1944 RHSVtoRGB(&cur_hsv, &cur_rgb);
1946 *rp = (unsigned char)(cur_rgb.red);
1947 *gp = (unsigned char)(cur_rgb.green);
1948 *bp = (unsigned char)(cur_rgb.blue);
1951 else {
1952 for (i = 0; i < 4; i++) {
1953 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1954 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1955 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1957 *rp = (unsigned char)(0);
1958 *gp = (unsigned char)(0);
1959 *bp = (unsigned char)(0);
1963 if (y < (colorWheelSize+4)/2)
1964 ofs[0] += 2*y+1;
1966 ofs[1] += 1 - (colorWheelSize + 4) * (colorWheelSize + 4 - 1 - 2*y);
1969 return matrix;
1972 /****************** ColorWheel Functions *******************/
1974 static void
1975 wheelRender(W_ColorPanel *panel)
1977 W_Screen *scr = WMWidgetScreen(panel->win);
1978 int x,y;
1979 RImage *image;
1980 unsigned char *rp, *gp, *bp;
1981 RColor gray;
1982 unsigned long ofs;
1984 image = RCreateImage(colorWheelSize+4, colorWheelSize+4, False);
1985 if (!image)
1986 return;
1988 gray.red = gray.green = gray.blue = 0xaa;
1990 for (x = 0; x < colorWheelSize+4; x++) {
1991 for (y = 0; y < colorWheelSize+4; y++) {
1993 ofs = (y * image->width) + x;
1994 rp = image->data[0] + ofs;
1995 gp = image->data[1] + ofs;
1996 bp = image->data[2] + ofs;
1998 if (wheelInsideColorWheel(panel, ofs)) {
1999 *rp = (unsigned int)(panel->wheelMtrx->values[
2000 panel->wheelMtrx->data[0][ofs] ]);
2001 *gp = (unsigned int)(panel->wheelMtrx->values[
2002 panel->wheelMtrx->data[1][ofs] ]);
2003 *bp = (unsigned int)(panel->wheelMtrx->values[
2004 panel->wheelMtrx->data[2][ofs] ]);
2006 else {
2007 *rp = (unsigned char)(gray.red);
2008 *gp = (unsigned char)(gray.green);
2009 *bp = (unsigned char)(gray.blue);
2014 if (panel->wheelImg)
2015 XFreePixmap(scr->display, panel->wheelImg);
2017 panel->wheelImg = XCreatePixmap(scr->display, W_DRAWABLE(scr),
2018 colorWheelSize+4, colorWheelSize+4, scr->depth);
2019 RConvertImage(scr->rcontext, image, &panel->wheelImg);
2021 /* Check if backimage exists. If it doesn't, allocate and fill it */
2022 if (!panel->selectionBackImg) {
2023 panel->selectionBackImg = XCreatePixmap(scr->display,
2024 W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
2025 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg,
2026 scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0);
2027 /* -2 is hot spot correction */
2030 RDestroyImage(image);
2033 static Bool
2034 wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs)
2036 return ((panel->wheelMtrx->data[0][ofs] != 0) &&
2037 (panel->wheelMtrx->data[1][ofs] != 0) &&
2038 (panel->wheelMtrx->data[2][ofs] != 0));
2041 static void
2042 wheelPaint (W_ColorPanel *panel)
2044 W_Screen *scr = WMWidgetScreen(panel->win);
2046 XCopyArea(scr->display, panel->wheelImg, panel->wheelView->window,
2047 scr->copyGC, 0, 0, colorWheelSize+4, colorWheelSize+4, 0, 0);
2049 /* Draw selection image */
2050 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window,
2051 scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
2054 static void
2055 wheelHandleEvents(XEvent *event, void *data)
2057 W_ColorPanel *panel = (W_ColorPanel*)data;
2059 switch (event->type) {
2060 case Expose:
2061 if (event->xexpose.count != 0)
2062 break;
2063 wheelPaint(panel);
2064 break;
2068 static void
2069 wheelHandleActionEvents(XEvent *event, void *data)
2071 W_ColorPanel *panel = (W_ColorPanel*)data;
2073 switch (event->type) {
2074 case ButtonPress:
2075 if (getPickerPart(panel, event->xbutton.x, event->xbutton.y) ==
2076 COLORWHEEL_PART) {
2077 panel->flags.dragging = 1;
2078 wheelPositionSelection(panel, event->xbutton.x,
2079 event->xbutton.y);
2081 break;
2083 case ButtonRelease:
2084 panel->flags.dragging = 0;
2085 if (!panel->flags.continuous) {
2086 if (panel->action)
2087 (*panel->action)(panel->action, panel->clientData);
2089 break;
2091 case MotionNotify:
2092 if (panel->flags.dragging) {
2093 if (getPickerPart(panel, event->xmotion.x, event->xmotion.y) ==
2094 COLORWHEEL_PART) {
2095 wheelPositionSelection(panel, event->xmotion.x,
2096 event->xmotion.y);
2098 else
2099 wheelPositionSelectionOutBounds(panel, event->xmotion.x,
2100 event->xmotion.y);
2102 break;
2107 static int
2108 getPickerPart(W_ColorPanel *panel, int x, int y)
2110 int lx, ly;
2111 unsigned long ofs;
2113 lx = x;
2114 ly = y;
2116 if (panel->mode == WMWheelModeColorPanel) {
2117 if ((lx >= 2) && (lx <= 2+colorWheelSize) && (ly >= 2) &&
2118 (ly <= 2+colorWheelSize)) {
2120 ofs = ly*panel->wheelMtrx->width+lx;
2122 if (wheelInsideColorWheel(panel, ofs))
2123 return COLORWHEEL_PART;
2127 if (panel->mode == WMCustomPaletteModeColorPanel) {
2128 if ((lx >= 2) && (lx < customPaletteWidth-2) && (ly >= 2) &&
2129 (ly < customPaletteHeight-2)) {
2130 return CUSTOMPALETTE_PART;
2134 return 0;
2138 static void
2139 wheelBrightnessSliderCallback(WMWidget *w, void *data)
2141 int i;
2142 unsigned int v;
2143 int value;
2144 unsigned long ofs;
2145 RColor cur_rgb;
2147 W_ColorPanel *panel = (W_ColorPanel*)data;
2149 value = 255-WMGetSliderValue(panel->wheelBrightnessS);
2151 for (i = 0; i < 256; i++) {
2152 /* We divide by 128 in advance, and check whether that number divides
2153 * by 2 properly. If not, we add one to round the number correctly
2155 v = (i*value) >> 7;
2156 #ifdef EASTEREGG
2157 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + v);
2158 #else
2159 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) +(v & 0x01));
2160 #endif
2163 ofs = (panel->coly * panel->wheelMtrx->width) + panel->colx;
2165 if (!wheelInsideColorWheel(panel, ofs)) {
2166 panel->hsvcolor.saturation = 255;
2167 panel->hsvcolor.value = value;
2168 RHSVtoRGB(&panel->hsvcolor, &cur_rgb);
2170 panel->color = cur_rgb;
2172 else {
2173 panel->color.red = panel->wheelMtrx->values[
2174 panel->wheelMtrx->data[0][ofs] ];
2175 panel->color.green = panel->wheelMtrx->values[
2176 panel->wheelMtrx->data[1][ofs] ];
2177 panel->color.blue = panel->wheelMtrx->values[
2178 panel->wheelMtrx->data[2][ofs] ];
2181 wheelRender(panel);
2182 wheelPaint(panel);
2183 wheelUpdateSelection(panel);
2187 static void
2188 wheelUpdateSelection(W_ColorPanel *panel)
2190 W_Screen *scr = WMWidgetScreen(panel->win);
2192 updateSwatch(panel, panel->color);
2193 panel->lastChanged = WMWheelModeColorPanel;
2195 /* Redraw color selector (and make a backup of the part it will cover) */
2196 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg,
2197 scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0);
2198 /* "-2" is correction for hotspot location */
2199 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window,
2200 scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
2201 /* see above */
2204 static void
2205 wheelUndrawSelection(W_ColorPanel *panel)
2207 W_Screen *scr = WMWidgetScreen(panel->win);
2209 XCopyArea(scr->display, panel->selectionBackImg, panel->wheelView->window,
2210 scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
2211 /* see above */
2214 static void
2215 wheelPositionSelection(W_ColorPanel *panel, int x, int y)
2217 unsigned long ofs = (y * panel->wheelMtrx->width)+ x;
2220 panel->color.red = panel->wheelMtrx->values[
2221 panel->wheelMtrx->data[0][ofs] ];
2222 panel->color.green = panel->wheelMtrx->values[
2223 panel->wheelMtrx->data[1][ofs] ];
2224 panel->color.blue = panel->wheelMtrx->values[
2225 panel->wheelMtrx->data[2][ofs] ];
2227 wheelUndrawSelection(panel);
2229 panel->colx = x;
2230 panel->coly = y;
2232 wheelUpdateSelection(panel);
2233 wheelUpdateBrightnessGradientFromLocation(panel);
2236 static void
2237 wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2239 RHSVColor cur_hsv;
2240 float hue;
2241 float xcor, ycor;
2243 xcor = ((x*2.0) / (colorWheelSize+4)) - 1.0;
2244 ycor = ((y*2.0) / (colorWheelSize+4)) - 1.0;
2246 cur_hsv.saturation = 255;
2247 cur_hsv.value = 255 - WMGetSliderValue(panel->wheelBrightnessS);
2249 if (xcor != 0)
2250 hue = atan(ycor/xcor);
2251 else {
2252 if (ycor > 0)
2253 hue = M_PI * 0.5;
2254 else
2255 hue = M_PI * 1.5;
2258 if (xcor < 0)
2259 hue += M_PI;
2260 if ((xcor > 0) && (ycor < 0))
2261 hue += M_PI * 2.0;
2263 hue = -hue;
2265 if (hue < 0)
2266 hue += M_PI * 2.0;
2268 cur_hsv.hue = (hue*180.0)/(M_PI);
2269 RHSVtoRGB(&cur_hsv, &panel->color);
2271 wheelUndrawSelection(panel);
2273 panel->colx = 2 + rint((colorWheelSize * (1.0 +
2274 cos( cur_hsv.hue*M_PI/180))) /2.0);
2275 /* "+2" because of "colorWheelSize + 4" */
2276 panel->coly = 2 + rint((colorWheelSize * (1.0 +
2277 sin(-cur_hsv.hue*M_PI/180))) /2.0);
2279 wheelUpdateSelection(panel);
2280 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
2283 static void
2284 wheelUpdateBrightnessGradientFromHSV(W_ColorPanel *panel, RHSVColor topColor)
2286 RColor from;
2288 /* Update Brightness-Slider */
2289 topColor.value = 255;
2290 RHSVtoRGB(&topColor, &from);
2292 wheelUpdateBrightnessGradient(panel, from);
2295 static void
2296 wheelUpdateBrightnessGradientFromLocation(W_ColorPanel *panel)
2298 RColor from;
2299 unsigned long ofs;
2301 ofs = panel->coly * panel->wheelMtrx->width + panel->colx;
2303 from.red = panel->wheelMtrx->data[0][ofs];
2304 from.green = panel->wheelMtrx->data[1][ofs];
2305 from.blue = panel->wheelMtrx->data[2][ofs];
2307 wheelUpdateBrightnessGradient(panel, from);
2310 static void
2311 wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor)
2313 RColor to;
2314 RImage *sliderImg;
2315 WMPixmap *sliderPxmp;
2317 to.red = to.green = to.blue = 0;
2319 sliderImg = RRenderGradient(16, 153, &topColor, &to, RGRD_VERTICAL);
2320 sliderPxmp = WMCreatePixmapFromRImage(WMWidgetScreen(panel->win),
2321 sliderImg, 0);
2322 RDestroyImage(sliderImg);
2323 WMSetSliderImage(panel->wheelBrightnessS, sliderPxmp);
2324 WMReleasePixmap(sliderPxmp);
2327 /****************** Grayscale Panel Functions ***************/
2329 static void
2330 grayBrightnessSliderCallback(WMWidget *w, void *data)
2332 RColor color;
2333 int value;
2334 char tmp[4];
2336 W_ColorPanel *panel = (W_ColorPanel*)data;
2338 value = WMGetSliderValue(panel->grayBrightnessS);
2340 sprintf(tmp, "%d", value);
2342 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2343 color.red = color.green = color.blue = rint(2.55*value);
2345 updateSwatch(panel, color);
2346 panel->lastChanged = WMGrayModeColorPanel;
2349 static void
2350 grayPresetButtonCallback(WMWidget *w, void *data)
2352 RColor color;
2353 char tmp[4];
2354 int value;
2355 int i=0;
2357 W_ColorPanel *panel = (W_ColorPanel*)data;
2359 while (i < 7) {
2360 if (w == panel->grayPresetBtn[i])
2361 break;
2362 i++;
2365 value = rint(100.0/6.0*i);
2366 sprintf(tmp, "%d", value);
2368 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2369 color.red = color.green = color.blue = rint(255.0*i/6.0);
2371 WMSetSliderValue(panel->grayBrightnessS, rint(100.0*i/6.0));
2373 updateSwatch(panel, color);
2374 panel->lastChanged = WMGrayModeColorPanel;
2377 static void
2378 grayBrightnessTextFieldCallback(void *observerData,
2379 WMNotification *notification)
2381 RColor color;
2382 char tmp[4];
2383 int value;
2384 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2386 value = atoi(WMGetTextFieldText(panel->grayBrightnessT));
2387 if (value > 100)
2388 value = 100;
2389 if (value < 0)
2390 value = 0;
2392 sprintf(tmp, "%d", value);
2393 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2394 WMSetSliderValue(panel->grayBrightnessS, value);
2396 color.red = color.green = color.blue = rint(255.0*value/100.0);
2397 updateSwatch(panel, color);
2398 panel->lastChanged = WMGrayModeColorPanel;
2401 /******************* RGB Panel Functions *****************/
2403 static void
2404 rgbSliderCallback(WMWidget *w, void *data)
2406 RColor color;
2407 int value[3];
2408 char tmp[4];
2410 W_ColorPanel *panel = (W_ColorPanel*)data;
2412 value[0] = WMGetSliderValue(panel->rgbRedS);
2413 value[1] = WMGetSliderValue(panel->rgbGreenS);
2414 value[2] = WMGetSliderValue(panel->rgbBlueS);
2416 sprintf(tmp, "%d", value[0]);
2417 WMSetTextFieldText(panel->rgbRedT, tmp);
2418 sprintf(tmp, "%d", value[1]);
2419 WMSetTextFieldText(panel->rgbGreenT, tmp);
2420 sprintf(tmp, "%d", value[2]);
2421 WMSetTextFieldText(panel->rgbBlueT, tmp);
2423 color.red = value[0];
2424 color.green = value[1];
2425 color.blue = value[2];
2427 updateSwatch(panel, color);
2428 panel->lastChanged = WMRGBModeColorPanel;
2431 static void
2432 rgbTextFieldCallback(void *observerData, WMNotification *notification)
2434 RColor color;
2435 int value[3];
2436 char tmp[4];
2437 int n;
2438 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2440 value[0] = atoi(WMGetTextFieldText(panel->rgbRedT));
2441 value[1] = atoi(WMGetTextFieldText(panel->rgbGreenT));
2442 value[2] = atoi(WMGetTextFieldText(panel->rgbBlueT));
2444 for (n=0; n < 3; n++) {
2445 if (value[n] > 255)
2446 value[n] = 255;
2447 if (value[n] < 0)
2448 value[n] = 0;
2451 sprintf(tmp, "%d", value[0]);
2452 WMSetTextFieldText(panel->rgbRedT, tmp);
2453 sprintf(tmp, "%d", value[1]);
2454 WMSetTextFieldText(panel->rgbGreenT, tmp);
2455 sprintf(tmp, "%d", value[2]);
2456 WMSetTextFieldText(panel->rgbBlueT, tmp);
2458 WMSetSliderValue(panel->rgbRedS, value[0]);
2459 WMSetSliderValue(panel->rgbGreenS, value[1]);
2460 WMSetSliderValue(panel->rgbBlueS, value[2]);
2462 color.red = value[0];
2463 color.green = value[1];
2464 color.blue = value[2];
2466 updateSwatch(panel, color);
2467 panel->lastChanged = WMRGBModeColorPanel;
2471 /******************* CMYK Panel Functions *****************/
2473 static void
2474 cmykSliderCallback(WMWidget *w, void *data)
2476 RColor color;
2477 int value[4];
2478 char tmp[4];
2480 W_ColorPanel *panel = (W_ColorPanel*)data;
2482 value[0] = WMGetSliderValue(panel->cmykCyanS);
2483 value[1] = WMGetSliderValue(panel->cmykMagentaS);
2484 value[2] = WMGetSliderValue(panel->cmykYellowS);
2485 value[3] = WMGetSliderValue(panel->cmykBlackS);
2487 sprintf(tmp, "%d", value[0]);
2488 WMSetTextFieldText(panel->cmykCyanT, tmp);
2489 sprintf(tmp, "%d", value[1]);
2490 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2491 sprintf(tmp, "%d", value[2]);
2492 WMSetTextFieldText(panel->cmykYellowT, tmp);
2493 sprintf(tmp, "%d", value[3]);
2494 WMSetTextFieldText(panel->cmykBlackT, tmp);
2496 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2497 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3]/100.0)));
2498 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] /100.0)));
2500 updateSwatch(panel, color);
2501 panel->lastChanged = WMCMYKModeColorPanel;
2504 static void
2505 cmykTextFieldCallback(void *observerData, WMNotification *notification)
2507 RColor color;
2508 int value[4];
2509 char tmp[4];
2510 int n;
2511 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2513 value[0] = atoi(WMGetTextFieldText(panel->cmykCyanT));
2514 value[1] = atoi(WMGetTextFieldText(panel->cmykMagentaT));
2515 value[2] = atoi(WMGetTextFieldText(panel->cmykYellowT));
2516 value[3] = atoi(WMGetTextFieldText(panel->cmykBlackT));
2518 for (n=0; n < 4; n++) {
2519 if (value[n] > 100)
2520 value[n] = 100;
2521 if (value[n] < 0)
2522 value[n] = 0;
2525 sprintf(tmp, "%d", value[0]);
2526 WMSetTextFieldText(panel->cmykCyanT, tmp);
2527 sprintf(tmp, "%d", value[1]);
2528 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2529 sprintf(tmp, "%d", value[2]);
2530 WMSetTextFieldText(panel->cmykYellowT, tmp);
2531 sprintf(tmp, "%d", value[3]);
2532 WMSetTextFieldText(panel->cmykBlackT, tmp);
2534 WMSetSliderValue(panel->cmykCyanS, value[0]);
2535 WMSetSliderValue(panel->cmykMagentaS, value[1]);
2536 WMSetSliderValue(panel->cmykYellowS, value[2]);
2537 WMSetSliderValue(panel->cmykBlackS, value[3]);
2539 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2540 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3]/100.0)));
2541 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] /100.0)));
2543 updateSwatch(panel, color);
2544 panel->lastChanged = WMCMYKModeColorPanel;
2547 /********************** HSB Panel Functions ***********************/
2549 static void
2550 hsbSliderCallback(WMWidget *w, void *data)
2552 RColor color;
2553 int value[3];
2554 char tmp[4];
2556 W_ColorPanel *panel = (W_ColorPanel*)data;
2558 value[0] = WMGetSliderValue(panel->hsbHueS);
2559 value[1] = WMGetSliderValue(panel->hsbSaturationS);
2560 value[2] = WMGetSliderValue(panel->hsbBrightnessS);
2562 sprintf(tmp, "%d", value[0]);
2563 WMSetTextFieldText(panel->hsbHueT, tmp);
2564 sprintf(tmp, "%d", value[1]);
2565 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2566 sprintf(tmp, "%d", value[2]);
2567 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2569 panel->hsvcolor.hue = value[0];
2570 panel->hsvcolor.saturation = value[1]*2.55;
2571 panel->hsvcolor.value = value[2]*2.55;
2573 RHSVtoRGB(&panel->hsvcolor, &color);
2575 panel->lastChanged = WMHSBModeColorPanel;
2576 updateSwatch(panel, color);
2578 if (w != panel->hsbBrightnessS)
2579 hsbUpdateBrightnessGradient(panel);
2580 if (w != panel->hsbSaturationS)
2581 hsbUpdateSaturationGradient(panel);
2582 if (w != panel->hsbHueS)
2583 hsbUpdateHueGradient(panel);
2586 static void
2587 hsbTextFieldCallback(void *observerData, WMNotification *notification)
2589 RColor color;
2590 int value[3];
2591 char tmp[4];
2592 int n;
2593 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2595 value[0] = atoi(WMGetTextFieldText(panel->hsbHueT));
2596 value[1] = atoi(WMGetTextFieldText(panel->hsbSaturationT));
2597 value[2] = atoi(WMGetTextFieldText(panel->hsbBrightnessT));
2599 if (value[0] > 359)
2600 value[0] = 359;
2601 if (value[0] < 0)
2602 value[0] = 0;
2604 for (n=1; n < 3; n++) {
2605 if (value[n] > 100)
2606 value[n] = 100;
2607 if (value[n] < 0)
2608 value[n] = 0;
2611 sprintf(tmp, "%d", value[0]);
2612 WMSetTextFieldText(panel->hsbHueT, tmp);
2613 sprintf(tmp, "%d", value[1]);
2614 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2615 sprintf(tmp, "%d", value[2]);
2616 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2618 WMSetSliderValue(panel->hsbHueS, value[0]);
2619 WMSetSliderValue(panel->hsbSaturationS, value[1]);
2620 WMSetSliderValue(panel->hsbBrightnessS, value[2]);
2622 panel->hsvcolor.hue = value[0];
2623 panel->hsvcolor.saturation = value[1]*2.55;
2624 panel->hsvcolor.value = value[2]*2.55;
2626 RHSVtoRGB(&panel->hsvcolor, &color);
2628 panel->lastChanged = WMHSBModeColorPanel;
2629 updateSwatch(panel, color);
2631 hsbUpdateBrightnessGradient(panel);
2632 hsbUpdateSaturationGradient(panel);
2633 hsbUpdateHueGradient(panel);
2636 static void
2637 hsbUpdateBrightnessGradient(W_ColorPanel *panel)
2639 W_Screen *scr = WMWidgetScreen(panel->win);
2640 RColor from;
2641 RColor to;
2642 RHSVColor hsvcolor;
2643 RImage *sliderImg;
2644 WMPixmap *sliderPxmp;
2646 from.red = from.green = from.blue = 0;
2647 hsvcolor = panel->hsvcolor;
2648 hsvcolor.value = 255;
2650 RHSVtoRGB(&hsvcolor, &to);
2652 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2653 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2654 RDestroyImage(sliderImg);
2655 W_PaintText(W_VIEW(panel->hsbBrightnessS), sliderPxmp->pixmap,
2656 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
2657 "Brightness", strlen("Brightness"));
2658 WMSetSliderImage(panel->hsbBrightnessS, sliderPxmp);
2659 WMReleasePixmap(sliderPxmp);
2662 static void
2663 hsbUpdateSaturationGradient(W_ColorPanel *panel)
2665 W_Screen *scr = WMWidgetScreen(panel->win);
2666 RColor from;
2667 RColor to;
2668 RHSVColor hsvcolor;
2669 RImage *sliderImg;
2670 WMPixmap *sliderPxmp;
2672 hsvcolor = panel->hsvcolor;
2673 hsvcolor.saturation = 0;
2674 RHSVtoRGB(&hsvcolor, &from);
2676 hsvcolor.saturation = 255;
2677 RHSVtoRGB(&hsvcolor, &to);
2679 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2680 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2681 RDestroyImage(sliderImg);
2682 if (hsvcolor.value < 128)
2683 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap,
2684 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
2685 "Saturation", strlen("Saturation"));
2686 else
2687 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap,
2688 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False,
2689 "Saturation", strlen("Saturation"));
2691 WMSetSliderImage(panel->hsbSaturationS, sliderPxmp);
2692 WMReleasePixmap(sliderPxmp);
2695 static void
2696 hsbUpdateHueGradient(W_ColorPanel *panel)
2698 W_Screen *scr = WMWidgetScreen(panel->win);
2699 RColor **colors = NULL;
2700 RHSVColor hsvcolor;
2701 RImage *sliderImg;
2702 WMPixmap *sliderPxmp;
2703 int i;
2705 hsvcolor = panel->hsvcolor;
2707 colors = malloc(sizeof(RColor*)*(8));
2708 for (i=0; i<7; i++) {
2709 hsvcolor.hue = (360*i)/6;
2710 colors[i] = malloc(sizeof(RColor));
2711 RHSVtoRGB(&hsvcolor, colors[i]);
2713 colors[7] = NULL;
2715 sliderImg = RRenderMultiGradient(141, 16, colors, RGRD_HORIZONTAL);
2716 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2717 RDestroyImage(sliderImg);
2718 if (hsvcolor.value < 128)
2719 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap,
2720 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
2721 "Hue", strlen("Hue"));
2722 else
2723 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap,
2724 panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False,
2725 "Hue", strlen("Hue"));
2727 WMSetSliderImage(panel->hsbHueS, sliderPxmp);
2728 WMReleasePixmap(sliderPxmp);
2730 for (i=0; i<7; i++) {
2731 if (colors[i])
2732 free(colors[i]);
2734 if (colors)
2735 free(colors);
2738 /*************** Custom Palette Functions ****************/
2740 static void
2741 customRenderSpectrum(W_ColorPanel *panel)
2743 RImage *spectrum;
2744 int hue, sat, val;
2745 int x,y;
2746 unsigned long ofs;
2747 unsigned char *rp, *gp, *bp;
2748 RColor color;
2749 RHSVColor cur_hsv;
2751 spectrum = RCreateImage(SPECTRUM_WIDTH, SPECTRUM_HEIGHT, 0);
2753 for (y=0; y<360; y++) {
2754 val = 255;
2755 sat = 0;
2756 hue = y;
2757 for (x=0; x<511; x++) {
2758 ofs = (y * 511) + x;
2760 cur_hsv.hue = hue;
2761 cur_hsv.saturation = sat;
2762 cur_hsv.value = val;
2764 RHSVtoRGB (&cur_hsv, &color);
2766 rp = spectrum->data[0] + ofs;
2767 gp = spectrum->data[1] + ofs;
2768 bp = spectrum->data[2] + ofs;
2770 *rp = (unsigned char)color.red;
2771 *gp = (unsigned char)color.green;
2772 *bp = (unsigned char)color.blue;
2774 if (x<255)
2775 sat++;
2777 if (x>255)
2778 val--;
2781 if (panel->customPaletteImg) {
2782 RDestroyImage(panel->customPaletteImg);
2783 panel->customPaletteImg = NULL;
2785 panel->customPaletteImg = spectrum;
2790 static void
2791 customSetPalette(W_ColorPanel *panel)
2793 W_Screen *scr = WMWidgetScreen(panel->win);
2794 RImage *scaledImg;
2795 Pixmap image;
2796 int item;
2798 image = XCreatePixmap(scr->display, W_DRAWABLE(scr), customPaletteWidth,
2799 customPaletteHeight, scr->depth);
2801 scaledImg = RScaleImage(panel->customPaletteImg, customPaletteWidth,
2802 customPaletteHeight);
2803 RConvertImage(scr->rcontext, scaledImg, &image);
2804 RDestroyImage(scaledImg);
2806 XCopyArea(scr->display, image, panel->customPaletteContentView->window,
2807 scr->copyGC, 0, 0, customPaletteWidth, customPaletteHeight, 0, 0);
2809 /* Check backimage exists. If it doesn't, allocate and fill it */
2810 if (!panel->selectionBackImg) {
2811 panel->selectionBackImg = XCreatePixmap(scr->display,
2812 panel->customPaletteContentView->window, 4, 4, scr->depth);
2815 XCopyArea(scr->display, image, panel->selectionBackImg, scr->copyGC,
2816 panel->palx-2, panel->paly-2, 4, 4, 0, 0);
2817 XCopyArea(scr->display, panel->selectionImg,
2818 panel->customPaletteContentView->window, scr->copyGC, 0 , 0, 4, 4,
2819 panel->palx-2, panel->paly-2);
2820 XFreePixmap(scr->display, image);
2822 panel->palXRatio = (float)(panel->customPaletteImg->width) /
2823 (float)(customPaletteWidth);
2824 panel->palYRatio = (float)(panel->customPaletteImg->height) /
2825 (float)(customPaletteHeight);
2827 item = WMGetPopUpButtonSelectedItem (panel->customPaletteHistoryBtn);
2829 /* if palette != "Spectrum", we are allowed to rename and remove it */
2830 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename,
2831 (item > 0) );
2832 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove,
2833 (item > 0) );
2837 static void
2838 customPalettePositionSelection(W_ColorPanel *panel, int x, int y)
2840 W_Screen *scr = WMWidgetScreen(panel->win);
2841 unsigned long ofs;
2844 /* undraw selection */
2845 XCopyArea(scr->display, panel->selectionBackImg,
2846 panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4,
2847 panel->palx-2, panel->paly-2);
2849 panel->palx = x;
2850 panel->paly = y;
2852 ofs = rint(x * panel->palXRatio) + rint(y * panel->palYRatio) *
2853 panel->customPaletteImg->width;
2855 panel->color.red = panel->customPaletteImg->data[0][ofs];
2856 panel->color.green = panel->customPaletteImg->data[1][ofs];
2857 panel->color.blue = panel->customPaletteImg->data[2][ofs];
2859 updateSwatch(panel, panel->color);
2860 panel->lastChanged = WMCustomPaletteModeColorPanel;
2862 /* Redraw color selector (and make a backup of the part it will cover) */
2863 XCopyArea(scr->display, panel->customPaletteContentView->window,
2864 panel->selectionBackImg, scr->copyGC, panel->palx-2, panel->paly-2,
2865 4, 4, 0, 0); /* "-2" is correction for hotspot location */
2866 XCopyArea(scr->display, panel->selectionImg,
2867 panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4,
2868 panel->palx-2, panel->paly-2); /* see above */
2872 static void
2873 customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2875 if (x < 2)
2876 x = 2;
2877 if (y < 2)
2878 y = 2;
2879 if (x >= customPaletteWidth)
2880 x = customPaletteWidth -2;
2881 if (y >= customPaletteHeight)
2882 y = customPaletteHeight -2;
2884 customPalettePositionSelection(panel, x, y);
2888 static void
2889 customPaletteHandleEvents(XEvent *event, void *data)
2891 W_ColorPanel *panel = (W_ColorPanel*)data;
2893 switch (event->type) {
2894 case Expose:
2895 if (event->xexpose.count != 0)
2896 break;
2897 customSetPalette(panel);
2898 break;
2902 static void
2903 customPaletteHandleActionEvents(XEvent *event, void *data)
2905 W_ColorPanel *panel = (W_ColorPanel*)data;
2906 int x, y;
2908 switch (event->type) {
2909 case ButtonPress:
2910 x = event->xbutton.x;
2911 y = event->xbutton.y;
2913 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2914 panel->flags.dragging = 1;
2915 customPalettePositionSelection(panel, x, y);
2917 break;
2919 case ButtonRelease:
2920 panel->flags.dragging = 0;
2921 if (!panel->flags.continuous) {
2922 if (panel->action)
2923 (*panel->action)(panel->action, panel->clientData);
2925 break;
2927 case MotionNotify:
2928 x = event->xmotion.x;
2929 y = event->xmotion.y;
2931 if (panel->flags.dragging) {
2932 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2933 customPalettePositionSelection(panel, x, y);
2935 else
2936 customPalettePositionSelectionOutBounds(panel, x, y);
2938 break;
2943 static void
2944 customPaletteMenuCallback(WMWidget *w, void *data)
2946 W_ColorPanel *panel = (W_ColorPanel*)data;
2947 int item = WMGetPopUpButtonSelectedItem(panel->customPaletteMenuBtn);
2949 switch (item) {
2950 case CPmenuNewFromFile:
2951 customPaletteMenuNewFromFile(panel);
2952 break;
2953 case CPmenuRename:
2954 customPaletteMenuRename(panel);
2955 break;
2956 case CPmenuRemove:
2957 customPaletteMenuRemove(panel);
2958 break;
2959 case CPmenuCopy:
2960 break;
2961 case CPmenuNewFromClipboard:
2962 break;
2967 static void
2968 customPaletteMenuNewFromFile(W_ColorPanel *panel)
2970 W_Screen *scr = WMWidgetScreen(panel->win);
2971 WMOpenPanel *browseP;
2972 char *filepath;
2973 char *filename = NULL;
2974 char *spath;
2975 char *tmp;
2976 int i;
2977 RImage *tmpImg = NULL;
2979 if ((!panel->lastBrowseDir) || (strcmp(panel->lastBrowseDir,"\0") == 0))
2980 spath = wexpandpath(wgethomedir());
2981 else
2982 spath = wexpandpath(panel->lastBrowseDir);
2984 browseP = WMGetOpenPanel(scr);
2985 WMSetFilePanelCanChooseDirectories(browseP, 0);
2986 WMSetFilePanelCanChooseFiles(browseP, 1);
2988 /* Get a filename */
2989 if (WMRunModalFilePanelForDirectory(browseP, panel->win, spath,
2990 "Open Palette",
2991 RSupportedFileFormats()) ) {
2992 filepath = WMGetFilePanelFileName(browseP);
2994 /* Get seperation position between path and filename */
2995 i = strrchr(filepath, '/') - filepath + 1;
2996 if (i > strlen(filepath))
2997 i = strlen(filepath);
2999 /* Store last browsed path */
3000 if (panel->lastBrowseDir)
3001 free(panel->lastBrowseDir);
3002 panel->lastBrowseDir = wmalloc((i+1)*sizeof(char));
3003 strncpy(panel->lastBrowseDir, filepath, i);
3004 panel->lastBrowseDir[i] = '\0';
3006 /* Get filename from path */
3007 filename = wstrdup(filepath + i);
3009 /* Check for duplicate files, and rename it if there are any */
3010 tmp = wstrappend(panel->configurationPath, filename);
3011 while (access (tmp, F_OK) == 0) {
3012 char *newName;
3014 free(tmp);
3016 newName = generateNewFilename(filename);
3017 free(filename);
3018 filename = newName;
3020 tmp = wstrappend(panel->configurationPath, filename);
3022 free(tmp);
3024 /* Copy image to $(gnustepdir)/Library/Colors/ &
3025 * Add filename to history menu */
3026 if (fetchFile (panel->configurationPath, filepath, filename) == 0) {
3028 /* filepath is a "local" path now the file has been copied */
3029 free(filepath);
3030 filepath = wstrappend(panel->configurationPath, filename);
3032 /* load the image & add menu entries */
3033 tmpImg = RLoadImage(scr->rcontext, filepath, 0);
3034 if (tmpImg) {
3035 if (panel->customPaletteImg)
3036 RDestroyImage(panel->customPaletteImg);
3037 panel->customPaletteImg = tmpImg;
3039 customSetPalette(panel);
3040 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, filename);
3042 panel->currentPalette = WMGetPopUpButtonNumberOfItems(
3043 panel->customPaletteHistoryBtn)-1;
3045 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
3046 panel->currentPalette);
3049 else
3051 tmp = wstrappend(panel->configurationPath, filename);
3053 i = remove(tmp); /* Delete the file, it doesn't belong here */
3054 WMRunAlertPanel(scr, panel->win, "File Error",
3055 "Invalid file format !", "OK", NULL, NULL);
3056 if (i != 0) {
3057 wsyserror("can't remove file %s", tmp);
3058 WMRunAlertPanel(scr, panel->win, "File Error",
3059 "Couldn't remove file from Configuration Directory !",
3060 "OK", NULL, NULL);
3062 free(tmp);
3064 free(filepath);
3065 free(filename);
3067 WMFreeFilePanel(browseP);
3069 free(spath);
3073 static void
3074 customPaletteMenuRename(W_ColorPanel *panel)
3076 W_Screen *scr = WMWidgetScreen(panel->win);
3077 char *toName = NULL;
3078 char *fromName;
3079 char *toPath, *fromPath;
3080 int item;
3081 int index;
3083 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
3084 fromName = WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item);
3086 toName = WMRunInputPanel(scr, panel->win, "Rename", "Rename palette to:",
3087 fromName, "OK", "Cancel");
3089 if (toName) {
3091 /* As some people do certain stupid things... */
3092 if (strcmp(toName, fromName) == 0) {
3093 free(toName);
3094 return;
3097 /* For normal people */
3098 fromPath = wstrappend(panel->configurationPath, fromName);
3099 toPath = wstrappend(panel->configurationPath, toName);
3101 if (access (toPath, F_OK) == 0) {
3102 /* Careful, this palette exists already */
3103 if (WMRunAlertPanel(scr, panel->win, "Warning",
3104 "Palette already exists !\n\nOverwrite ?", "No", "Yes",
3105 NULL) == 1) {
3106 /* "No" = 0, "Yes" = 1 */
3107 int items = WMGetPopUpButtonNumberOfItems(
3108 panel->customPaletteHistoryBtn);
3110 remove(toPath);
3112 /* Remove from History list too */
3113 index = 1;
3114 while ((index < items) && (strcmp(WMGetPopUpButtonItem(
3115 panel->customPaletteHistoryBtn, index),
3116 toName) != 0 ))
3117 index++;
3119 if (index < items) {
3120 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn,
3121 index);
3122 if (index < item)
3123 item--;
3126 } else {
3127 free(fromPath);
3128 free(toName);
3129 free(toPath);
3131 return;
3135 if ( rename(fromPath, toPath) != 0)
3136 wsyserror("Couldn't rename palette %s to %s\n", fromName, toName);
3137 else {
3138 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
3139 WMInsertPopUpButtonItem(panel->customPaletteHistoryBtn, item,
3140 toName);
3142 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item);
3144 free(fromPath);
3145 free(toPath);
3146 free(toName);
3151 static void
3152 customPaletteMenuRemove(W_ColorPanel *panel)
3154 W_Screen *scr = WMWidgetScreen(panel->win);
3155 char *text;
3156 char *tmp;
3157 int choice;
3158 int item;
3160 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
3162 tmp = wstrappend( "This will permanently remove the palette ",
3163 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
3164 text = wstrappend( tmp, ".\n\nAre you sure you want to remove this"
3165 " palette ?");
3166 free(tmp);
3168 choice = WMRunAlertPanel(scr, panel->win, NULL, text, "Yes", "No", NULL);
3169 /* returns 0 (= "Yes") or 1 (="No") */
3170 free(text);
3172 if (choice == 0) {
3174 tmp = wstrappend(panel->configurationPath,
3175 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
3177 if ( remove(tmp) != 0)
3178 wsyserror("Couldn't remove palette %s\n", tmp);
3179 free(tmp);
3181 /* item -1 always exists */
3182 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item-1);
3184 customPaletteHistoryCallback(panel->customPaletteHistoryBtn, panel);
3185 customSetPalette(panel);
3187 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
3192 static void
3193 customPaletteHistoryCallback(WMWidget *w, void *data)
3195 W_ColorPanel *panel = (W_ColorPanel*)data;
3196 W_Screen *scr = WMWidgetScreen(panel->win);
3197 int item;
3198 char *filename;
3199 RImage *tmp = NULL;
3201 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
3202 if (item == panel->currentPalette)
3203 return;
3205 if (item == 0)
3206 customRenderSpectrum(panel);
3207 else {
3208 /* Load file from configpath */
3209 filename = wstrappend( panel->configurationPath,
3210 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item) );
3212 /* XXX To do: Check existence of file and remove it from the history
3213 * if it doesn't exist */
3215 tmp = RLoadImage(scr->rcontext, filename, 0);
3216 if (tmp) {
3217 if (panel->customPaletteImg) {
3218 RDestroyImage(panel->customPaletteImg);
3219 panel->customPaletteImg = NULL;
3221 panel->customPaletteImg = tmp;
3223 free(filename);
3225 customSetPalette(panel);
3227 panel->currentPalette = item;
3231 /*************** Panel Initialisation Functions *****************/
3233 static void
3234 wheelInit(W_ColorPanel *panel)
3236 RHSVColor cur_hsv;
3237 int i;
3238 int v;
3240 RRGBtoHSV(&panel->color, &cur_hsv);
3242 WMSetSliderValue(panel->wheelBrightnessS, 255-cur_hsv.value);
3243 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
3245 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 + (
3246 cur_hsv.saturation/255.0) * cos( cur_hsv.hue*M_PI/180.0)));
3247 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 + (
3248 cur_hsv.saturation/255.0) * sin(-cur_hsv.hue*M_PI/180.0)));
3250 for (i = 0; i < 256; i++) {
3251 /* We divide by 128 in advance, and check whether that number divides
3252 * by 2 properly. If not, we add one to round the number correctly
3254 v = (i*cur_hsv.value) >> 7;
3255 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + (v & 1));
3259 static void
3260 grayInit(W_ColorPanel *panel)
3262 RHSVColor cur_hsv;
3263 int value;
3264 char tmp[4];
3266 RRGBtoHSV(&panel->color, &cur_hsv);
3268 value = rint(cur_hsv.value/2.55);
3269 WMSetSliderValue(panel->grayBrightnessS, value);
3271 sprintf(tmp, "%d", value);
3272 WMSetTextFieldText(panel->grayBrightnessT, tmp);
3275 static void
3276 rgbInit(W_ColorPanel *panel)
3278 char tmp[4];
3280 WMSetSliderValue(panel->rgbRedS,panel->color.red);
3281 WMSetSliderValue(panel->rgbGreenS,panel->color.green);
3282 WMSetSliderValue(panel->rgbBlueS,panel->color.blue);
3284 sprintf(tmp, "%d", panel->color.red);
3285 WMSetTextFieldText(panel->rgbRedT, tmp);
3286 sprintf(tmp, "%d", panel->color.green);
3287 WMSetTextFieldText(panel->rgbGreenT, tmp);
3288 sprintf(tmp, "%d", panel->color.blue);
3289 WMSetTextFieldText(panel->rgbBlueT, tmp);
3292 static void
3293 cmykInit(W_ColorPanel *panel)
3295 int value[3];
3296 char tmp[4];
3298 value[0] = rint((255-panel->color.red)/2.55);
3299 value[1] = rint((255-panel->color.green)/2.55);
3300 value[2] = rint((255-panel->color.blue)/2.55);
3302 WMSetSliderValue(panel->cmykCyanS, value[0]);
3303 WMSetSliderValue(panel->cmykMagentaS, value[1]);
3304 WMSetSliderValue(panel->cmykYellowS, value[2]);
3305 WMSetSliderValue(panel->cmykBlackS, 0);
3307 sprintf(tmp, "%d", value[0]);
3308 WMSetTextFieldText(panel->cmykCyanT, tmp);
3309 sprintf(tmp, "%d", value[1]);
3310 WMSetTextFieldText(panel->cmykMagentaT, tmp);
3311 sprintf(tmp, "%d", value[2]);
3312 WMSetTextFieldText(panel->cmykYellowT, tmp);
3313 WMSetTextFieldText(panel->cmykBlackT, "0");
3316 static void
3317 hsbInit(W_ColorPanel *panel)
3319 int value[3];
3320 char tmp[4];
3322 value[0] = panel->hsvcolor.hue;
3323 value[1] = rint(panel->hsvcolor.saturation/2.55);
3324 value[2] = rint(panel->hsvcolor.value/2.55);
3326 WMSetSliderValue(panel->hsbHueS,value[0]);
3327 WMSetSliderValue(panel->hsbSaturationS,value[1]);
3328 WMSetSliderValue(panel->hsbBrightnessS,value[2]);
3330 sprintf(tmp, "%d", value[0]);
3331 WMSetTextFieldText(panel->hsbHueT, tmp);
3332 sprintf(tmp, "%d", value[1]);
3333 WMSetTextFieldText(panel->hsbSaturationT, tmp);
3334 sprintf(tmp, "%d", value[2]);
3335 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
3337 hsbUpdateBrightnessGradient(panel);
3338 hsbUpdateSaturationGradient(panel);
3339 hsbUpdateHueGradient(panel);
3345 /************************* ColorList Panel Functions **********************/
3347 static void
3348 colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text,
3349 int state, WMRect *rect)
3351 int width, height, x, y;
3352 RColor color = *((RColor *)WMGetListItem(lPtr, index)->clientData);
3353 WMScreen *scr = WMWidgetScreen(lPtr);
3354 Display *dpy = WMScreenDisplay(scr);
3355 W_ColorPanel *panel = WMGetHangedData(lPtr);
3356 WMColor *white = WMWhiteColor(scr);
3357 WMColor *black = WMBlackColor(scr);
3358 WMColor *fillColor;
3360 width = rect->size.width;
3361 height = rect->size.height;
3362 x = rect->pos.x;
3363 y = rect->pos.y;
3365 if (state & WLDSSelected)
3366 WMPaintColorSwatch(white, d, x +15, y, width -15, height);
3367 else
3368 XClearArea(dpy, d, x +15, y, width -15, height, False);
3370 fillColor = WMCreateRGBColor(scr, color.red*256, color.green*256,
3371 color.blue*256, False);
3373 WMSetColorInGC(fillColor, WMColorGC(fillColor));
3374 WMPaintColorSwatch(fillColor, d, x, y, 15, 15);
3375 WMReleaseColor(fillColor);
3377 WMDrawString(scr, d, WMColorGC(black), panel->font12, x+18, y, text,
3378 strlen(text));
3380 WMReleaseColor(white);
3381 WMReleaseColor(black);
3385 static void
3386 colorListSelect(WMWidget *w, void *data)
3388 W_ColorPanel *panel = (W_ColorPanel *)data;
3389 RColor color = *((RColor *)WMGetListSelectedItem(w)->clientData);
3391 panel->lastChanged = WMColorListModeColorPanel;
3392 updateSwatch(panel, color);
3396 static void
3397 colorListColorMenuCallback(WMWidget *w, void *data)
3399 W_ColorPanel *panel = (W_ColorPanel *)data;
3400 int item = WMGetPopUpButtonSelectedItem(panel->colorListColorMenuBtn);
3402 switch (item) {
3403 case CLmenuAdd:
3404 break;
3405 case CLmenuRename:
3406 break;
3407 case CLmenuRemove:
3408 break;
3413 static void
3414 colorListListMenuCallback(WMWidget *w, void *data)
3416 W_ColorPanel *panel = (W_ColorPanel *)data;
3417 int item = WMGetPopUpButtonSelectedItem(panel->colorListListMenuBtn);
3419 switch (item) {
3420 case CLmenuAdd:
3421 /* New Color List */
3422 colorListListMenuNew(panel);
3423 break;
3424 case CLmenuRename:
3425 break;
3426 case CLmenuRemove:
3427 break;
3432 static void
3433 colorListListMenuNew(W_ColorPanel *panel)
3439 /************************** Common utility functions ************************/
3441 static int
3442 fetchFile(char *toPath, char *srcFile, char *destFile)
3444 int src, dest;
3445 int n;
3446 char *tmp;
3447 char buf[BUFSIZE];
3449 if ((src = open(srcFile, O_RDONLY)) == 0) {
3450 wsyserror("Could not open %s", srcFile);
3451 return -1;
3454 tmp = wstrappend(toPath, destFile);
3455 if ((dest = open( tmp, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))
3456 == 0) {
3457 wsyserror("Could not create %s", tmp);
3458 free(tmp);
3459 return -1;
3461 free(tmp);
3464 /* Copy the file */
3465 while ((n = read(src, buf, BUFSIZE)) > 0)
3467 if (write (dest, buf, n) != n) {
3468 wsyserror("Write error on file %s", destFile);
3469 return -1;
3473 return 0;
3477 char*
3478 generateNewFilename(char *curName)
3480 int n;
3481 char c;
3482 int baseLen;
3483 char *ptr;
3484 char *newName;
3487 assert(curName);
3489 ptr = curName;
3491 if (
3492 ((ptr = strrchr(ptr, '{')) == 0) ||
3493 sscanf(ptr, "{%i}%c", &n, &c) != 1
3495 return wstrappend(curName, " {1}");
3497 baseLen = ptr - curName -1;
3499 newName = wmalloc(baseLen + 16);
3500 strncpy(newName, curName, baseLen);
3501 newName[baseLen] = 0;
3503 sprintf(&newName[baseLen], " {%i}", n+1);
3505 return newName;