Update for 0.51.2-pre2
[wmaker-crm.git] / WINGs / wcolorpanel.c
blob27ca13e6aefb8bedfb9ea876f0525c107a1175c4
1 /*
2 * ColorPanel for WINGs
4 * by ]d : Original idea and basic initial code
5 * Pascal Hofstee : Code for wheeldrawing and calculating colors from it.
6 * Primary coder of this Color Panel.
7 * Alban Hertroys : Optimizations for algorithms for color-
8 * wheel. Also custom ColorPalettes and magnifying
9 * glass. Secondary coder ;)
10 * Alfredo K. Kojima : For pointing out memory-allocation problems
11 * and similair code-issues
12 * Marco van Hylckama-Vlieg : For once again doing the artwork ;-)
14 * small note: Tabstop size = 8
19 #include "WINGsP.h"
20 #include <math.h>
21 #include <unistd.h>
22 #include <ctype.h>
23 #include <fcntl.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <dirent.h>
27 #include <errno.h>
30 #ifndef PATH_MAX
31 # define PATH_MAX 1024
32 #endif
36 * Bitmaps for magnifying glass cursor
39 /* Cursor */
40 #define Cursor_x_hot 11
41 #define Cursor_y_hot 11
42 #define Cursor_width 32
43 #define Cursor_height 32
44 static unsigned char Cursor_bits[] = {
45 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
46 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
47 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
48 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
49 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
50 0x00,0x08,0x00,0x50,0x00,0x10,0x00,0x88,0x00,0x20,0x00,0x5c,0x01,0xc0,0x81,
51 0x3b,0x02,0x00,0x7e,0x70,0x05,0x00,0x00,0xe0,0x08,0x00,0x00,0xc0,0x15,0x00,
52 0x00,0x80,0x23,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x5c,
53 0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x70};
55 /* Cursor shape-mask */
56 #define Cursor_shape_width 32
57 #define Cursor_shape_height 32
58 static unsigned char Cursor_shape_bits[] = {
59 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
60 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
61 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
62 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
63 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
64 0x00,0x08,0x00,0x70,0x00,0x10,0x00,0xf8,0x00,0x20,0x00,0xfc,0x01,0xc0,0x81,
65 0xfb,0x03,0x00,0x7e,0xf0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x1f,0x00,
66 0x00,0x80,0x3f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfc,
67 0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70};
69 /* Clip-mask for magnified pixels */
70 #define Cursor_mask_width 22
71 #define Cursor_mask_height 22
72 static unsigned char Cursor_mask_bits[] = {
73 0x00,0x3f,0x00,0xe0,0xff,0x01,0xf0,0xff,0x03,0xf8,0xff,0x07,0xfc,0xff,0x0f,
74 0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xff,0xff,0x3f,0xff,0xff,0x3f,
75 0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xfe,0xff,0x1f,
76 0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfc,0xff,0x0f,0xf8,0xff,0x07,0xf0,0xff,0x03,
77 0xe0,0xff,0x01,0x00,0x3f,0x00};
80 typedef struct MovingView {
81 WMView *view; /* The view this is all about */
82 Pixmap pixmap; /* What's under the view */
83 Pixmap mask; /* Pixmap mask for view-contents */
84 int valid; /* Are contents still valid ? */
85 RColor color; /* Color of a pixel in the image */
86 } MovingView;
88 typedef struct WheelMatrix {
89 unsigned int width, height; /* Size of the colorwheel */
90 unsigned char *data[3]; /* Wheel data (R,G,B) */
91 unsigned char values[256]; /* Precalculated values for R,G & B values 0..255 */
92 } wheelMatrix;
94 typedef struct W_ColorPanel {
95 WMWindow *win;
96 WMFont *font8;
97 WMFont *font12;
99 void *clientData;
100 WMAction *action;
102 /* Common Stuff */
103 WMColorWell *colorWell;
104 WMButton *magnifyBtn;
105 WMButton *wheelBtn;
106 WMButton *slidersBtn;
107 WMButton *customPaletteBtn;
108 WMButton *colorListBtn;
110 /* Magnifying Glass */
111 MovingView *magnifyGlass;
113 /* ColorWheel Panel */
114 WMFrame *wheelFrm;
115 WMSlider *wheelBrightnessS;
116 WMView *wheelView;
118 /* Slider Panels */
119 WMFrame *slidersFrm;
120 WMFrame *seperatorFrm;
121 WMButton *grayBtn;
122 WMButton *rgbBtn;
123 WMButton *cmykBtn;
124 WMButton *hsbBtn;
125 /* Gray Scale Panel */
126 WMFrame *grayFrm;
127 WMLabel *grayMinL;
128 WMLabel *grayMaxL;
129 WMSlider *grayBrightnessS;
130 WMTextField *grayBrightnessT;
131 WMButton *grayPresetBtn[7];
133 /* RGB Panel */
134 WMFrame *rgbFrm;
135 WMLabel *rgbMinL;
136 WMLabel *rgbMaxL;
137 WMSlider *rgbRedS;
138 WMSlider *rgbGreenS;
139 WMSlider *rgbBlueS;
140 WMTextField *rgbRedT;
141 WMTextField *rgbGreenT;
142 WMTextField *rgbBlueT;
144 /* CMYK Panel */
145 WMFrame *cmykFrm;
146 WMLabel *cmykMinL;
147 WMLabel *cmykMaxL;
148 WMSlider *cmykCyanS;
149 WMSlider *cmykMagentaS;
150 WMSlider *cmykYellowS;
151 WMSlider *cmykBlackS;
152 WMTextField *cmykCyanT;
153 WMTextField *cmykMagentaT;
154 WMTextField *cmykYellowT;
155 WMTextField *cmykBlackT;
157 /* HSB Panel */
158 WMFrame *hsbFrm;
159 WMSlider *hsbHueS;
160 WMSlider *hsbSaturationS;
161 WMSlider *hsbBrightnessS;
162 WMTextField *hsbHueT;
163 WMTextField *hsbSaturationT;
164 WMTextField *hsbBrightnessT;
166 /* Custom Palette Panel*/
167 WMFrame *customPaletteFrm;
168 WMPopUpButton *customPaletteHistoryBtn;
169 WMFrame *customPaletteContentFrm;
170 WMPopUpButton *customPaletteMenuBtn;
171 WMView *customPaletteContentView;
173 /* Color List Panel */
174 WMFrame *colorListFrm;
175 WMPopUpButton *colorListHistoryBtn;
176 WMList *colorListContentLst;
177 WMPopUpButton *colorListColorMenuBtn;
178 WMPopUpButton *colorListListMenuBtn;
180 /* Look-Up Tables and Images */
181 wheelMatrix *wheelMtrx;
182 Pixmap wheelImg;
183 Pixmap selectionImg;
184 Pixmap selectionBackImg;
185 RImage *customPaletteImg;
186 char *lastBrowseDir;
188 /* Common Data Fields */
189 RColor color; /* Current color */
190 RHSVColor hsvcolor; /* Backup HSV Color */
191 WMColorPanelMode mode; /* Current color selection mode */
192 WMColorPanelMode slidersmode; /* Current color selection mode at sliders panel */
193 WMColorPanelMode lastChanged; /* Panel that last changed the color */
194 int colx, coly; /* (x,y) of selection-marker in WheelMode */
195 int palx, paly; /* (x,y) of selection-marker in CustomPaletteMode */
196 float palXRatio, palYRatio; /* Ratios in x & y between original and scaled palettesize */
197 int currentPalette;
198 char *configurationPath;
200 struct {
201 unsigned int continuous:1;
203 unsigned int dragging:1;
204 } flags;
205 } W_ColorPanel;
207 enum {
208 CPmenuNewFromFile,
209 CPmenuRename,
210 CPmenuRemove,
211 CPmenuCopy,
212 CPmenuNewFromClipboard
213 } customPaletteMenuItem;
215 enum {
216 CLmenuAdd,
217 CLmenuRename,
218 CLmenuRemove
219 } colorListMenuItem;
222 #define PWIDTH 194
223 #define PHEIGHT 266
224 #define colorWheelSize 150
225 #define customPaletteWidth 182
226 #define customPaletteHeight 106
227 #define knobThickness 8
229 #define SPECTRUM_WIDTH 511
230 #define SPECTRUM_HEIGHT 360
232 #define COLORWHEEL_PART 1
233 #define CUSTOMPALETTE_PART 2
234 #define BUFSIZE 1024
236 #undef EASTEREGG
238 #define RGBTXT "/usr/X11R6/lib/X11/rgb.txt"
239 #define MAX_LENGTH 1024
241 static int fetchFile(char* toPath, char *imageSrcFile, char *imageDestFileName);
242 char *generateNewFilename(char *curName);
244 static void modeButtonCallback(WMWidget *w, void *data);
245 static int getPickerPart(W_ColorPanel *panel, int x, int y);
246 static void readConfiguration(W_ColorPanel *panel);
247 static void readXColors(W_ColorPanel *panel);
249 static void closeWindowCallback(WMWidget *w, void *data);
251 static Cursor magnifyGrabPointer(W_ColorPanel *panel);
252 static WMPoint magnifyInitialize(W_ColorPanel *panel);
253 static void magnifyPutCursor(WMWidget *w, void *data);
254 static Pixmap magnifyCreatePixmap(WMColorPanel *panel);
255 static Pixmap magnifyGetStorePixmap(W_ColorPanel *panel, int x1, int y1, int x2, int y2);
256 static Pixmap magnifyGetImage(WMScreen *scr, int x, int y);
258 static wheelMatrix* wheelCreateMatrix(unsigned int width , unsigned int height);
259 static void wheelDestroyMatrix(wheelMatrix *matrix);
260 static wheelMatrix* wheelInitMatrix(W_ColorPanel *panel);
261 static void wheelRender(W_ColorPanel *panel);
262 static Bool wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs);
263 static void wheelPaint(W_ColorPanel *panel);
265 static void wheelHandleEvents(XEvent *event, void *data);
266 static void wheelHandleActionEvents(XEvent *event, void *data);
267 static void wheelBrightnessSliderCallback(WMWidget *w, void *data);
268 static void wheelUpdateSelection(W_ColorPanel *panel);
269 static void wheelUndrawSelection(W_ColorPanel *panel);
271 static void wheelPositionSelection(W_ColorPanel *panel, int x, int y);
272 static void wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y);
273 static void wheelUpdateBrightnessGradientFromHSV (W_ColorPanel *panel, RHSVColor topColor);
274 static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel *panel);
275 static void wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor);
277 static void grayBrightnessSliderCallback(WMWidget *w, void *data);
278 static void grayPresetButtonCallback(WMWidget *w, void *data);
279 static void grayBrightnessTextFieldCallback(void *observerData, WMNotification *notification);
281 static void rgbSliderCallback(WMWidget *w, void *data);
282 static void rgbTextFieldCallback(void *observerData, WMNotification *notification);
284 static void cmykSliderCallback(WMWidget *w, void *data);
285 static void cmykTextFieldCallback(void *observerData, WMNotification *notification);
287 static void hsbSliderCallback(WMWidget *w, void *data);
288 static void hsbTextFieldCallback(void *observerData, WMNotification *notification);
289 static void hsbUpdateBrightnessGradient(W_ColorPanel *panel);
290 static void hsbUpdateSaturationGradient(W_ColorPanel *panel);
291 static void hsbUpdateHueGradient(W_ColorPanel *panel);
293 static void customRenderSpectrum(W_ColorPanel *panel);
294 static void customSetPalette(W_ColorPanel *panel);
295 static void customPaletteHandleEvents(XEvent *event, void *data);
296 static void customPaletteHandleActionEvents(XEvent *event, void *data);
297 static void customPalettePositionSelection(W_ColorPanel *panel, int x, int y);
298 static void customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y);
299 static void customPaletteMenuCallback(WMWidget *w, void *data);
300 static void customPaletteHistoryCallback(WMWidget *w, void *data);
302 static void customPaletteMenuNewFromFile(W_ColorPanel *panel);
303 static void customPaletteMenuRename(W_ColorPanel *panel);
304 static void customPaletteMenuRemove(W_ColorPanel *panel);
306 static void colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text, int state, WMRect *rect);
307 static void colorListSelect(WMWidget *w, void *data);
308 static void colorListColorMenuCallback(WMWidget *w, void *data);
309 static void colorListListMenuCallback(WMWidget *w, void *data);
310 static void colorListListMenuNew(W_ColorPanel *panel);
312 static void wheelInit(W_ColorPanel *panel);
313 static void grayInit(W_ColorPanel *panel);
314 static void rgbInit(W_ColorPanel *panel);
315 static void cmykInit(W_ColorPanel *panel);
316 static void hsbInit(W_ColorPanel *panel);
320 void
321 WMSetColorPanelAction(WMColorPanel *panel, WMAction *action, void *data)
323 panel->action = action;
324 panel->clientData = data;
329 static WMColorPanel*
330 makeColorPanel(WMScreen *scrPtr, char *name)
332 WMColorPanel *panel;
333 RImage *image;
334 WMPixmap *pixmap;
335 RColor from;
336 RColor to;
337 WMColor *textcolor;
338 int i;
339 int x,y;
342 panel = wmalloc(sizeof(WMColorPanel));
343 memset(panel, 0, sizeof(WMColorPanel));
345 panel->font8 = WMSystemFontOfSize(scrPtr, 8);
346 panel->font12 = WMSystemFontOfSize(scrPtr, 12);
348 panel->win = WMCreateWindowWithStyle(scrPtr, name, WMTitledWindowMask | WMClosableWindowMask | WMResizableWindowMask);
349 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
350 WMSetWindowTitle(panel->win, "Colors");
351 WMSetWindowCloseAction(panel->win, closeWindowCallback, panel);
353 /* Set Default ColorPanel Mode(s) */
354 panel->mode = WMWheelModeColorPanel;
355 panel->lastChanged = WMWheelModeColorPanel;
356 panel->slidersmode = WMRGBModeColorPanel;
357 panel->configurationPath = wstrappend(wusergnusteppath(), "/Library/Colors/");
359 /* Some Generic Purpose Widgets */
360 panel->colorWell = WMCreateColorWell(panel->win);
361 WMResizeWidget(panel->colorWell, 134, 36);
362 WSetColorWellBordered(panel->colorWell, False);
363 WMMoveWidget(panel->colorWell, 56, 4);
365 panel->magnifyBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
366 WMResizeWidget(panel->magnifyBtn, 46, 36);
367 WMMoveWidget(panel->magnifyBtn, 6,4);
368 WMSetButtonAction(panel->magnifyBtn, magnifyPutCursor, panel);
369 WMSetButtonImagePosition(panel->magnifyBtn, WIPImageOnly);
370 WMSetButtonImage(panel->magnifyBtn, scrPtr->magnifyIcon);
372 panel->wheelBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
373 WMResizeWidget(panel->wheelBtn, 46, 32);
374 WMMoveWidget(panel->wheelBtn, 6, 44);
375 WMSetButtonAction(panel->wheelBtn, modeButtonCallback, panel);
376 WMSetButtonImagePosition(panel->wheelBtn, WIPImageOnly);
377 WMSetButtonImage(panel->wheelBtn, scrPtr->wheelIcon);
379 panel->slidersBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
380 WMResizeWidget(panel->slidersBtn, 46, 32);
381 WMMoveWidget(panel->slidersBtn, 52, 44);
382 WMSetButtonAction(panel->slidersBtn, modeButtonCallback, panel);
383 WMSetButtonImagePosition(panel->slidersBtn, WIPImageOnly);
384 WMSetButtonImage(panel->slidersBtn, scrPtr->rgbIcon);
386 panel->customPaletteBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
387 WMResizeWidget(panel->customPaletteBtn, 46, 32);
388 WMMoveWidget(panel->customPaletteBtn, 98, 44);
389 WMSetButtonAction(panel->customPaletteBtn, modeButtonCallback, panel);
390 WMSetButtonImagePosition(panel->customPaletteBtn, WIPImageOnly);
391 WMSetButtonImage(panel->customPaletteBtn, scrPtr->customPaletteIcon);
393 panel->colorListBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
394 WMResizeWidget(panel->colorListBtn, 46, 32);
395 WMMoveWidget(panel->colorListBtn, 144, 44);
396 WMSetButtonAction(panel->colorListBtn, modeButtonCallback, panel);
397 WMSetButtonImagePosition(panel->colorListBtn, WIPImageOnly);
398 WMSetButtonImage(panel->colorListBtn, scrPtr->colorListIcon);
400 /* Let's Group some of them together */
401 WMGroupButtons(panel->wheelBtn, panel->slidersBtn);
402 WMGroupButtons(panel->wheelBtn, panel->customPaletteBtn);
403 WMGroupButtons(panel->wheelBtn, panel->colorListBtn);
405 /* Widgets for the ColorWheel Panel */
406 panel->wheelFrm = WMCreateFrame(panel->win);
407 WMSetFrameRelief(panel->wheelFrm, WRFlat);
408 WMResizeWidget(panel->wheelFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
409 WMMoveWidget(panel->wheelFrm, 5, 80);
411 panel->wheelView = W_CreateView(W_VIEW(panel->wheelFrm));
412 /* XXX Can we create a view ? */
413 W_ResizeView(panel->wheelView, colorWheelSize+4, colorWheelSize+4);
414 W_MoveView(panel->wheelView, 0, 0);
416 /* Create an event handler to handle expose/click events in the ColorWheel */
417 WMCreateEventHandler(panel->wheelView, ButtonPressMask|ButtonReleaseMask|EnterWindowMask
418 |LeaveWindowMask|ButtonMotionMask, wheelHandleActionEvents, panel);
420 WMCreateEventHandler(panel->wheelView, ExposureMask, wheelHandleEvents, panel);
422 panel->wheelBrightnessS = WMCreateSlider(panel->wheelFrm);
423 WMResizeWidget(panel->wheelBrightnessS, 16, 153);
424 WMMoveWidget(panel->wheelBrightnessS, 5+colorWheelSize+14, 1);
425 WMSetSliderMinValue(panel->wheelBrightnessS, 0);
426 WMSetSliderMaxValue(panel->wheelBrightnessS, 255);
427 WMSetSliderAction(panel->wheelBrightnessS, wheelBrightnessSliderCallback, panel);
428 WMSetSliderKnobThickness(panel->wheelBrightnessS, knobThickness);
431 /* Widgets for the Slider Panels */
432 panel->slidersFrm = WMCreateFrame(panel->win);
433 WMSetFrameRelief(panel->slidersFrm, WRFlat);
434 WMResizeWidget(panel->slidersFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
435 WMMoveWidget(panel->slidersFrm, 4, 80);
437 panel->seperatorFrm = WMCreateFrame(panel->slidersFrm);
438 WMSetFrameRelief(panel->seperatorFrm, WRPushed);
439 WMResizeWidget(panel->seperatorFrm, PWIDTH - 8, 2);
440 WMMoveWidget(panel->seperatorFrm, 0, 1);
442 panel->grayBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask);
443 WMResizeWidget(panel->grayBtn, 46, 24);
444 WMMoveWidget(panel->grayBtn, 1, 8);
445 WMSetButtonAction(panel->grayBtn, modeButtonCallback, panel);
446 WMSetButtonImagePosition(panel->grayBtn, WIPImageOnly);
447 WMSetButtonImage(panel->grayBtn, scrPtr->grayIcon);
449 panel->rgbBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask);
450 WMResizeWidget(panel->rgbBtn, 46, 24);
451 WMMoveWidget(panel->rgbBtn, 47, 8);
452 WMSetButtonAction(panel->rgbBtn, modeButtonCallback, panel);
453 WMSetButtonImagePosition(panel->rgbBtn, WIPImageOnly);
454 WMSetButtonImage(panel->rgbBtn, scrPtr->rgbIcon);
456 panel->cmykBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask);
457 WMResizeWidget(panel->cmykBtn, 46, 24);
458 WMMoveWidget(panel->cmykBtn, 93, 8);
459 WMSetButtonAction(panel->cmykBtn, modeButtonCallback, panel);
460 WMSetButtonImagePosition(panel->cmykBtn, WIPImageOnly);
461 WMSetButtonImage(panel->cmykBtn, scrPtr->cmykIcon);
463 panel->hsbBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask);
464 WMResizeWidget(panel->hsbBtn, 46, 24);
465 WMMoveWidget(panel->hsbBtn, 139, 8);
466 WMSetButtonAction(panel->hsbBtn, modeButtonCallback, panel);
467 WMSetButtonImagePosition(panel->hsbBtn, WIPImageOnly);
468 WMSetButtonImage(panel->hsbBtn, scrPtr->hsbIcon);
470 /* Let's Group the Slider Panel Buttons Together */
471 WMGroupButtons(panel->grayBtn, panel->rgbBtn);
472 WMGroupButtons(panel->grayBtn, panel->cmykBtn);
473 WMGroupButtons(panel->grayBtn, panel->hsbBtn);
475 textcolor = WMDarkGrayColor(scrPtr);
477 /* Widgets for GrayScale Panel */
478 panel->grayFrm = WMCreateFrame(panel->slidersFrm);
479 WMSetFrameRelief(panel->grayFrm, WRFlat);
480 WMResizeWidget(panel->grayFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
481 WMMoveWidget(panel->grayFrm, 0, 34);
483 panel->grayMinL = WMCreateLabel(panel->grayFrm);
484 WMResizeWidget(panel->grayMinL, 20, 10);
485 WMMoveWidget(panel->grayMinL, 2, 2);
486 WMSetLabelText(panel->grayMinL, "0");
487 WMSetLabelTextAlignment(panel->grayMinL, WALeft);
488 WMSetLabelTextColor(panel->grayMinL, textcolor);
489 WMSetLabelFont(panel->grayMinL, panel->font8);
491 panel->grayMaxL = WMCreateLabel(panel->grayFrm);
492 WMResizeWidget(panel->grayMaxL, 40, 10);
493 WMMoveWidget(panel->grayMaxL, 104, 2);
494 WMSetLabelText(panel->grayMaxL, "100");
495 WMSetLabelTextAlignment(panel->grayMaxL, WARight);
496 WMSetLabelTextColor(panel->grayMaxL, textcolor);
497 WMSetLabelFont(panel->grayMaxL, panel->font8);
499 panel->grayBrightnessS = WMCreateSlider(panel->grayFrm);
500 WMResizeWidget(panel->grayBrightnessS, 141, 16);
501 WMMoveWidget(panel->grayBrightnessS, 2, 14);
502 WMSetSliderMinValue(panel->grayBrightnessS, 0);
503 WMSetSliderMaxValue(panel->grayBrightnessS, 100);
504 WMSetSliderKnobThickness(panel->grayBrightnessS, knobThickness);
505 WMSetSliderAction(panel->grayBrightnessS, grayBrightnessSliderCallback, panel);
507 from.red = 0;
508 from.green = 0;
509 from.blue = 0;
511 to.red = 255;
512 to.green = 255;
513 to.blue = 255;
515 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
516 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
517 RDestroyImage(image);
518 W_PaintText(W_VIEW(panel->grayBrightnessS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Brightness", strlen("Brightness"));
519 WMSetSliderImage(panel->grayBrightnessS, pixmap);
520 WMReleasePixmap(pixmap);
522 panel->grayBrightnessT = WMCreateTextField(panel->grayFrm);
523 WMResizeWidget(panel->grayBrightnessT, 40, 18);
524 WMMoveWidget(panel->grayBrightnessT, 146, 13);
525 WMSetTextFieldAlignment(panel->grayBrightnessT, WALeft);
526 WMAddNotificationObserver(grayBrightnessTextFieldCallback, panel, \
527 WMTextDidEndEditingNotification, panel->grayBrightnessT);
529 image = RCreateImage(13,13,False);
530 for (i=0; i < 7; i++) {
531 for (x=0; x < 13; x++) {
532 for (y=0; y < 13; y++) {
533 image->data[0][y*13+x] = 255/6*i;
534 image->data[1][y*13+x] = 255/6*i;
535 image->data[2][y*13+x] = 255/6*i;
538 panel->grayPresetBtn[i] = WMCreateCommandButton(panel->grayFrm);
539 WMResizeWidget(panel->grayPresetBtn[i], 20, 24);
540 WMMoveWidget(panel->grayPresetBtn[i], 2+(i*20), 34);
541 WMSetButtonAction(panel->grayPresetBtn[i], grayPresetButtonCallback, panel);
542 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
543 WMSetButtonImage(panel->grayPresetBtn[i], pixmap);
544 WMSetButtonImagePosition(panel->grayPresetBtn[i], WIPImageOnly);
545 WMReleasePixmap(pixmap);
547 RDestroyImage(image);
548 /* End of GrayScale Panel */
550 /* Widgets for RGB Panel */
551 panel->rgbFrm = WMCreateFrame(panel->slidersFrm);
552 WMSetFrameRelief(panel->rgbFrm, WRFlat);
553 WMResizeWidget(panel->rgbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
554 WMMoveWidget(panel->rgbFrm, 0, 34);
556 panel->rgbMinL = WMCreateLabel(panel->rgbFrm);
557 WMResizeWidget(panel->rgbMinL, 20, 10);
558 WMMoveWidget(panel->rgbMinL, 2, 2);
559 WMSetLabelText(panel->rgbMinL, "0");
560 WMSetLabelTextAlignment(panel->rgbMinL, WALeft);
561 WMSetLabelTextColor(panel->rgbMinL, textcolor);
562 WMSetLabelFont(panel->rgbMinL, panel->font8);
564 panel->rgbMaxL = WMCreateLabel(panel->rgbFrm);
565 WMResizeWidget(panel->rgbMaxL, 40, 10);
566 WMMoveWidget(panel->rgbMaxL, 104, 2);
567 WMSetLabelText(panel->rgbMaxL, "255");
568 WMSetLabelTextAlignment(panel->rgbMaxL, WARight);
569 WMSetLabelTextColor(panel->rgbMaxL, textcolor);
570 WMSetLabelFont(panel->rgbMaxL, panel->font8);
572 panel->rgbRedS = WMCreateSlider(panel->rgbFrm);
573 WMResizeWidget(panel->rgbRedS, 141, 16);
574 WMMoveWidget(panel->rgbRedS, 2, 14);
575 WMSetSliderMinValue(panel->rgbRedS, 0);
576 WMSetSliderMaxValue(panel->rgbRedS, 255);
577 WMSetSliderKnobThickness(panel->rgbRedS, knobThickness);
578 WMSetSliderAction(panel->rgbRedS, rgbSliderCallback, panel);
580 to.red = 255;
581 to.green = 0;
582 to.blue = 0;
584 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
585 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
586 W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Red", strlen("Red"));
587 RDestroyImage(image);
588 WMSetSliderImage(panel->rgbRedS, pixmap);
589 WMReleasePixmap(pixmap);
591 panel->rgbRedT = WMCreateTextField(panel->rgbFrm);
592 WMResizeWidget(panel->rgbRedT, 40, 18);
593 WMMoveWidget(panel->rgbRedT, 146, 13);
594 WMSetTextFieldAlignment(panel->rgbRedT, WALeft);
595 WMAddNotificationObserver(rgbTextFieldCallback, panel,
596 WMTextDidEndEditingNotification,
597 panel->rgbRedT);
600 panel->rgbGreenS = WMCreateSlider(panel->rgbFrm);
601 WMResizeWidget(panel->rgbGreenS, 141, 16);
602 WMMoveWidget(panel->rgbGreenS, 2, 36);
603 WMSetSliderMinValue(panel->rgbGreenS, 0);
604 WMSetSliderMaxValue(panel->rgbGreenS, 255);
605 WMSetSliderKnobThickness(panel->rgbGreenS, knobThickness);
606 WMSetSliderAction(panel->rgbGreenS, rgbSliderCallback, panel);
608 to.red = 0;
609 to.green = 255;
610 to.blue = 0;
612 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
613 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
614 W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Green", strlen("Green"));
615 RDestroyImage(image);
616 WMSetSliderImage(panel->rgbGreenS, pixmap);
617 WMReleasePixmap(pixmap);
619 panel->rgbGreenT = WMCreateTextField(panel->rgbFrm);
620 WMResizeWidget(panel->rgbGreenT, 40, 18);
621 WMMoveWidget(panel->rgbGreenT, 146, 35);
622 WMSetTextFieldAlignment(panel->rgbGreenT, WALeft);
623 WMAddNotificationObserver(rgbTextFieldCallback, panel,
624 WMTextDidEndEditingNotification,
625 panel->rgbGreenT);
628 panel->rgbBlueS = WMCreateSlider(panel->rgbFrm);
629 WMResizeWidget(panel->rgbBlueS, 141, 16);
630 WMMoveWidget(panel->rgbBlueS, 2, 58);
631 WMSetSliderMinValue(panel->rgbBlueS, 0);
632 WMSetSliderMaxValue(panel->rgbBlueS, 255);
633 WMSetSliderKnobThickness(panel->rgbBlueS, knobThickness);
634 WMSetSliderAction(panel->rgbBlueS, rgbSliderCallback, panel);
636 to.red = 0;
637 to.green = 0;
638 to.blue = 255;
640 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
641 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
642 W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Blue", strlen("Blue"));
643 RDestroyImage(image);
644 WMSetSliderImage(panel->rgbBlueS, pixmap);
645 WMReleasePixmap(pixmap);
647 panel->rgbBlueT = WMCreateTextField(panel->rgbFrm);
648 WMResizeWidget(panel->rgbBlueT, 40, 18);
649 WMMoveWidget(panel->rgbBlueT, 146, 57);
650 WMSetTextFieldAlignment(panel->rgbBlueT, WALeft);
651 WMAddNotificationObserver(rgbTextFieldCallback, panel,
652 WMTextDidEndEditingNotification,
653 panel->rgbBlueT);
654 /* End of RGB Panel */
656 /* Widgets for CMYK Panel */
657 panel->cmykFrm = WMCreateFrame(panel->slidersFrm);
658 WMSetFrameRelief(panel->cmykFrm, WRFlat);
659 WMResizeWidget(panel->cmykFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
660 WMMoveWidget(panel->cmykFrm, 0, 34);
662 panel->cmykMinL = WMCreateLabel(panel->cmykFrm);
663 WMResizeWidget(panel->cmykMinL, 20, 10);
664 WMMoveWidget(panel->cmykMinL, 2, 2);
665 WMSetLabelText(panel->cmykMinL, "0");
666 WMSetLabelTextAlignment(panel->cmykMinL, WALeft);
667 WMSetLabelTextColor(panel->cmykMinL, textcolor);
668 WMSetLabelFont(panel->cmykMinL, panel->font8);
670 panel->cmykMaxL = WMCreateLabel(panel->cmykFrm);
671 WMResizeWidget(panel->cmykMaxL, 40, 10);
672 WMMoveWidget(panel->cmykMaxL, 104, 2);
673 WMSetLabelText(panel->cmykMaxL, "100");
674 WMSetLabelTextAlignment(panel->cmykMaxL, WARight);
675 WMSetLabelTextColor(panel->cmykMaxL, textcolor);
676 WMSetLabelFont(panel->cmykMaxL, panel->font8);
678 panel->cmykCyanS = WMCreateSlider(panel->cmykFrm);
679 WMResizeWidget(panel->cmykCyanS, 141, 16);
680 WMMoveWidget(panel->cmykCyanS, 2, 14);
681 WMSetSliderMinValue(panel->cmykCyanS, 0);
682 WMSetSliderMaxValue(panel->cmykCyanS, 100);
683 WMSetSliderKnobThickness(panel->cmykCyanS, knobThickness);
684 WMSetSliderAction(panel->cmykCyanS, cmykSliderCallback, panel);
686 from.red = 255;
687 from.green = 255;
688 from.blue = 255;
690 to.red = 0;
691 to.green = 255;
692 to.blue = 255;
694 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
695 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
696 W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Cyan", strlen("Cyan"));
697 RDestroyImage(image);
698 WMSetSliderImage(panel->cmykCyanS, pixmap);
699 WMReleasePixmap(pixmap);
701 panel->cmykCyanT = WMCreateTextField(panel->cmykFrm);
702 WMResizeWidget(panel->cmykCyanT, 40, 18);
703 WMMoveWidget(panel->cmykCyanT, 146, 13);
704 WMSetTextFieldAlignment(panel->cmykCyanT, WALeft);
705 WMAddNotificationObserver(cmykTextFieldCallback, panel,
706 WMTextDidEndEditingNotification,
707 panel->cmykCyanT);
709 panel->cmykMagentaS = WMCreateSlider(panel->cmykFrm);
710 WMResizeWidget(panel->cmykMagentaS, 141, 16);
711 WMMoveWidget(panel->cmykMagentaS, 2, 36);
712 WMSetSliderMinValue(panel->cmykMagentaS, 0);
713 WMSetSliderMaxValue(panel->cmykMagentaS, 100);
714 WMSetSliderKnobThickness(panel->cmykMagentaS, knobThickness);
715 WMSetSliderAction(panel->cmykMagentaS, cmykSliderCallback, panel);
717 to.red = 255;
718 to.green = 0;
719 to.blue = 255;
721 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
722 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
723 W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Magenta", strlen("Magenta"));
724 RDestroyImage(image);
725 WMSetSliderImage(panel->cmykMagentaS, pixmap);
726 WMReleasePixmap(pixmap);
728 panel->cmykMagentaT = WMCreateTextField(panel->cmykFrm);
729 WMResizeWidget(panel->cmykMagentaT, 40, 18);
730 WMMoveWidget(panel->cmykMagentaT, 146, 35);
731 WMSetTextFieldAlignment(panel->cmykMagentaT, WALeft);
732 WMAddNotificationObserver(cmykTextFieldCallback, panel,
733 WMTextDidEndEditingNotification,
734 panel->cmykMagentaT);
737 panel->cmykYellowS = WMCreateSlider(panel->cmykFrm);
738 WMResizeWidget(panel->cmykYellowS, 141, 16);
739 WMMoveWidget(panel->cmykYellowS, 2, 58);
740 WMSetSliderMinValue(panel->cmykYellowS, 0);
741 WMSetSliderMaxValue(panel->cmykYellowS, 100);
742 WMSetSliderKnobThickness(panel->cmykYellowS, knobThickness);
743 WMSetSliderAction(panel->cmykYellowS, cmykSliderCallback, panel);
745 to.red = 255;
746 to.green = 255;
747 to.blue = 0;
749 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
750 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
751 W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Yellow", strlen("Yellow"));
752 RDestroyImage(image);
753 WMSetSliderImage(panel->cmykYellowS, pixmap);
754 WMReleasePixmap(pixmap);
756 panel->cmykYellowT = WMCreateTextField(panel->cmykFrm);
757 WMResizeWidget(panel->cmykYellowT, 40, 18);
758 WMMoveWidget(panel->cmykYellowT, 146, 57);
759 WMSetTextFieldAlignment(panel->cmykYellowT, WALeft);
760 WMAddNotificationObserver(cmykTextFieldCallback, panel,
761 WMTextDidEndEditingNotification,
762 panel->cmykYellowT);
764 panel->cmykBlackS = WMCreateSlider(panel->cmykFrm);
765 WMResizeWidget(panel->cmykBlackS, 141, 16);
766 WMMoveWidget(panel->cmykBlackS, 2, 80);
767 WMSetSliderMinValue(panel->cmykBlackS, 0);
768 WMSetSliderMaxValue(panel->cmykBlackS, 100);
769 WMSetSliderValue(panel->cmykBlackS, 0);
770 WMSetSliderKnobThickness(panel->cmykBlackS, knobThickness);
771 WMSetSliderAction(panel->cmykBlackS, cmykSliderCallback, panel);
773 to.red = 0;
774 to.green = 0;
775 to.blue = 0;
777 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
778 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
779 W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Black", strlen("Black"));
780 RDestroyImage(image);
781 WMSetSliderImage(panel->cmykBlackS, pixmap);
782 WMReleasePixmap(pixmap);
784 panel->cmykBlackT = WMCreateTextField(panel->cmykFrm);
785 WMResizeWidget(panel->cmykBlackT, 40, 18);
786 WMMoveWidget(panel->cmykBlackT, 146, 79);
787 WMSetTextFieldAlignment(panel->cmykBlackT, WALeft);
788 WMAddNotificationObserver(cmykTextFieldCallback, panel,
789 WMTextDidEndEditingNotification,
790 panel->cmykBlackT);
791 /* End of CMYK Panel */
793 /* Widgets for HSB Panel */
794 panel->hsbFrm = WMCreateFrame(panel->slidersFrm);
795 WMSetFrameRelief(panel->hsbFrm, WRFlat);
796 WMResizeWidget(panel->hsbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
797 WMMoveWidget(panel->hsbFrm, 0, 34);
799 panel->hsbHueS = WMCreateSlider(panel->hsbFrm);
800 WMResizeWidget(panel->hsbHueS, 141, 16);
801 WMMoveWidget(panel->hsbHueS, 2, 14);
802 WMSetSliderMinValue(panel->hsbHueS, 0);
803 WMSetSliderMaxValue(panel->hsbHueS, 359);
804 WMSetSliderKnobThickness(panel->hsbHueS, knobThickness);
805 WMSetSliderAction(panel->hsbHueS, hsbSliderCallback, panel);
807 panel->hsbHueT = WMCreateTextField(panel->hsbFrm);
808 WMResizeWidget(panel->hsbHueT, 40, 18);
809 WMMoveWidget(panel->hsbHueT, 146, 13);
810 WMSetTextFieldAlignment(panel->hsbHueT, WALeft);
811 WMAddNotificationObserver(hsbTextFieldCallback, panel,
812 WMTextDidEndEditingNotification,
813 panel->hsbHueT);
815 panel->hsbSaturationS = WMCreateSlider(panel->hsbFrm);
816 WMResizeWidget(panel->hsbSaturationS, 141, 16);
817 WMMoveWidget(panel->hsbSaturationS, 2, 36);
818 WMSetSliderMinValue(panel->hsbSaturationS, 0);
819 WMSetSliderMaxValue(panel->hsbSaturationS, 100);
820 WMSetSliderKnobThickness(panel->hsbSaturationS, knobThickness);
821 WMSetSliderAction(panel->hsbSaturationS, hsbSliderCallback, panel);
823 panel->hsbSaturationT = WMCreateTextField(panel->hsbFrm);
824 WMResizeWidget(panel->hsbSaturationT, 40, 18);
825 WMMoveWidget(panel->hsbSaturationT, 146, 35);
826 WMSetTextFieldAlignment(panel->hsbSaturationT, WALeft);
827 WMAddNotificationObserver(hsbTextFieldCallback, panel,
828 WMTextDidEndEditingNotification,
829 panel->hsbSaturationT);
831 panel->hsbBrightnessS = WMCreateSlider(panel->hsbFrm);
832 WMResizeWidget(panel->hsbBrightnessS, 141, 16);
833 WMMoveWidget(panel->hsbBrightnessS, 2, 58);
834 WMSetSliderMinValue(panel->hsbBrightnessS, 0);
835 WMSetSliderMaxValue(panel->hsbBrightnessS, 100);
836 WMSetSliderKnobThickness(panel->hsbBrightnessS, knobThickness);
837 WMSetSliderAction(panel->hsbBrightnessS, hsbSliderCallback, panel);
839 panel->hsbBrightnessT = WMCreateTextField(panel->hsbFrm);
840 WMResizeWidget(panel->hsbBrightnessT, 40, 18);
841 WMMoveWidget(panel->hsbBrightnessT, 146, 57);
842 WMSetTextFieldAlignment(panel->hsbBrightnessT, WALeft);
843 WMAddNotificationObserver(hsbTextFieldCallback, panel,
844 WMTextDidEndEditingNotification,
845 panel->hsbBrightnessT);
846 /* End of HSB Panel */
849 WMReleaseColor(textcolor);
851 /* Widgets for the CustomPalette Panel */
852 panel->customPaletteFrm = WMCreateFrame(panel->win);
853 WMSetFrameRelief(panel->customPaletteFrm, WRFlat);
854 WMResizeWidget(panel->customPaletteFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
855 WMMoveWidget(panel->customPaletteFrm, 5, 80);
857 panel->customPaletteHistoryBtn = WMCreatePopUpButton(panel->customPaletteFrm);
858 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, "Spectrum");
859 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn)-1);
860 WMSetPopUpButtonAction(panel->customPaletteHistoryBtn, customPaletteHistoryCallback, panel);
861 WMResizeWidget(panel->customPaletteHistoryBtn, PWIDTH - 8, 20);
862 WMMoveWidget(panel->customPaletteHistoryBtn, 0, 0);
864 panel->customPaletteContentFrm = WMCreateFrame(panel->customPaletteFrm);
865 WMSetFrameRelief(panel->customPaletteContentFrm, WRSunken);
866 WMResizeWidget(panel->customPaletteContentFrm, PWIDTH - 8, PHEIGHT - 156);
867 WMMoveWidget(panel->customPaletteContentFrm, 0, 23);
869 panel->customPaletteContentView = W_CreateView(W_VIEW(panel->customPaletteContentFrm));
870 /* XXX Can we create a view ? */
871 W_ResizeView(panel->customPaletteContentView, customPaletteWidth, customPaletteHeight);
872 W_MoveView(panel->customPaletteContentView, 2, 2);
874 /* Create an event handler to handle expose/click events in the CustomPalette */
875 WMCreateEventHandler(panel->customPaletteContentView, ButtonPressMask|ButtonReleaseMask|EnterWindowMask
876 |LeaveWindowMask|ButtonMotionMask, customPaletteHandleActionEvents, panel);
878 WMCreateEventHandler(panel->customPaletteContentView, ExposureMask, customPaletteHandleEvents, panel);
880 panel->customPaletteMenuBtn = WMCreatePopUpButton(panel->customPaletteFrm);
881 WMSetPopUpButtonPullsDown(panel->customPaletteMenuBtn, 1);
882 WMSetPopUpButtonText(panel->customPaletteMenuBtn, "Palette");
883 WMSetPopUpButtonAction(panel->customPaletteMenuBtn, customPaletteMenuCallback, panel);
884 WMResizeWidget(panel->customPaletteMenuBtn, PWIDTH - 8, 20);
885 WMMoveWidget(panel->customPaletteMenuBtn, 0, PHEIGHT - 130);
887 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from File...");
888 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Rename...");
889 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Remove");
890 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Copy");
891 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from Clipboard");
893 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, 0);
894 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, 0);
895 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuCopy, 0);
896 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuNewFromClipboard, 0);
898 customRenderSpectrum(panel);
899 panel->currentPalette = 0;
902 /* Widgets for the ColorList Panel */
903 panel->colorListFrm = WMCreateFrame(panel->win);
904 WMSetFrameRelief(panel->colorListFrm, WRFlat);
905 WMResizeWidget(panel->colorListFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
906 WMMoveWidget(panel->colorListFrm, 5, 80);
908 panel->colorListHistoryBtn = WMCreatePopUpButton(panel->colorListFrm);
909 WMAddPopUpButtonItem(panel->colorListHistoryBtn, "X11-Colors");
910 WMSetPopUpButtonSelectedItem(panel->colorListHistoryBtn, WMGetPopUpButtonNumberOfItems(panel->colorListHistoryBtn)-1);
911 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn, colorListHistoryCallback, panel); */
912 WMResizeWidget(panel->colorListHistoryBtn, PWIDTH - 8, 20);
913 WMMoveWidget(panel->colorListHistoryBtn, 0, 0);
915 panel->colorListContentLst = WMCreateList(panel->colorListFrm);
916 WMSetListAction(panel->colorListContentLst, colorListSelect, panel);
917 WMSetListUserDrawProc(panel->colorListContentLst, colorListPaintItem);
918 WMResizeWidget(panel->colorListContentLst, PWIDTH - 8, PHEIGHT - 156);
919 WMMoveWidget(panel->colorListContentLst, 0, 23);
920 WMHangData(panel->colorListContentLst, panel);
922 panel->colorListColorMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
923 WMSetPopUpButtonPullsDown(panel->colorListColorMenuBtn, 1);
924 WMSetPopUpButtonText(panel->colorListColorMenuBtn, "Color");
925 WMSetPopUpButtonAction(panel->colorListColorMenuBtn, colorListColorMenuCallback, panel);
926 WMResizeWidget(panel->colorListColorMenuBtn, (PWIDTH - 16)/2, 20);
927 WMMoveWidget(panel->colorListColorMenuBtn, 0, PHEIGHT - 130);
929 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Add...");
930 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Rename...");
931 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Remove");
933 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuAdd, 0);
934 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRename, 0);
935 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRemove, 0);
937 panel->colorListListMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
938 WMSetPopUpButtonPullsDown(panel->colorListListMenuBtn, 1);
939 WMSetPopUpButtonText(panel->colorListListMenuBtn, "List");
940 WMSetPopUpButtonAction(panel->colorListListMenuBtn, colorListListMenuCallback, panel);
941 WMResizeWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2, 20);
942 WMMoveWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2 + 8, PHEIGHT - 130);
944 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "New...");
945 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Rename...");
946 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Remove");
948 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRename, 0);
949 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRemove, 0);
951 WMRealizeWidget(panel->win);
952 WMMapSubwidgets(panel->win);
954 WMMapSubwidgets(panel->wheelFrm);
955 WMMapSubwidgets(panel->slidersFrm);
956 WMMapSubwidgets(panel->grayFrm);
957 WMMapSubwidgets(panel->rgbFrm);
958 WMMapSubwidgets(panel->cmykFrm);
959 WMMapSubwidgets(panel->hsbFrm);
960 WMMapSubwidgets(panel->customPaletteFrm);
961 WMMapSubwidgets(panel->customPaletteContentFrm);
962 WMMapSubwidgets(panel->colorListFrm);
964 readConfiguration(panel);
965 readXColors(panel);
967 return panel;
971 WMColorPanel*
972 WMGetColorPanel(WMScreen *scrPtr)
974 WMColorPanel *panel;
976 if (scrPtr->sharedColorPanel)
977 return scrPtr->sharedColorPanel;
979 panel = makeColorPanel(scrPtr, "colorPanel");
981 scrPtr->sharedColorPanel = panel;
983 return panel;
987 void
988 WMFreeColorPanel(WMColorPanel *panel)
990 W_Screen *scr = WMWidgetScreen(panel->win);
992 if (panel == scr->sharedColorPanel) {
993 WMWidgetScreen(panel->win)->sharedColorPanel = NULL;
995 WMRemoveNotificationObserver(panel);
996 WMUnmapWidget(panel->win);
997 WMDestroyWidget(panel->win);
998 if (panel->font8)
999 WMReleaseFont(panel->font8);
1000 if (panel->font12)
1001 WMReleaseFont(panel->font12);
1002 if (panel->magnifyGlass->pixmap)
1003 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1004 if (panel->wheelMtrx)
1005 wheelDestroyMatrix(panel->wheelMtrx);
1006 if (panel->wheelImg)
1007 XFreePixmap(scr->display, panel->wheelImg);
1008 if (panel->selectionImg)
1009 XFreePixmap(scr->display, panel->selectionImg);
1010 if (panel->selectionBackImg)
1011 XFreePixmap(scr->display, panel->selectionBackImg);
1012 if (panel->customPaletteImg)
1013 RDestroyImage(panel->customPaletteImg);
1014 if (panel->lastBrowseDir)
1015 free(panel->lastBrowseDir);
1016 if (panel->configurationPath)
1017 free(panel->configurationPath);
1019 free(panel);
1023 void
1024 WMCloseColorPanel(WMColorPanel *panel)
1026 WMCloseWindow(panel->win);
1030 void
1031 WMShowColorPanel(WMColorPanel *panel)
1033 WMScreen *scr = WMWidgetScreen(panel->win);
1034 XEvent event;
1035 RHSVColor hsvcolor;
1036 GC bgc = WMColorGC(scr->black);
1037 GC wgc = WMColorGC(scr->white);
1038 RColor color;
1040 panel->wheelMtrx = wheelInitMatrix(panel); /* Needs to be done After Color is set */
1044 /* Maybe put this in sub-function ... Initialising selection images */
1045 RRGBtoHSV(&color, &hsvcolor);
1046 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 + (hsvcolor.saturation/255.0) * cos( hsvcolor.hue*M_PI/180.0)));
1047 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 + (hsvcolor.saturation/255.0) * sin(-hsvcolor.hue*M_PI/180.0)));
1048 wheelUpdateBrightnessGradientFromHSV(panel, hsvcolor);
1049 WMSetSliderValue(panel->wheelBrightnessS, 255 - hsvcolor.value);
1051 panel->selectionImg = XCreatePixmap(scr->display, W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
1052 XFillRectangle(scr->display, panel->selectionImg, bgc, 0, 0, 4, 4);
1053 XFillRectangle(scr->display, panel->selectionImg, wgc, 1, 1, 2, 2);
1054 /* End of initialisation section */
1056 panel->palx = customPaletteWidth/2;
1057 panel->paly = customPaletteHeight/2;
1059 WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel);
1061 WMMapWidget(panel->win);
1065 static void
1066 closeWindowCallback(WMWidget *w, void *data)
1068 W_ColorPanel *panel = (W_ColorPanel*)data;
1070 WMCloseWindow(panel->win);
1074 static void
1075 readConfiguration(W_ColorPanel *panel)
1077 /* XXX Doesn't take care of "invalid" files */
1079 DIR *dPtr;
1080 struct dirent *dp;
1081 struct stat stat_buf;
1084 if (stat(panel->configurationPath, &stat_buf)!=0) {
1085 if (mkdir(panel->configurationPath, S_IRWXU|S_IRGRP|S_IROTH|S_IXGRP|S_IXOTH)!=0) {
1086 wsyserror("ColorPanel could not create directory %s needed to store configurations", panel->configurationPath);
1087 WMSetPopUpButtonEnabled(panel->customPaletteMenuBtn, False);
1088 WMSetPopUpButtonEnabled(panel->colorListColorMenuBtn, False);
1089 WMSetPopUpButtonEnabled(panel->colorListListMenuBtn, False);
1090 WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win, "File Error", "Could not create ColorPanel configuration directory", "OK", NULL, NULL);
1092 return;
1095 dPtr = opendir(panel->configurationPath);
1096 while ((dp = readdir(dPtr)) != NULL) {
1097 if (dp->d_name[0] != '.')
1098 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, dp->d_name);
1100 (void)closedir(dPtr);
1104 static void
1105 readXColors(W_ColorPanel *panel)
1107 struct stat stat_buf;
1108 FILE *rgbtxt;
1109 char line[MAX_LENGTH];
1110 int red, green, blue;
1111 char name[48];
1112 RColor *color;
1113 WMListItem *item;
1115 if (stat(RGBTXT, &stat_buf) != 0) {
1116 wwarning("Cannot find file %s", RGBTXT);
1117 return;
1119 else {
1120 rgbtxt = fopen(RGBTXT, "r");
1121 if (rgbtxt) {
1122 while (fgets(line, MAX_LENGTH, rgbtxt)) {
1123 if (sscanf(line, "%d%d%d %[^\n]", &red, &green, &blue, name)) {
1124 color = wmalloc(sizeof(RColor));
1125 color->red = (unsigned char)red;
1126 color->green = (unsigned char)green;
1127 color->blue = (unsigned char)blue;
1128 item = WMAddListItem(panel->colorListContentLst, name);
1129 item->clientData = (void *)color;
1132 fclose(rgbtxt);
1134 else {
1135 wsyserror("Unable to open file %s for reading", RGBTXT);
1141 void
1142 WMSetColorPanelPickerMode(WMColorPanel *panel, WMColorPanelMode mode)
1144 W_Screen *scr = WMWidgetScreen(panel->win);
1146 if (mode != WMWheelModeColorPanel) {
1147 WMUnmapWidget(panel->wheelFrm);
1148 if (panel->selectionBackImg) {
1149 XFreePixmap(WMWidgetScreen(panel->win)->display, panel->selectionBackImg);
1150 panel->selectionBackImg = None;
1153 if (mode != WMGrayModeColorPanel)
1154 WMUnmapWidget(panel->grayFrm);
1155 if (mode != WMRGBModeColorPanel)
1156 WMUnmapWidget(panel->rgbFrm);
1157 if (mode != WMCMYKModeColorPanel)
1158 WMUnmapWidget(panel->cmykFrm);
1159 if (mode != WMHSBModeColorPanel)
1160 WMUnmapWidget(panel->hsbFrm);
1161 if (mode != WMCustomPaletteModeColorPanel) {
1162 WMUnmapWidget(panel->customPaletteFrm);
1163 if (panel->selectionBackImg) {
1164 XFreePixmap(WMWidgetScreen(panel->win)->display, panel->selectionBackImg);
1165 panel->selectionBackImg = None;
1168 if (mode != WMColorListModeColorPanel)
1169 WMUnmapWidget(panel->colorListFrm);
1170 if ((mode != WMGrayModeColorPanel) && (mode != WMRGBModeColorPanel) && \
1171 (mode != WMCMYKModeColorPanel) && (mode != WMHSBModeColorPanel))
1172 WMUnmapWidget(panel->slidersFrm);
1173 else
1174 panel->slidersmode = mode;
1176 if (mode == WMWheelModeColorPanel) {
1177 WMMapWidget(panel->wheelFrm);
1178 WMSetButtonSelected(panel->wheelBtn, True);
1179 if (panel->lastChanged != WMWheelModeColorPanel)
1180 wheelInit(panel);
1181 wheelRender(panel);
1182 wheelPaint(panel);
1183 } else if (mode == WMGrayModeColorPanel) {
1184 WMMapWidget(panel->slidersFrm);
1185 WMSetButtonSelected(panel->slidersBtn, True);
1186 WMMapWidget(panel->grayFrm);
1187 WMSetButtonSelected(panel->grayBtn, True);
1188 WMSetButtonImage(panel->slidersBtn, scr->grayIcon);
1189 if (panel->lastChanged != WMGrayModeColorPanel)
1190 grayInit(panel);
1191 } else if (mode == WMRGBModeColorPanel) {
1192 WMMapWidget(panel->slidersFrm);
1193 WMSetButtonSelected(panel->slidersBtn, True);
1194 WMMapWidget(panel->rgbFrm);
1195 WMSetButtonSelected(panel->rgbBtn, True);
1196 WMSetButtonImage(panel->slidersBtn, scr->rgbIcon);
1197 if (panel->lastChanged != WMRGBModeColorPanel)
1198 rgbInit(panel);
1199 } else if (mode == WMCMYKModeColorPanel) {
1200 WMMapWidget(panel->slidersFrm);
1201 WMSetButtonSelected(panel->slidersBtn, True);
1202 WMMapWidget(panel->cmykFrm);
1203 WMSetButtonSelected(panel->cmykBtn, True);
1204 WMSetButtonImage(panel->slidersBtn, scr->cmykIcon);
1205 if (panel->lastChanged != WMCMYKModeColorPanel)
1206 cmykInit(panel);
1207 } else if (mode == WMHSBModeColorPanel) {
1208 WMMapWidget(panel->slidersFrm);
1209 WMSetButtonSelected(panel->slidersBtn, True);
1210 WMMapWidget(panel->hsbFrm);
1211 WMSetButtonSelected(panel->hsbBtn, True);
1212 WMSetButtonImage(panel->slidersBtn, scr->hsbIcon);
1213 if (panel->lastChanged != WMHSBModeColorPanel)
1214 hsbInit(panel);
1215 } else if (mode == WMCustomPaletteModeColorPanel) {
1216 WMMapWidget(panel->customPaletteFrm);
1217 WMSetButtonSelected(panel->customPaletteBtn, True);
1218 customSetPalette(panel);
1219 } else if (mode == WMColorListModeColorPanel) {
1220 WMMapWidget(panel->colorListFrm);
1221 WMSetButtonSelected(panel->colorListBtn, True);
1225 panel->mode = mode;
1229 void
1230 WMSetColorPanelColor(WMColorPanel *panel, RColor color)
1232 return;
1236 static void
1237 updateSwatch(WMColorPanel *panel, RColor color)
1239 WMSetColorPanelColor(panel, color);
1240 if (panel->action && (!panel->flags.dragging || panel->flags.continuous)) {
1241 (*panel->action)(panel, panel->clientData);
1246 static void
1247 modeButtonCallback(WMWidget *w, void *data)
1249 W_ColorPanel *panel = (W_ColorPanel*)(data);
1251 if (w == panel->wheelBtn)
1252 WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel);
1253 else if (w == panel->slidersBtn)
1254 WMSetColorPanelPickerMode(panel, panel->slidersmode);
1255 else if (w == panel->customPaletteBtn)
1256 WMSetColorPanelPickerMode(panel, WMCustomPaletteModeColorPanel);
1257 else if (w == panel->colorListBtn)
1258 WMSetColorPanelPickerMode(panel, WMColorListModeColorPanel);
1259 else if (w == panel->grayBtn)
1260 WMSetColorPanelPickerMode(panel, WMGrayModeColorPanel);
1261 else if (w == panel->rgbBtn)
1262 WMSetColorPanelPickerMode(panel, WMRGBModeColorPanel);
1263 else if (w == panel->cmykBtn)
1264 WMSetColorPanelPickerMode(panel, WMCMYKModeColorPanel);
1265 else if (w == panel->hsbBtn)
1266 WMSetColorPanelPickerMode(panel, WMHSBModeColorPanel);
1270 /****************** Magnifying Cursor Functions *******************/
1271 static Pixmap
1272 magnifyGetImage(WMScreen *scr, int x, int y)
1274 XImage *image;
1275 Pixmap pixmap;
1276 int x0, y0, w0, h0;
1277 int displayWidth = DisplayWidth(scr->display, scr->screen);
1278 int displayHeight = DisplayHeight(scr->display, scr->screen);
1279 const int half_mask_width = (Cursor_mask_width +1)/2;
1280 const int half_mask_height = (Cursor_mask_height +1)/2;
1282 /* Coordinate correction for back pixmap */
1283 x0 = 0; y0 = 0; w0 = Cursor_mask_width; h0 = Cursor_mask_height;
1285 if (x < half_mask_width) {
1286 if (x < 0) x = 0;
1287 x0 = half_mask_width - x;
1288 w0 = Cursor_mask_width - x0;
1291 if (x > displayWidth - half_mask_width) {
1292 if (x > displayWidth) x = displayWidth;
1293 w0 = Cursor_mask_width - (half_mask_width - (displayWidth - x));
1296 if (y < half_mask_height) {
1297 if (y < 0) y = 0;
1298 y0 = half_mask_height - y;
1299 h0 = Cursor_mask_height - y0;
1302 if (y > displayHeight - half_mask_height) {
1303 if (y > displayHeight) y = displayHeight;
1304 h0 = Cursor_mask_height - (half_mask_height - (displayHeight - y));
1307 image = XGetImage(scr->display, scr->rootWin, x + x0 - Cursor_x_hot,
1308 y + y0 - Cursor_y_hot, w0, h0, AllPlanes, ZPixmap);
1310 pixmap = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1311 Cursor_mask_height, scr->depth);
1312 XPutImage(scr->display, pixmap, scr->copyGC, image, 0, 0, x0, y0, w0, h0);
1314 return pixmap;
1318 static Pixmap
1319 magnifyGetStorePixmap(WMColorPanel *panel, int x1, int y1, int x2, int y2)
1322 * (x1, y1) = topleft corner of existing rectangle
1323 * (x2, y2) = topleft corner of new position
1326 W_Screen *scr = WMWidgetScreen(panel->win);
1327 Pixmap pixmap;
1328 int xa, ya, xb, yb, w, h;
1330 if (x1 < x2) {
1331 xa = x2 - x1;
1332 xb = 0;
1333 } else {
1334 xa = 0;
1335 xb = x1 - x2;
1338 if (y1 < y2) {
1339 ya = y2 - y1;
1340 yb = 0;
1341 } else {
1342 ya = 0;
1343 yb = y1 - y2;
1346 w = Cursor_mask_width - abs(x1-x2);
1347 h = Cursor_mask_height - abs(y1-y2);
1349 /* Get pixmap from screen */
1350 pixmap = magnifyGetImage(scr, x2, y2);
1352 /* Copy previously stored pixmap on covered part of above pixmap */
1353 if (panel->magnifyGlass->valid)
1355 XCopyArea(scr->display, panel->magnifyGlass->pixmap, pixmap,
1356 scr->copyGC, xa, ya, w, h, xb, yb);
1358 /* Free it, so we can reuse it */
1359 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1362 return pixmap;
1366 static Pixmap
1367 magnifyCreatePixmap(WMColorPanel *panel)
1369 W_Screen *scr = WMWidgetScreen(panel->win);
1370 int u, v;
1371 int i, j;
1372 int ofs;
1373 Pixmap magPix;
1374 Pixmap backPix;
1375 RImage *pixelImg;
1376 const int half_mask_width = Cursor_mask_width/2;
1377 const int half_mask_height = Cursor_mask_height/2;
1381 * Get image
1384 /* Rectangle that's going to be the background */
1385 backPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1386 Cursor_mask_height , scr->depth);
1387 XCopyArea(scr->display, panel->magnifyGlass->pixmap, backPix, scr->copyGC,
1388 0, 0, Cursor_mask_width, Cursor_mask_height, 0, 0);
1391 * Magnify image
1394 magPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width +2,
1395 Cursor_mask_height +2, scr->depth);
1397 for (u=0; u<5+1; u++) /* Copy an area of 5x5 pixels from the center */
1398 for (v=0; v<5+1; v++)
1399 for (i=u*5; i < (u+1)*5; i++) /* magnify it 5 times */
1400 for (j=v*5; j < (v+1)*5; j++)
1401 XCopyArea(scr->display, backPix, magPix, scr->copyGC, u +9, v +9, 1, 1, i, j);
1403 /* Get color under hotspot */
1404 ofs = half_mask_width + half_mask_height * Cursor_mask_width;
1405 pixelImg = RCreateImageFromDrawable(scr->rcontext, backPix, backPix);
1406 panel->magnifyGlass->color.red = pixelImg->data[0][ofs];
1407 panel->magnifyGlass->color.green = pixelImg->data[1][ofs];
1408 panel->magnifyGlass->color.blue = pixelImg->data[2][ofs];
1409 RDestroyImage(pixelImg);
1411 /* Copy the magnified pixmap, with the clip mask, to the background pixmap */
1412 XSetClipMask(scr->display, scr->clipGC, panel->magnifyGlass->mask);
1413 XSetClipOrigin(scr->display, scr->clipGC, 0, 0);
1415 XCopyArea(scr->display, magPix, backPix, scr->clipGC, 2, 2, Cursor_mask_width,
1416 Cursor_mask_height, 0, 0); /* (2,2) puts center pixel on center of glass */
1418 XFreePixmap(scr->display, magPix);
1420 return backPix;
1424 static WMView*
1425 magnifyCreateView(W_ColorPanel *panel)
1427 W_Screen *scr = WMWidgetScreen(panel->win);
1428 WMView *magView;
1430 magView = W_CreateTopView(scr);
1431 magView->self = panel;
1433 W_ResizeView(magView, Cursor_mask_width, Cursor_mask_height);
1435 magView->attribFlags |= CWOverrideRedirect | CWSaveUnder;
1436 magView->attribs.event_mask = StructureNotifyMask;
1437 magView->attribs.override_redirect = True;
1438 magView->attribs.save_under = True;
1440 W_RealizeView(magView);
1441 W_MapView(magView);
1443 return magView;
1447 static Cursor
1448 magnifyGrabPointer(W_ColorPanel *panel)
1450 W_Screen *scr = WMWidgetScreen(panel->win);
1451 Pixmap magPixmap, magPixmap2;
1452 Cursor magCursor;
1453 XColor fgColor = {0, 0,0,0, DoRed|DoGreen|DoBlue};
1454 XColor bgColor = {0, 0xbf00, 0xa000, 0x5000, DoRed|DoGreen|DoBlue};
1456 /* Cursor creation stuff */
1457 magPixmap = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1458 Cursor_bits, Cursor_width, Cursor_height, 1, 0, 1);
1459 magPixmap2 = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1460 Cursor_shape_bits, Cursor_width, Cursor_height, 1, 0, 1);
1462 magCursor = XCreatePixmapCursor(scr->display, magPixmap, magPixmap2,
1463 &fgColor, &bgColor, Cursor_x_hot, Cursor_y_hot);
1465 XFreePixmap(scr->display, magPixmap);
1466 XFreePixmap(scr->display, magPixmap2);
1468 XRecolorCursor(scr->display, magCursor, &fgColor, &bgColor);
1470 /* Set up Pointer */
1471 XGrabPointer (scr->display, panel->magnifyGlass->view->window, True,
1472 PointerMotionMask | ButtonPressMask,
1473 GrabModeAsync, GrabModeAsync,
1474 scr->rootWin, magCursor, CurrentTime);
1476 return magCursor;
1480 static WMPoint
1481 magnifyInitialize(W_ColorPanel *panel)
1483 W_Screen *scr = WMWidgetScreen(panel->win);
1484 int x, y, u, v;
1485 unsigned int mask;
1486 Pixmap pixmap;
1487 WMPoint point;
1489 XQueryPointer(scr->display, scr->rootWin, &scr->rootWin,
1490 &W_VIEW(panel->win)->window, &x, &y, &u, &v, &mask);
1493 /* Clipmask to make magnified view-contents circular */
1494 panel->magnifyGlass->mask = XCreatePixmapFromBitmapData(scr->display,
1495 W_DRAWABLE(scr), Cursor_mask_bits,
1496 Cursor_mask_width, Cursor_mask_height, 1, 0, 1);
1498 /* Draw initial magnified part */
1499 panel->magnifyGlass->valid = False;
1500 /* also free's magnifyGlass->pixmap */
1501 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(panel, x, y, x, y);
1502 panel->magnifyGlass->valid = True;
1504 pixmap = magnifyCreatePixmap(panel);
1505 W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot +1, y - Cursor_y_hot +1);
1507 XSetWindowBackgroundPixmap(scr->display, panel->magnifyGlass->view->window, pixmap);
1508 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1509 XFlush(scr->display);
1511 XFreePixmap(scr->display, pixmap);
1513 point.x = x;
1514 point.y = y;
1516 return point;
1520 static void
1521 magnifyPutCursor(WMWidget *w, void *data)
1523 W_ColorPanel *panel = (W_ColorPanel*)(data);
1524 W_Screen *scr = WMWidgetScreen(panel->win);
1525 Cursor magCursor;
1526 int x, y;
1527 Pixmap pixmap;
1528 XEvent event;
1529 WMPoint initialPosition;
1531 /* Destroy wheelBackImg, so it'll update properly */
1532 if (panel->selectionBackImg) {
1533 XFreePixmap(WMWidgetScreen(panel->win)->display, panel->selectionBackImg);
1534 panel->selectionBackImg = None;
1537 /* Create magnifying glass */
1538 panel->magnifyGlass = wmalloc(sizeof(MovingView));
1540 panel->magnifyGlass->view = magnifyCreateView(panel);
1541 magCursor = magnifyGrabPointer(panel);
1543 initialPosition = magnifyInitialize(panel);
1544 x = initialPosition.x;
1545 y = initialPosition.y;
1548 while(panel->magnifyGlass->valid)
1550 WMNextEvent(scr->display, &event);
1552 switch (event.type)
1554 case ButtonPress:
1555 if (event.xbutton.button == Button1) {
1556 updateSwatch(panel, panel->magnifyGlass->color);
1557 switch (panel->mode) {
1558 case WMWheelModeColorPanel:
1559 wheelInit(panel);
1560 wheelRender(panel);
1561 wheelPaint(panel);
1562 break;
1563 case WMGrayModeColorPanel:
1564 grayInit(panel);
1565 break;
1566 case WMRGBModeColorPanel:
1567 rgbInit(panel);
1568 break;
1569 case WMCMYKModeColorPanel:
1570 cmykInit(panel);
1571 break;
1572 case WMHSBModeColorPanel:
1573 hsbInit(panel);
1574 break;
1575 default:
1576 break;
1578 panel->lastChanged = panel->mode;
1581 panel->magnifyGlass->valid = False;
1582 WMSetButtonSelected(panel->magnifyBtn, False);
1583 break;
1585 case MotionNotify:
1586 /* Get a "dirty rectangle" */
1587 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(
1588 panel, x+1, y+1, /* Cool, a circular reference ! */
1589 event.xmotion.x_root+1, event.xmotion.y_root+1); /* also free's magnifyGlass->pixmap */
1591 /* Update coordinates */
1592 x = event.xmotion.x_root;
1593 y = event.xmotion.y_root;
1595 /* Move view */
1596 W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot +1, y - Cursor_y_hot +1);
1598 /* Put new image (with magn.) in view */
1599 pixmap = magnifyCreatePixmap(panel);
1600 XSetWindowBackgroundPixmap(scr->display, panel->magnifyGlass->view->window, pixmap);
1601 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1603 XFreePixmap(scr->display, pixmap);
1604 break;
1606 default:
1607 WMHandleEvent(&event);
1608 break;
1609 } /* of switch */
1611 panel->magnifyGlass->valid = False;
1613 XUngrabPointer(scr->display, CurrentTime);
1614 XFreeCursor(scr->display, magCursor);
1615 W_DestroyView(panel->magnifyGlass->view);
1617 XFreePixmap(scr->display, panel->magnifyGlass->mask);
1618 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1619 free(panel->magnifyGlass);
1624 /****************** WheelMatrix Functions ************************/
1626 static wheelMatrix*
1627 wheelCreateMatrix(unsigned int width, unsigned int height)
1629 wheelMatrix *matrix = NULL;
1630 int i;
1632 assert((width > 0) && (height > 0));
1634 matrix = malloc(sizeof(wheelMatrix));
1635 if (!matrix) {
1636 RErrorCode = RERR_NOMEMORY;
1637 return NULL;
1640 memset(matrix, 0, sizeof(wheelMatrix));
1641 matrix->width = width;
1642 matrix->height = height;
1643 for (i = 0; i < 3; i++) {
1644 matrix->data[i] = malloc(width*height*sizeof(unsigned char));
1645 if (!matrix->data[i])
1646 goto error;
1649 return matrix;
1651 error:
1652 for (i = 0; i < 3; i++) {
1653 if (matrix->data[i])
1654 free(matrix->data[i]);
1656 if (matrix)
1657 free(matrix);
1658 RErrorCode = RERR_NOMEMORY;
1659 return NULL;
1663 static void
1664 wheelDestroyMatrix(wheelMatrix *matrix)
1666 int i;
1668 assert (matrix!=NULL);
1670 for (i = 0; i < 3; i++) {
1671 if (matrix->data[i])
1672 free(matrix->data[i]);
1674 free(matrix);
1678 static wheelMatrix*
1679 wheelInitMatrix(W_ColorPanel *panel)
1681 int i;
1682 int x,y;
1683 wheelMatrix *matrix;
1684 unsigned char *rp, *gp, *bp;
1685 RHSVColor cur_hsv;
1686 RColor cur_rgb;
1687 long ofs[4];
1688 float hue;
1689 int sat;
1690 float xcor, ycor;
1691 int dhue[4];
1693 matrix = wheelCreateMatrix(colorWheelSize+4, colorWheelSize+4);
1694 if (!matrix)
1695 return NULL;
1697 RRGBtoHSV(&panel->color, &cur_hsv);
1699 for (i = 0; i < 256; i++)
1700 matrix->values[i] = (unsigned char)(rint(i*cur_hsv.value/255));
1702 cur_hsv.value = 255;
1704 ofs[0] = -1;
1705 ofs[1] = -(colorWheelSize + 4);
1706 /* ofs[2] = 0; superfluous
1707 ofs[3] = 0;
1709 for (y = 0; y < (colorWheelSize+4)/2; y++) {
1710 for (x = y; x < (colorWheelSize+4-y); x++) {
1711 xcor = ((float)(2.0*x - 4.0) / colorWheelSize) - 1;
1712 ycor = ((float)(2.0*y - 4.0) / colorWheelSize) - 1;
1714 sat = rint(255.0 * sqrt((xcor*xcor) + (ycor*ycor)));
1718 /* offsets are counterclockwise (in triangles) */
1719 if (y < (colorWheelSize+4)/2)
1720 ofs[0]++;
1721 /* top quarter */
1722 ofs[1] += colorWheelSize + 4; /* left quarter */
1725 ofs[2] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[0]; /* bottom quarter */
1726 ofs[3] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[1]; /* right quarter */
1728 if (sat < 256) {
1729 cur_hsv.saturation = (unsigned char)sat;
1731 if (xcor != 0)
1732 hue = atan(ycor/xcor);
1733 else {
1734 if (ycor > 0)
1735 hue = M_PI * 0.5;
1736 else
1737 hue = M_PI * 1.5;
1740 if (xcor < 0)
1741 hue += M_PI;
1742 if ((xcor > 0) && (ycor < 0))
1743 hue += M_PI * 2.0;
1745 hue = -hue; /* Reverse direction of ColorWheel */
1747 if (hue < 0)
1748 hue += M_PI * 2.0;
1750 dhue[0] = (hue*360) / (M_PI * 2.0);
1752 for (i = 0; i < 4; i++) {
1754 if (i > 0)
1755 dhue[i] = (dhue[i-1] + 90) % 360;
1757 if ((i == 1) || (i == 3))
1758 dhue[i] = 360 - dhue[i];
1760 if (i == 2)
1761 dhue[i] = 360 - dhue[i] + 180;
1763 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1764 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1765 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1767 cur_hsv.hue = dhue[i];
1768 RHSVtoRGB(&cur_hsv, &cur_rgb);
1770 *rp = (unsigned char)(cur_rgb.red);
1771 *gp = (unsigned char)(cur_rgb.green);
1772 *bp = (unsigned char)(cur_rgb.blue);
1775 else {
1776 for (i = 0; i < 4; i++) {
1777 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1778 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1779 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1781 *rp = (unsigned char)(0);
1782 *gp = (unsigned char)(0);
1783 *bp = (unsigned char)(0);
1787 if (y < (colorWheelSize+4)/2)
1788 ofs[0] += 2*y+1;
1790 ofs[1] += 1 - (colorWheelSize + 4) * (colorWheelSize + 4 - 1 - 2*y);
1793 return matrix;
1796 /****************** ColorWheel Functions *******************/
1798 static void
1799 wheelRender(W_ColorPanel *panel)
1801 W_Screen *scr = WMWidgetScreen(panel->win);
1802 int x,y;
1803 RImage *image;
1804 unsigned char *rp, *gp, *bp;
1805 RColor gray;
1806 unsigned long ofs;
1808 image = RCreateImage(colorWheelSize+4, colorWheelSize+4, False);
1809 if (!image)
1810 return;
1812 gray.red = gray.green = gray.blue = 0xaa;
1814 for (x = 0; x < colorWheelSize+4; x++) {
1815 for (y = 0; y < colorWheelSize+4; y++) {
1817 ofs = (y * image->width) + x;
1818 rp = image->data[0] + ofs;
1819 gp = image->data[1] + ofs;
1820 bp = image->data[2] + ofs;
1822 if (wheelInsideColorWheel(panel, ofs)) {
1823 *rp = (unsigned int)(panel->wheelMtrx->values[ panel->wheelMtrx->data[0][ofs] ]);
1824 *gp = (unsigned int)(panel->wheelMtrx->values[ panel->wheelMtrx->data[1][ofs] ]);
1825 *bp = (unsigned int)(panel->wheelMtrx->values[ panel->wheelMtrx->data[2][ofs] ]);
1827 else {
1828 *rp = (unsigned char)(gray.red);
1829 *gp = (unsigned char)(gray.green);
1830 *bp = (unsigned char)(gray.blue);
1835 if (panel->wheelImg)
1836 XFreePixmap(scr->display, panel->wheelImg);
1838 panel->wheelImg = XCreatePixmap(scr->display, W_DRAWABLE(scr), colorWheelSize+4, colorWheelSize+4, scr->depth);
1839 RConvertImage(scr->rcontext, image, &panel->wheelImg);
1841 /* Check backimage existence. If it doesn't exist, allocate it and fill it */
1842 if (!panel->selectionBackImg) {
1843 panel->selectionBackImg = XCreatePixmap(scr->display, W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
1844 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg, scr->copyGC,
1845 panel->colx -2, panel->coly -2, 4, 4, 0, 0); /* -2 is for hot spot correction */
1848 RDestroyImage(image);
1851 static Bool
1852 wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs)
1854 return ((panel->wheelMtrx->data[0][ofs] != 0) &&
1855 (panel->wheelMtrx->data[1][ofs] != 0) &&
1856 (panel->wheelMtrx->data[2][ofs] != 0));
1859 static void
1860 wheelPaint (W_ColorPanel *panel)
1862 W_Screen *scr = WMWidgetScreen(panel->win);
1864 XCopyArea(scr->display, panel->wheelImg, panel->wheelView->window, scr->copyGC,
1865 0, 0, colorWheelSize+4, colorWheelSize+4, 0, 0);
1867 /* Draw selection image */
1868 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window, scr->copyGC,
1869 0, 0, 4, 4, panel->colx -2, panel->coly -2);
1872 static void
1873 wheelHandleEvents(XEvent *event, void *data)
1875 W_ColorPanel *panel = (W_ColorPanel*)data;
1877 switch (event->type) {
1878 case Expose:
1879 if (event->xexpose.count != 0)
1880 break;
1881 wheelPaint(panel);
1882 break;
1886 static void
1887 wheelHandleActionEvents(XEvent *event, void *data)
1889 W_ColorPanel *panel = (W_ColorPanel*)data;
1891 switch (event->type) {
1892 case ButtonPress:
1893 if (getPickerPart(panel, event->xbutton.x, event->xbutton.y) == COLORWHEEL_PART) {
1894 panel->flags.dragging = 1;
1895 wheelPositionSelection(panel, event->xbutton.x, event->xbutton.y);
1897 break;
1899 case ButtonRelease:
1900 panel->flags.dragging = 0;
1901 if (!panel->flags.continuous) {
1902 if (panel->action)
1903 (*panel->action)(panel->action, panel->clientData);
1905 break;
1907 case MotionNotify:
1908 if (panel->flags.dragging) {
1909 if (getPickerPart(panel, event->xmotion.x, event->xmotion.y) == COLORWHEEL_PART) {
1910 wheelPositionSelection(panel, event->xmotion.x, event->xmotion.y);
1912 else
1913 wheelPositionSelectionOutBounds(panel, event->xmotion.x, event->xmotion.y);
1915 break;
1920 static int
1921 getPickerPart(W_ColorPanel *panel, int x, int y)
1923 int lx, ly;
1924 unsigned long ofs;
1926 lx = x;
1927 ly = y;
1929 if (panel->mode == WMWheelModeColorPanel) {
1930 if ((lx >= 2) && (lx <= 2+colorWheelSize) && (ly >= 2) && (ly <= 2+colorWheelSize)) {
1931 ofs = ly*panel->wheelMtrx->width+lx;
1933 if (wheelInsideColorWheel(panel, ofs))
1934 return COLORWHEEL_PART;
1938 if (panel->mode == WMCustomPaletteModeColorPanel) {
1939 if ((lx >= 2) && (lx < customPaletteWidth-2) && (ly >= 2) && (ly < customPaletteHeight-2)) {
1940 return CUSTOMPALETTE_PART;
1944 return 0;
1948 static void
1949 wheelBrightnessSliderCallback(WMWidget *w, void *data)
1951 int i;
1952 unsigned int v;
1953 int value;
1954 unsigned long ofs;
1955 RColor cur_rgb;
1957 W_ColorPanel *panel = (W_ColorPanel*)data;
1959 value = 255-WMGetSliderValue(panel->wheelBrightnessS);
1961 for (i = 0; i < 256; i++) {
1962 /* We divide by 128 in advance, and check whether that number divides
1963 * by 2 properly. If not, we add one to round the number correctly
1965 v = (i*value) >> 7;
1966 #ifdef EASTEREGG
1967 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + v);
1968 #else
1969 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) +(v & 0x01));
1970 #endif
1973 ofs = (panel->coly * panel->wheelMtrx->width) + panel->colx;
1975 if (!wheelInsideColorWheel(panel, ofs)) {
1976 panel->hsvcolor.saturation = 255;
1977 panel->hsvcolor.value = value;
1978 RHSVtoRGB(&panel->hsvcolor, &cur_rgb);
1980 panel->color = cur_rgb;
1982 else {
1983 panel->color.red = panel->wheelMtrx->values[ panel->wheelMtrx->data[0][ofs] ];
1984 panel->color.green = panel->wheelMtrx->values[ panel->wheelMtrx->data[1][ofs] ];
1985 panel->color.blue = panel->wheelMtrx->values[ panel->wheelMtrx->data[2][ofs] ];
1988 wheelRender(panel);
1989 wheelPaint(panel);
1990 wheelUpdateSelection(panel);
1994 static void
1995 wheelUpdateSelection(W_ColorPanel *panel)
1997 W_Screen *scr = WMWidgetScreen(panel->win);
1999 updateSwatch(panel, panel->color);
2000 panel->lastChanged = WMWheelModeColorPanel;
2002 /* Redraw color selector (and make a backup of the part it will cover) */
2003 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg, scr->copyGC,
2004 panel->colx -2, panel->coly -2, 4, 4, 0, 0); /* "-2" is correction for hotspot location */
2005 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window, scr->copyGC,
2006 0, 0, 4, 4, panel->colx -2, panel->coly -2); /* see above */
2009 static void
2010 wheelUndrawSelection(W_ColorPanel *panel)
2012 W_Screen *scr = WMWidgetScreen(panel->win);
2014 XCopyArea(scr->display, panel->selectionBackImg, panel->wheelView->window, scr->copyGC,
2015 0, 0, 4, 4, panel->colx -2, panel->coly -2); /* see above */
2018 static void
2019 wheelPositionSelection(W_ColorPanel *panel, int x, int y)
2021 unsigned long ofs = (y * panel->wheelMtrx->width)+ x;
2024 panel->color.red = panel->wheelMtrx->values[ panel->wheelMtrx->data[0][ofs] ];
2025 panel->color.green = panel->wheelMtrx->values[ panel->wheelMtrx->data[1][ofs] ];
2026 panel->color.blue = panel->wheelMtrx->values[ panel->wheelMtrx->data[2][ofs] ];
2028 wheelUndrawSelection(panel);
2030 panel->colx = x;
2031 panel->coly = y;
2033 wheelUpdateSelection(panel);
2034 wheelUpdateBrightnessGradientFromLocation(panel);
2037 static void
2038 wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2040 RHSVColor cur_hsv;
2041 float hue;
2042 float xcor, ycor;
2044 xcor = ((x*2.0) / (colorWheelSize+4)) - 1.0;
2045 ycor = ((y*2.0) / (colorWheelSize+4)) - 1.0;
2047 cur_hsv.saturation = 255;
2048 cur_hsv.value = 255 - WMGetSliderValue(panel->wheelBrightnessS);
2050 if (xcor != 0)
2051 hue = atan(ycor/xcor);
2052 else {
2053 if (ycor > 0)
2054 hue = M_PI * 0.5;
2055 else
2056 hue = M_PI * 1.5;
2059 if (xcor < 0)
2060 hue += M_PI;
2061 if ((xcor > 0) && (ycor < 0))
2062 hue += M_PI * 2.0;
2064 hue = -hue;
2066 if (hue < 0)
2067 hue += M_PI * 2.0;
2069 cur_hsv.hue = (hue*180.0)/(M_PI);
2070 RHSVtoRGB(&cur_hsv, &panel->color);
2072 wheelUndrawSelection(panel);
2074 panel->colx = 2 + rint((colorWheelSize * (1.0 + cos( cur_hsv.hue*M_PI/180))) /2.0); /* "+2" because of "colorWheelSize + 4" */
2075 panel->coly = 2 + rint((colorWheelSize * (1.0 + sin(-cur_hsv.hue*M_PI/180))) /2.0);
2077 wheelUpdateSelection(panel);
2078 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
2081 static void
2082 wheelUpdateBrightnessGradientFromHSV(W_ColorPanel *panel, RHSVColor topColor)
2084 RColor from;
2086 /* Update Brightness-Slider */
2087 topColor.value = 255;
2088 RHSVtoRGB(&topColor, &from);
2090 wheelUpdateBrightnessGradient(panel, from);
2093 static void
2094 wheelUpdateBrightnessGradientFromLocation(W_ColorPanel *panel)
2096 RColor from;
2097 unsigned long ofs;
2099 ofs = panel->coly * panel->wheelMtrx->width + panel->colx;
2101 from.red = panel->wheelMtrx->data[0][ofs];
2102 from.green = panel->wheelMtrx->data[1][ofs];
2103 from.blue = panel->wheelMtrx->data[2][ofs];
2105 wheelUpdateBrightnessGradient(panel, from);
2108 static void
2109 wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor)
2111 RColor to;
2112 RImage *sliderImg;
2113 WMPixmap *sliderPxmp;
2115 to.red = to.green = to.blue = 0;
2117 sliderImg = RRenderGradient(16, 153, &topColor, &to, RGRD_VERTICAL);
2118 sliderPxmp = WMCreatePixmapFromRImage(WMWidgetScreen(panel->win), sliderImg, 0);
2119 RDestroyImage(sliderImg);
2120 WMSetSliderImage(panel->wheelBrightnessS, sliderPxmp);
2121 WMReleasePixmap(sliderPxmp);
2124 /****************** Grayscale Panel Functions ***************/
2126 static void
2127 grayBrightnessSliderCallback(WMWidget *w, void *data)
2129 RColor color;
2130 int value;
2131 char tmp[4];
2133 W_ColorPanel *panel = (W_ColorPanel*)data;
2135 value = WMGetSliderValue(panel->grayBrightnessS);
2137 sprintf(tmp, "%d", value);
2139 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2140 color.red = color.green = color.blue = rint(2.55*value);
2142 updateSwatch(panel, color);
2143 panel->lastChanged = WMGrayModeColorPanel;
2146 static void
2147 grayPresetButtonCallback(WMWidget *w, void *data)
2149 RColor color;
2150 char tmp[4];
2151 int value;
2152 int i=0;
2154 W_ColorPanel *panel = (W_ColorPanel*)data;
2156 while (i < 7) {
2157 if (w == panel->grayPresetBtn[i])
2158 break;
2159 i++;
2162 value = rint(100.0/6.0*i);
2163 sprintf(tmp, "%d", value);
2165 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2166 color.red = color.green = color.blue = rint(255.0*i/6.0);
2168 WMSetSliderValue(panel->grayBrightnessS, rint(100.0*i/6.0));
2170 updateSwatch(panel, color);
2171 panel->lastChanged = WMGrayModeColorPanel;
2174 static void
2175 grayBrightnessTextFieldCallback(void *observerData, WMNotification *notification)
2177 RColor color;
2178 char tmp[4];
2179 int value;
2180 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2182 value = atoi(WMGetTextFieldText(panel->grayBrightnessT));
2183 if (value > 100)
2184 value = 100;
2185 if (value < 0)
2186 value = 0;
2188 sprintf(tmp, "%d", value);
2189 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2190 WMSetSliderValue(panel->grayBrightnessS, value);
2192 color.red = color.green = color.blue = rint(255.0*value/100.0);
2193 updateSwatch(panel, color);
2194 panel->lastChanged = WMGrayModeColorPanel;
2197 /******************* RGB Panel Functions *****************/
2199 static void
2200 rgbSliderCallback(WMWidget *w, void *data)
2202 RColor color;
2203 int value[3];
2204 char tmp[4];
2206 W_ColorPanel *panel = (W_ColorPanel*)data;
2208 value[0] = WMGetSliderValue(panel->rgbRedS);
2209 value[1] = WMGetSliderValue(panel->rgbGreenS);
2210 value[2] = WMGetSliderValue(panel->rgbBlueS);
2212 sprintf(tmp, "%d", value[0]);
2213 WMSetTextFieldText(panel->rgbRedT, tmp);
2214 sprintf(tmp, "%d", value[1]);
2215 WMSetTextFieldText(panel->rgbGreenT, tmp);
2216 sprintf(tmp, "%d", value[2]);
2217 WMSetTextFieldText(panel->rgbBlueT, tmp);
2219 color.red = value[0];
2220 color.green = value[1];
2221 color.blue = value[2];
2223 updateSwatch(panel, color);
2224 panel->lastChanged = WMRGBModeColorPanel;
2227 static void
2228 rgbTextFieldCallback(void *observerData, WMNotification *notification)
2230 RColor color;
2231 int value[3];
2232 char tmp[4];
2233 int n;
2234 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2236 value[0] = atoi(WMGetTextFieldText(panel->rgbRedT));
2237 value[1] = atoi(WMGetTextFieldText(panel->rgbGreenT));
2238 value[2] = atoi(WMGetTextFieldText(panel->rgbBlueT));
2240 for (n=0; n < 3; n++) {
2241 if (value[n] > 255)
2242 value[n] = 255;
2243 if (value[n] < 0)
2244 value[n] = 0;
2247 sprintf(tmp, "%d", value[0]);
2248 WMSetTextFieldText(panel->rgbRedT, tmp);
2249 sprintf(tmp, "%d", value[1]);
2250 WMSetTextFieldText(panel->rgbGreenT, tmp);
2251 sprintf(tmp, "%d", value[2]);
2252 WMSetTextFieldText(panel->rgbBlueT, tmp);
2254 WMSetSliderValue(panel->rgbRedS, value[0]);
2255 WMSetSliderValue(panel->rgbGreenS, value[1]);
2256 WMSetSliderValue(panel->rgbBlueS, value[2]);
2258 color.red = value[0];
2259 color.green = value[1];
2260 color.blue = value[2];
2262 updateSwatch(panel, color);
2263 panel->lastChanged = WMRGBModeColorPanel;
2267 /******************* CMYK Panel Functions *****************/
2269 static void
2270 cmykSliderCallback(WMWidget *w, void *data)
2272 RColor color;
2273 int value[4];
2274 char tmp[4];
2276 W_ColorPanel *panel = (W_ColorPanel*)data;
2278 value[0] = WMGetSliderValue(panel->cmykCyanS);
2279 value[1] = WMGetSliderValue(panel->cmykMagentaS);
2280 value[2] = WMGetSliderValue(panel->cmykYellowS);
2281 value[3] = WMGetSliderValue(panel->cmykBlackS);
2283 sprintf(tmp, "%d", value[0]);
2284 WMSetTextFieldText(panel->cmykCyanT, tmp);
2285 sprintf(tmp, "%d", value[1]);
2286 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2287 sprintf(tmp, "%d", value[2]);
2288 WMSetTextFieldText(panel->cmykYellowT, tmp);
2289 sprintf(tmp, "%d", value[3]);
2290 WMSetTextFieldText(panel->cmykBlackT, tmp);
2292 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2293 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3] / 100.0)));
2294 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] / 100.0)));
2296 updateSwatch(panel, color);
2297 panel->lastChanged = WMCMYKModeColorPanel;
2300 static void
2301 cmykTextFieldCallback(void *observerData, WMNotification *notification)
2303 RColor color;
2304 int value[4];
2305 char tmp[4];
2306 int n;
2307 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2309 value[0] = atoi(WMGetTextFieldText(panel->cmykCyanT));
2310 value[1] = atoi(WMGetTextFieldText(panel->cmykMagentaT));
2311 value[2] = atoi(WMGetTextFieldText(panel->cmykYellowT));
2312 value[3] = atoi(WMGetTextFieldText(panel->cmykBlackT));
2314 for (n=0; n < 4; n++) {
2315 if (value[n] > 100)
2316 value[n] = 100;
2317 if (value[n] < 0)
2318 value[n] = 0;
2321 sprintf(tmp, "%d", value[0]);
2322 WMSetTextFieldText(panel->cmykCyanT, tmp);
2323 sprintf(tmp, "%d", value[1]);
2324 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2325 sprintf(tmp, "%d", value[2]);
2326 WMSetTextFieldText(panel->cmykYellowT, tmp);
2327 sprintf(tmp, "%d", value[3]);
2328 WMSetTextFieldText(panel->cmykBlackT, tmp);
2330 WMSetSliderValue(panel->cmykCyanS, value[0]);
2331 WMSetSliderValue(panel->cmykMagentaS, value[1]);
2332 WMSetSliderValue(panel->cmykYellowS, value[2]);
2333 WMSetSliderValue(panel->cmykBlackS, value[3]);
2335 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2336 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3] / 100.0)));
2337 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] / 100.0)));
2339 updateSwatch(panel, color);
2340 panel->lastChanged = WMCMYKModeColorPanel;
2343 /********************** HSB Panel Functions ***********************/
2345 static void
2346 hsbSliderCallback(WMWidget *w, void *data)
2348 RColor color;
2349 int value[3];
2350 char tmp[4];
2352 W_ColorPanel *panel = (W_ColorPanel*)data;
2354 value[0] = WMGetSliderValue(panel->hsbHueS);
2355 value[1] = WMGetSliderValue(panel->hsbSaturationS);
2356 value[2] = WMGetSliderValue(panel->hsbBrightnessS);
2358 sprintf(tmp, "%d", value[0]);
2359 WMSetTextFieldText(panel->hsbHueT, tmp);
2360 sprintf(tmp, "%d", value[1]);
2361 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2362 sprintf(tmp, "%d", value[2]);
2363 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2365 panel->hsvcolor.hue = value[0];
2366 panel->hsvcolor.saturation = value[1]*2.55;
2367 panel->hsvcolor.value = value[2]*2.55;
2369 RHSVtoRGB(&panel->hsvcolor, &color);
2371 panel->lastChanged = WMHSBModeColorPanel;
2372 updateSwatch(panel, color);
2374 if (w != panel->hsbBrightnessS)
2375 hsbUpdateBrightnessGradient(panel);
2376 if (w != panel->hsbSaturationS)
2377 hsbUpdateSaturationGradient(panel);
2378 if (w != panel->hsbHueS)
2379 hsbUpdateHueGradient(panel);
2382 static void
2383 hsbTextFieldCallback(void *observerData, WMNotification *notification)
2385 RColor color;
2386 int value[3];
2387 char tmp[4];
2388 int n;
2389 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2391 value[0] = atoi(WMGetTextFieldText(panel->hsbHueT));
2392 value[1] = atoi(WMGetTextFieldText(panel->hsbSaturationT));
2393 value[2] = atoi(WMGetTextFieldText(panel->hsbBrightnessT));
2395 if (value[0] > 359)
2396 value[0] = 359;
2397 if (value[0] < 0)
2398 value[0] = 0;
2400 for (n=1; n < 3; n++) {
2401 if (value[n] > 100)
2402 value[n] = 100;
2403 if (value[n] < 0)
2404 value[n] = 0;
2407 sprintf(tmp, "%d", value[0]);
2408 WMSetTextFieldText(panel->hsbHueT, tmp);
2409 sprintf(tmp, "%d", value[1]);
2410 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2411 sprintf(tmp, "%d", value[2]);
2412 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2414 WMSetSliderValue(panel->hsbHueS, value[0]);
2415 WMSetSliderValue(panel->hsbSaturationS, value[1]);
2416 WMSetSliderValue(panel->hsbBrightnessS, value[2]);
2418 panel->hsvcolor.hue = value[0];
2419 panel->hsvcolor.saturation = value[1]*2.55;
2420 panel->hsvcolor.value = value[2]*2.55;
2422 RHSVtoRGB(&panel->hsvcolor, &color);
2424 panel->lastChanged = WMHSBModeColorPanel;
2425 updateSwatch(panel, color);
2427 hsbUpdateBrightnessGradient(panel);
2428 hsbUpdateSaturationGradient(panel);
2429 hsbUpdateHueGradient(panel);
2432 static void
2433 hsbUpdateBrightnessGradient(W_ColorPanel *panel)
2435 W_Screen *scr = WMWidgetScreen(panel->win);
2436 RColor from;
2437 RColor to;
2438 RHSVColor hsvcolor;
2439 RImage *sliderImg;
2440 WMPixmap *sliderPxmp;
2442 from.red = from.green = from.blue = 0;
2443 hsvcolor = panel->hsvcolor;
2444 hsvcolor.value = 255;
2446 RHSVtoRGB(&hsvcolor, &to);
2448 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2449 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2450 RDestroyImage(sliderImg);
2451 W_PaintText(W_VIEW(panel->hsbBrightnessS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False, "Brightness", strlen("Brightness"));
2452 WMSetSliderImage(panel->hsbBrightnessS, sliderPxmp);
2453 WMReleasePixmap(sliderPxmp);
2456 static void
2457 hsbUpdateSaturationGradient(W_ColorPanel *panel)
2459 W_Screen *scr = WMWidgetScreen(panel->win);
2460 RColor from;
2461 RColor to;
2462 RHSVColor hsvcolor;
2463 RImage *sliderImg;
2464 WMPixmap *sliderPxmp;
2466 hsvcolor = panel->hsvcolor;
2467 hsvcolor.saturation = 0;
2468 RHSVtoRGB(&hsvcolor, &from);
2470 hsvcolor.saturation = 255;
2471 RHSVtoRGB(&hsvcolor, &to);
2473 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2474 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2475 RDestroyImage(sliderImg);
2476 if (hsvcolor.value < 128)
2477 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False, "Saturation", strlen("Saturation"));
2478 else
2479 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False, "Saturation", strlen("Saturation"));
2481 WMSetSliderImage(panel->hsbSaturationS, sliderPxmp);
2482 WMReleasePixmap(sliderPxmp);
2485 static void
2486 hsbUpdateHueGradient(W_ColorPanel *panel)
2488 W_Screen *scr = WMWidgetScreen(panel->win);
2489 RColor **colors = NULL;
2490 RHSVColor hsvcolor;
2491 RImage *sliderImg;
2492 WMPixmap *sliderPxmp;
2493 int i;
2495 hsvcolor = panel->hsvcolor;
2497 colors = malloc(sizeof(RColor*)*(8));
2498 for (i=0; i<7; i++) {
2499 hsvcolor.hue = (360*i)/6;
2500 colors[i] = malloc(sizeof(RColor));
2501 RHSVtoRGB(&hsvcolor, colors[i]);
2503 colors[7] = NULL;
2505 sliderImg = RRenderMultiGradient(141, 16, colors, RGRD_HORIZONTAL);
2506 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2507 RDestroyImage(sliderImg);
2508 if (hsvcolor.value < 128)
2509 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False, "Hue", strlen("Hue"));
2510 else
2511 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False, "Hue", strlen("Hue"));
2513 WMSetSliderImage(panel->hsbHueS, sliderPxmp);
2514 WMReleasePixmap(sliderPxmp);
2516 for (i=0; i<7; i++) {
2517 if (colors[i])
2518 free(colors[i]);
2520 if (colors)
2521 free(colors);
2524 /*************** Custom Palette Functions ****************/
2526 static void
2527 customRenderSpectrum(W_ColorPanel *panel)
2529 RImage *spectrum;
2530 int hue, sat, val;
2531 int x,y;
2532 unsigned long ofs;
2533 unsigned char *rp, *gp, *bp;
2534 RColor color;
2535 RHSVColor cur_hsv;
2537 spectrum = RCreateImage(SPECTRUM_WIDTH, SPECTRUM_HEIGHT, 0);
2539 for (y=0; y<360; y++) {
2540 val = 255;
2541 sat = 0;
2542 hue = y;
2543 for (x=0; x<511; x++) {
2544 ofs = (y * 511) + x;
2546 cur_hsv.hue = hue;
2547 cur_hsv.saturation = sat;
2548 cur_hsv.value = val;
2550 RHSVtoRGB (&cur_hsv, &color);
2552 rp = spectrum->data[0] + ofs;
2553 gp = spectrum->data[1] + ofs;
2554 bp = spectrum->data[2] + ofs;
2556 *rp = (unsigned char)color.red;
2557 *gp = (unsigned char)color.green;
2558 *bp = (unsigned char)color.blue;
2560 if (x<255)
2561 sat++;
2563 if (x>255)
2564 val--;
2567 if (panel->customPaletteImg) {
2568 RDestroyImage(panel->customPaletteImg);
2569 panel->customPaletteImg = NULL;
2571 panel->customPaletteImg = spectrum;
2576 static void
2577 customSetPalette(W_ColorPanel *panel)
2579 W_Screen *scr = WMWidgetScreen(panel->win);
2580 RImage *scaledImg;
2581 Pixmap image;
2582 int item;
2584 image = XCreatePixmap(scr->display, W_DRAWABLE(scr), customPaletteWidth, customPaletteHeight, scr->depth);
2586 scaledImg = RScaleImage(panel->customPaletteImg, customPaletteWidth, customPaletteHeight);
2587 RConvertImage(scr->rcontext, scaledImg, &image);
2588 RDestroyImage(scaledImg);
2590 XCopyArea(scr->display, image, panel->customPaletteContentView->window, scr->copyGC, 0, 0, customPaletteWidth, customPaletteHeight, 0, 0);
2592 /* Check backimage existence. If it doesn't exist, allocate it and fill it */
2593 if (!panel->selectionBackImg) {
2594 panel->selectionBackImg = XCreatePixmap(scr->display, panel->customPaletteContentView->window, 4, 4, scr->depth);
2597 XCopyArea(scr->display, image, panel->selectionBackImg, scr->copyGC, panel->palx-2, panel->paly-2, 4, 4, 0, 0);
2598 XCopyArea(scr->display, panel->selectionImg, panel->customPaletteContentView->window, scr->copyGC, 0 , 0, 4, 4, panel->palx-2, panel->paly-2);
2599 XFreePixmap(scr->display, image);
2601 panel->palXRatio = (float)(panel->customPaletteImg->width) / (float)(customPaletteWidth);
2602 panel->palYRatio = (float)(panel->customPaletteImg->height) / (float)(customPaletteHeight);
2604 item = WMGetPopUpButtonSelectedItem (panel->customPaletteHistoryBtn);
2606 /* if palette != "Spectrum", we are allowed to rename and remove it */
2607 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, (item > 0) );
2608 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, (item > 0) );
2612 static void
2613 customPalettePositionSelection(W_ColorPanel *panel, int x, int y)
2615 W_Screen *scr = WMWidgetScreen(panel->win);
2616 unsigned long ofs;
2619 /* undraw selection */
2620 XCopyArea(scr->display, panel->selectionBackImg, panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4, panel->palx-2, panel->paly-2);
2622 panel->palx = x;
2623 panel->paly = y;
2625 ofs = rint(x * panel->palXRatio) + rint(y * panel->palYRatio) * panel->customPaletteImg->width;
2627 panel->color.red = panel->customPaletteImg->data[0][ofs];
2628 panel->color.green = panel->customPaletteImg->data[1][ofs];
2629 panel->color.blue = panel->customPaletteImg->data[2][ofs];
2631 updateSwatch(panel, panel->color);
2632 panel->lastChanged = WMCustomPaletteModeColorPanel;
2634 /* Redraw color selector (and make a backup of the part it will cover) */
2635 XCopyArea(scr->display, panel->customPaletteContentView->window, panel->selectionBackImg, scr->copyGC, panel->palx-2, panel->paly-2, 4, 4, 0, 0); /* "-2" is correction for hotspot location */
2636 XCopyArea(scr->display, panel->selectionImg, panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4, panel->palx-2, panel->paly-2); /* see above */
2640 static void
2641 customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2643 if (x < 2)
2644 x = 2;
2645 if (y < 2)
2646 y = 2;
2647 if (x >= customPaletteWidth)
2648 x = customPaletteWidth -2;
2649 if (y >= customPaletteHeight)
2650 y = customPaletteHeight -2;
2652 customPalettePositionSelection(panel, x, y);
2656 static void
2657 customPaletteHandleEvents(XEvent *event, void *data)
2659 W_ColorPanel *panel = (W_ColorPanel*)data;
2661 switch (event->type) {
2662 case Expose:
2663 if (event->xexpose.count != 0)
2664 break;
2665 customSetPalette(panel);
2666 break;
2670 static void
2671 customPaletteHandleActionEvents(XEvent *event, void *data)
2673 W_ColorPanel *panel = (W_ColorPanel*)data;
2674 int x, y;
2676 switch (event->type) {
2677 case ButtonPress:
2678 x = event->xbutton.x;
2679 y = event->xbutton.y;
2681 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2682 panel->flags.dragging = 1;
2683 customPalettePositionSelection(panel, x, y);
2685 break;
2687 case ButtonRelease:
2688 panel->flags.dragging = 0;
2689 if (!panel->flags.continuous) {
2690 if (panel->action)
2691 (*panel->action)(panel->action, panel->clientData);
2693 break;
2695 case MotionNotify:
2696 x = event->xmotion.x;
2697 y = event->xmotion.y;
2699 if (panel->flags.dragging) {
2700 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2701 customPalettePositionSelection(panel, x, y);
2703 else
2704 customPalettePositionSelectionOutBounds(panel, x, y);
2706 break;
2711 static void
2712 customPaletteMenuCallback(WMWidget *w, void *data)
2714 W_ColorPanel *panel = (W_ColorPanel*)data;
2715 int item = WMGetPopUpButtonSelectedItem(panel->customPaletteMenuBtn);
2717 switch (item) {
2718 case CPmenuNewFromFile:
2719 customPaletteMenuNewFromFile(panel);
2720 break;
2721 case CPmenuRename:
2722 customPaletteMenuRename(panel);
2723 break;
2724 case CPmenuRemove:
2725 customPaletteMenuRemove(panel);
2726 break;
2727 case CPmenuCopy:
2728 break;
2729 case CPmenuNewFromClipboard:
2730 break;
2735 static void
2736 customPaletteMenuNewFromFile(W_ColorPanel *panel)
2738 W_Screen *scr = WMWidgetScreen(panel->win);
2739 WMOpenPanel *browseP;
2740 char *filepath;
2741 char *filename = NULL;
2742 char *spath;
2743 char *tmp;
2744 int i;
2745 RImage *tmpImg = NULL;
2747 if ((!panel->lastBrowseDir) || (strcmp(panel->lastBrowseDir,"\0") == 0))
2748 spath = wexpandpath(wgethomedir());
2749 else
2750 spath = wexpandpath(panel->lastBrowseDir);
2752 browseP = WMGetOpenPanel(scr);
2753 WMSetFilePanelCanChooseDirectories(browseP, 0);
2754 WMSetFilePanelCanChooseFiles(browseP, 1);
2756 /* Get a filename */
2757 if (WMRunModalFilePanelForDirectory(browseP, panel->win, spath,
2758 "Open Palette",
2759 RSupportedFileFormats()) ) {
2760 filepath = WMGetFilePanelFileName(browseP);
2762 /* Get seperation position between path and filename */
2763 i = strrchr(filepath, '/') - filepath + 1;
2764 if (i > strlen(filepath))
2765 i = strlen(filepath);
2767 /* Store last browsed path */
2768 if (panel->lastBrowseDir)
2769 free(panel->lastBrowseDir);
2770 panel->lastBrowseDir = wmalloc((i+1)*sizeof(char));
2771 strncpy(panel->lastBrowseDir, filepath, i);
2772 panel->lastBrowseDir[i] = '\0';
2774 /* Get filename from path */
2775 filename = wstrdup(filepath + i);
2777 /* Check for duplicate files, and rename it if there are any */
2778 tmp = wstrappend(panel->configurationPath, filename);
2779 while (access (tmp, F_OK) == 0) {
2780 char *newName;
2782 free(tmp);
2784 newName = generateNewFilename(filename);
2785 free(filename);
2786 filename = newName;
2788 tmp = wstrappend(panel->configurationPath, filename);
2790 free(tmp);
2792 /* Copy the image to $(gnustepdir)/Library/Colors/ & Add the filename to the history menu */
2793 if (fetchFile (panel->configurationPath, filepath, filename) == 0) {
2795 /* filepath is a "local" path now the file has been copied */
2796 free(filepath);
2797 filepath = wstrappend(panel->configurationPath, filename);
2799 /* load the image & add menu entries */
2800 tmpImg = RLoadImage(scr->rcontext, filepath, 0);
2801 if (tmpImg) {
2802 if (panel->customPaletteImg)
2803 RDestroyImage(panel->customPaletteImg);
2804 panel->customPaletteImg = tmpImg;
2806 customSetPalette(panel);
2807 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, filename);
2809 panel->currentPalette = WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn)-1;
2811 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
2812 panel->currentPalette);
2815 else
2817 tmp = wstrappend(panel->configurationPath, filename);
2819 i = remove(tmp); /* Delete the file, it doesn't belong here */
2820 WMRunAlertPanel(scr, panel->win, "File Error", "Invalid file format !", "OK", NULL, NULL);
2821 if (i != 0) {
2822 wsyserror("can't remove file %s", tmp);
2823 WMRunAlertPanel(scr, panel->win, "File Error", "Couldn't remove file from Configuration Directory !", "OK", NULL, NULL);
2825 free(tmp);
2827 free(filepath);
2828 free(filename);
2830 WMFreeFilePanel(browseP);
2832 free(spath);
2836 static void
2837 customPaletteMenuRename(W_ColorPanel *panel)
2839 W_Screen *scr = WMWidgetScreen(panel->win);
2840 char *toName = NULL;
2841 char *fromName;
2842 char *toPath, *fromPath;
2843 int item;
2844 int index;
2846 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
2847 fromName = WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item);
2849 toName = WMRunInputPanel(scr, panel->win, "Rename", "Rename palette to:",
2850 fromName, "OK", "Cancel");
2852 if (toName) {
2854 /* As some people do certain stupid things... */
2855 if (strcmp(toName, fromName) == 0) {
2856 free(toName);
2857 return;
2860 /* For normal people */
2861 fromPath = wstrappend(panel->configurationPath, fromName);
2862 toPath = wstrappend(panel->configurationPath, toName);
2864 if (access (toPath, F_OK) == 0) { /* Careful, this palette exists already */
2865 if (WMRunAlertPanel(scr, panel->win, "Warning",
2866 "Palette already exists !\n\nOverwrite ?", "No", "Yes", NULL) == 1) {
2867 /* "No" = 0, "Yes" = 1 */
2868 int items = WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn);
2870 remove(toPath);
2872 /* Remove from History list too */
2873 index = 1;
2874 while ((index < items) &&
2875 (strcmp(WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, index), toName) != 0 ))
2876 index++;
2878 if (index < items) {
2879 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, index);
2880 if (index < item)
2881 item--;
2884 } else {
2885 free(fromPath);
2886 free(toName);
2887 free(toPath);
2889 return;
2893 if ( rename(fromPath, toPath) != 0)
2894 wsyserror("Couldn't rename palette %s to %s\n", fromName, toName);
2895 else {
2896 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
2897 WMInsertPopUpButtonItem(panel->customPaletteHistoryBtn, item, toName);
2899 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item);
2901 free(fromPath);
2902 free(toPath);
2903 free(toName);
2908 static void
2909 customPaletteMenuRemove(W_ColorPanel *panel)
2911 W_Screen *scr = WMWidgetScreen(panel->win);
2912 char *text;
2913 char *tmp;
2914 int choice;
2915 int item;
2917 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
2919 tmp = wstrappend( "This will permanently remove the palette ",
2920 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
2921 text = wstrappend( tmp, ".\n\nAre you sure you want to remove this palette ?");
2922 free(tmp);
2924 choice = WMRunAlertPanel(scr, panel->win, NULL, text, "Yes", "No", NULL);
2925 /* returns 0 (= "Yes") or 1 (="No") */
2926 free(text);
2928 if (choice == 0) {
2930 tmp = wstrappend(panel->configurationPath,
2931 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
2933 if ( remove(tmp) != 0)
2934 wsyserror("Couldn't remove palette %s\n", tmp);
2935 free(tmp);
2937 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item-1); /* item -1 always exists */
2938 customPaletteHistoryCallback(panel->customPaletteHistoryBtn, panel);
2939 customSetPalette(panel);
2941 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
2946 static void
2947 customPaletteHistoryCallback(WMWidget *w, void *data)
2949 W_ColorPanel *panel = (W_ColorPanel*)data;
2950 W_Screen *scr = WMWidgetScreen(panel->win);
2951 int item;
2952 char *filename;
2953 RImage *tmp = NULL;
2955 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
2956 if (item == panel->currentPalette)
2957 return;
2959 if (item == 0)
2960 customRenderSpectrum(panel);
2961 else {
2962 /* Load file from configpath */
2963 filename = wstrappend( panel->configurationPath, WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item) );
2965 /* XXX To do: Check existence of file and remove it from the history if it doesn't exist */
2967 tmp = RLoadImage(scr->rcontext, filename, 0);
2968 if (tmp) {
2969 if (panel->customPaletteImg) {
2970 RDestroyImage(panel->customPaletteImg);
2971 panel->customPaletteImg = NULL;
2973 panel->customPaletteImg = tmp;
2975 free(filename);
2977 customSetPalette(panel);
2979 panel->currentPalette = item;
2983 /*************** Panel Initialisation Functions *****************/
2985 static void
2986 wheelInit(W_ColorPanel *panel)
2988 RHSVColor cur_hsv;
2989 int i;
2990 int v;
2992 RRGBtoHSV(&panel->color, &cur_hsv);
2994 WMSetSliderValue(panel->wheelBrightnessS, 255-cur_hsv.value);
2995 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
2997 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 + (cur_hsv.saturation/255.0) * cos( cur_hsv.hue*M_PI/180.0)));
2998 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 + (cur_hsv.saturation/255.0) * sin(-cur_hsv.hue*M_PI/180.0)));
3000 for (i = 0; i < 256; i++) {
3001 /* We divide by 128 in advance, and check whether that number divides
3002 * by 2 properly. If not, we add one to round the number correctly
3004 v = (i*cur_hsv.value) >> 7;
3005 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + (v & 1));
3009 static void
3010 grayInit(W_ColorPanel *panel)
3012 RHSVColor cur_hsv;
3013 int value;
3014 char tmp[4];
3016 RRGBtoHSV(&panel->color, &cur_hsv);
3018 value = rint(cur_hsv.value/2.55);
3019 WMSetSliderValue(panel->grayBrightnessS, value);
3021 sprintf(tmp, "%d", value);
3022 WMSetTextFieldText(panel->grayBrightnessT, tmp);
3025 static void
3026 rgbInit(W_ColorPanel *panel)
3028 char tmp[4];
3030 WMSetSliderValue(panel->rgbRedS,panel->color.red);
3031 WMSetSliderValue(panel->rgbGreenS,panel->color.green);
3032 WMSetSliderValue(panel->rgbBlueS,panel->color.blue);
3034 sprintf(tmp, "%d", panel->color.red);
3035 WMSetTextFieldText(panel->rgbRedT, tmp);
3036 sprintf(tmp, "%d", panel->color.green);
3037 WMSetTextFieldText(panel->rgbGreenT, tmp);
3038 sprintf(tmp, "%d", panel->color.blue);
3039 WMSetTextFieldText(panel->rgbBlueT, tmp);
3042 static void
3043 cmykInit(W_ColorPanel *panel)
3045 int value[3];
3046 char tmp[4];
3048 value[0] = rint((255-panel->color.red)/2.55);
3049 value[1] = rint((255-panel->color.green)/2.55);
3050 value[2] = rint((255-panel->color.blue)/2.55);
3052 WMSetSliderValue(panel->cmykCyanS, value[0]);
3053 WMSetSliderValue(panel->cmykMagentaS, value[1]);
3054 WMSetSliderValue(panel->cmykYellowS, value[2]);
3055 WMSetSliderValue(panel->cmykBlackS, 0);
3057 sprintf(tmp, "%d", value[0]);
3058 WMSetTextFieldText(panel->cmykCyanT, tmp);
3059 sprintf(tmp, "%d", value[1]);
3060 WMSetTextFieldText(panel->cmykMagentaT, tmp);
3061 sprintf(tmp, "%d", value[2]);
3062 WMSetTextFieldText(panel->cmykYellowT, tmp);
3063 WMSetTextFieldText(panel->cmykBlackT, "0");
3066 static void
3067 hsbInit(W_ColorPanel *panel)
3069 int value[3];
3070 char tmp[4];
3072 value[0] = panel->hsvcolor.hue;
3073 value[1] = rint(panel->hsvcolor.saturation/2.55);
3074 value[2] = rint(panel->hsvcolor.value/2.55);
3076 WMSetSliderValue(panel->hsbHueS,value[0]);
3077 WMSetSliderValue(panel->hsbSaturationS,value[1]);
3078 WMSetSliderValue(panel->hsbBrightnessS,value[2]);
3080 sprintf(tmp, "%d", value[0]);
3081 WMSetTextFieldText(panel->hsbHueT, tmp);
3082 sprintf(tmp, "%d", value[1]);
3083 WMSetTextFieldText(panel->hsbSaturationT, tmp);
3084 sprintf(tmp, "%d", value[2]);
3085 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
3087 hsbUpdateBrightnessGradient(panel);
3088 hsbUpdateSaturationGradient(panel);
3089 hsbUpdateHueGradient(panel);
3095 /************************* ColorList Panel Functions **********************/
3097 static void
3098 colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text, int state, WMRect *rect)
3100 int width, height, x, y;
3101 RColor color = *((RColor *)WMGetListItem(lPtr, index)->clientData);
3102 WMScreen *scr = WMWidgetScreen(lPtr);
3103 Display *dpy = WMScreenDisplay(scr);
3104 W_ColorPanel *panel = WMGetHangedData(lPtr);
3105 WMColor *white = WMWhiteColor(scr);
3106 WMColor *black = WMBlackColor(scr);
3107 WMColor *fillColor;
3109 width = rect->size.width;
3110 height = rect->size.height;
3111 x = rect->pos.x;
3112 y = rect->pos.y;
3114 if (state & WLDSSelected)
3115 WMPaintColorSwatch(white, d, x +15, y, width -15, height);
3116 else
3117 XClearArea(dpy, d, x +15, y, width -15, height, False);
3119 fillColor = WMCreateRGBColor(scr, color.red*256, color.green*256, color.blue*256, False);
3121 WMSetColorInGC(fillColor, WMColorGC(fillColor));
3122 WMPaintColorSwatch(fillColor, d, x, y, 15, 15);
3123 WMReleaseColor(fillColor);
3125 WMDrawString(scr, d, WMColorGC(black), panel->font12, x+18, y, text, strlen(text));
3127 WMReleaseColor(white);
3128 WMReleaseColor(black);
3132 static void
3133 colorListSelect(WMWidget *w, void *data)
3135 W_ColorPanel *panel = (W_ColorPanel *)data;
3136 RColor color = *((RColor *)WMGetListSelectedItem(w)->clientData);
3138 panel->lastChanged = WMColorListModeColorPanel;
3139 updateSwatch(panel, color);
3143 static void
3144 colorListColorMenuCallback(WMWidget *w, void *data)
3146 W_ColorPanel *panel = (W_ColorPanel *)data;
3147 int item = WMGetPopUpButtonSelectedItem(panel->colorListColorMenuBtn);
3149 switch (item) {
3150 case CLmenuAdd:
3151 break;
3152 case CLmenuRename:
3153 break;
3154 case CLmenuRemove:
3155 break;
3160 static void
3161 colorListListMenuCallback(WMWidget *w, void *data)
3163 W_ColorPanel *panel = (W_ColorPanel *)data;
3164 int item = WMGetPopUpButtonSelectedItem(panel->colorListListMenuBtn);
3166 switch (item) {
3167 case CLmenuAdd:
3168 /* New Color List */
3169 colorListListMenuNew(panel);
3170 break;
3171 case CLmenuRename:
3172 break;
3173 case CLmenuRemove:
3174 break;
3179 static void
3180 colorListListMenuNew(W_ColorPanel *panel)
3186 /************************** Common utility functions ************************/
3188 static int
3189 fetchFile(char *toPath, char *srcFile, char *destFile)
3191 int src, dest;
3192 int n;
3193 char *tmp;
3194 char buf[BUFSIZE];
3196 if ((src = open(srcFile, O_RDONLY)) == 0) {
3197 wsyserror("Could not open %s", srcFile);
3198 return -1;
3201 tmp = wstrappend(toPath, destFile);
3202 if ((dest = open( tmp, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == 0) {
3203 wsyserror("Could not create %s", tmp);
3204 free(tmp);
3205 return -1;
3207 free(tmp);
3210 /* Copy the file */
3211 while ((n = read(src, buf, BUFSIZE)) > 0)
3213 if (write (dest, buf, n) != n) {
3214 wsyserror("Write error on file %s", destFile);
3215 return -1;
3219 return 0;
3223 char*
3224 generateNewFilename(char *curName)
3226 int n;
3227 char c;
3228 int baseLen;
3229 char *ptr;
3230 char *newName;
3232 ptr = curName;
3234 while ((ptr = strrchr(ptr, '{')) && !(sscanf(ptr, "{%i}%c", &n, &c)==1)) {
3235 ptr++;
3237 if (!ptr)
3238 return wstrappend(curName, " {1}");
3240 baseLen = ptr - curName -1;
3242 newName = wmalloc(baseLen + 16);
3243 strncpy(newName, curName, baseLen);
3244 newName[baseLen] = 0;
3246 sprintf(&newName[baseLen], " {%i}", n+1);
3248 return newName;