*** empty log message ***
[wmaker-crm.git] / WINGs / wcolorpanel.c
blob0f07a5879daa33e40e5fada6286b98d82a049cfa
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 = 4
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 /* Common Stuff */
100 WMColorWell *colorWell;
101 WMButton *magnifyBtn;
102 WMButton *wheelBtn;
103 WMButton *slidersBtn;
104 WMButton *customPaletteBtn;
105 WMButton *colorListBtn;
107 /* Magnifying Glass */
108 MovingView *magnifyGlass;
110 /* ColorWheel Panel */
111 WMFrame *wheelFrm;
112 WMSlider *wheelBrightnessS;
113 WMView *wheelView;
115 /* Slider Panels */
116 WMFrame *slidersFrm;
117 WMFrame *seperatorFrm;
118 WMButton *grayBtn;
119 WMButton *rgbBtn;
120 WMButton *cmykBtn;
121 WMButton *hsbBtn;
122 /* Gray Scale Panel */
123 WMFrame *grayFrm;
124 WMLabel *grayMinL;
125 WMLabel *grayMaxL;
126 WMSlider *grayBrightnessS;
127 WMTextField *grayBrightnessT;
128 WMButton *grayPresetBtn[7];
130 /* RGB Panel */
131 WMFrame *rgbFrm;
132 WMLabel *rgbMinL;
133 WMLabel *rgbMaxL;
134 WMSlider *rgbRedS;
135 WMSlider *rgbGreenS;
136 WMSlider *rgbBlueS;
137 WMTextField *rgbRedT;
138 WMTextField *rgbGreenT;
139 WMTextField *rgbBlueT;
141 /* CMYK Panel */
142 WMFrame *cmykFrm;
143 WMLabel *cmykMinL;
144 WMLabel *cmykMaxL;
145 WMSlider *cmykCyanS;
146 WMSlider *cmykMagentaS;
147 WMSlider *cmykYellowS;
148 WMSlider *cmykBlackS;
149 WMTextField *cmykCyanT;
150 WMTextField *cmykMagentaT;
151 WMTextField *cmykYellowT;
152 WMTextField *cmykBlackT;
154 /* HSB Panel */
155 WMFrame *hsbFrm;
156 WMSlider *hsbHueS;
157 WMSlider *hsbSaturationS;
158 WMSlider *hsbBrightnessS;
159 WMTextField *hsbHueT;
160 WMTextField *hsbSaturationT;
161 WMTextField *hsbBrightnessT;
163 /* Custom Palette Panel*/
164 WMFrame *customPaletteFrm;
165 WMPopUpButton *customPaletteHistoryBtn;
166 WMFrame *customPaletteContentFrm;
167 WMPopUpButton *customPaletteMenuBtn;
168 WMView *customPaletteContentView;
170 /* Color List Panel */
171 WMFrame *colorListFrm;
172 WMPopUpButton *colorListHistoryBtn;
173 WMList *colorListContentLst;
174 WMPopUpButton *colorListColorMenuBtn;
175 WMPopUpButton *colorListListMenuBtn;
177 /* Look-Up Tables and Images */
178 wheelMatrix *wheelMtrx;
179 Pixmap wheelImg;
180 Pixmap selectionImg;
181 Pixmap selectionBackImg;
182 RImage *customPaletteImg;
183 char *lastBrowseDir;
185 /* Common Data Fields */
186 RColor color; /* Current color */
187 RHSVColor hsvcolor; /* Backup HSV Color */
188 WMColorPanelMode mode; /* Current color selection mode */
189 WMColorPanelMode slidersmode; /* Current color selection mode at sliders panel */
190 WMColorPanelMode lastChanged; /* Panel that last changed the color */
191 int colx, coly; /* (x,y) of selection-marker in WheelMode */
192 int palx, paly; /* (x,y) of selection-marker in CustomPaletteMode */
193 float palXRatio, palYRatio; /* Ratios in x & y between original and scaled palettesize */
194 int currentPalette;
195 char *configurationPath;
197 struct {
198 unsigned int dragging:1;
199 unsigned int done:1;
200 } flags;
201 } W_ColorPanel;
203 enum {
204 CPmenuNewFromFile,
205 CPmenuRename,
206 CPmenuRemove,
207 CPmenuCopy,
208 CPmenuNewFromClipboard
209 } customPaletteMenuItem;
211 enum {
212 CLmenuAdd,
213 CLmenuRename,
214 CLmenuRemove
215 } colorListMenuItem;
218 #define PWIDTH 194
219 #define PHEIGHT 266
220 #define colorWheelSize 150
221 #define customPaletteWidth 182
222 #define customPaletteHeight 106
223 #define knobThickness 8
225 #define SPECTRUM_WIDTH 511
226 #define SPECTRUM_HEIGHT 360
228 #define COLORWHEEL_PART 1
229 #define CUSTOMPALETTE_PART 2
230 #define BUFSIZE 1024
232 #undef EASTEREGG
234 #define RGBTXT "/usr/X11R6/lib/X11/rgb.txt"
235 #define MAX_LENGTH 1024
237 static int fetchFile(char* toPath, char *imageSrcFile, char *imageDestFileName);
238 char *generateNewFilename(char *curName);
240 static void modeButtonCallback(WMWidget *w, void *data);
241 static int getPickerPart(W_ColorPanel *panel, int x, int y);
242 static void readConfiguration(W_ColorPanel *panel);
243 static void readXColors(W_ColorPanel *panel);
245 static Cursor magnifyGrabPointer(W_ColorPanel *panel);
246 static WMPoint magnifyInitialize(W_ColorPanel *panel);
247 static void magnifyPutCursor(WMWidget *w, void *data);
248 static Pixmap magnifyCreatePixmap(WMColorPanel *panel);
249 static Pixmap magnifyGetStorePixmap(W_ColorPanel *panel, int x1, int y1, int x2, int y2);
250 static Pixmap magnifyGetImage(WMScreen *scr, int x, int y);
252 static wheelMatrix* wheelCreateMatrix(unsigned int width , unsigned int height);
253 static void wheelDestroyMatrix(wheelMatrix *matrix);
254 static wheelMatrix* wheelInitMatrix(W_ColorPanel *panel);
255 static void wheelRender(W_ColorPanel *panel);
256 static Bool wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs);
257 static void wheelPaint(W_ColorPanel *panel);
259 static void wheelHandleEvents(XEvent *event, void *data);
260 static void wheelHandleActionEvents(XEvent *event, void *data);
261 static void wheelBrightnessSliderCallback(WMWidget *w, void *data);
262 static void wheelUpdateSelection(W_ColorPanel *panel);
263 static void wheelUndrawSelection(W_ColorPanel *panel);
265 static void wheelPositionSelection(W_ColorPanel *panel, int x, int y);
266 static void wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y);
267 static void wheelUpdateBrightnessGradientFromHSV (W_ColorPanel *panel, RHSVColor topColor);
268 static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel *panel);
269 static void wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor);
271 static void grayBrightnessSliderCallback(WMWidget *w, void *data);
272 static void grayPresetButtonCallback(WMWidget *w, void *data);
273 static void grayBrightnessTextFieldCallback(void *observerData, WMNotification *notification);
275 static void rgbSliderCallback(WMWidget *w, void *data);
276 static void rgbTextFieldCallback(void *observerData, WMNotification *notification);
278 static void cmykSliderCallback(WMWidget *w, void *data);
279 static void cmykTextFieldCallback(void *observerData, WMNotification *notification);
281 static void hsbSliderCallback(WMWidget *w, void *data);
282 static void hsbTextFieldCallback(void *observerData, WMNotification *notification);
283 static void hsbUpdateBrightnessGradient(W_ColorPanel *panel);
284 static void hsbUpdateSaturationGradient(W_ColorPanel *panel);
285 static void hsbUpdateHueGradient(W_ColorPanel *panel);
287 static void customRenderSpectrum(W_ColorPanel *panel);
288 static void customSetPalette(W_ColorPanel *panel);
289 static void customPaletteHandleEvents(XEvent *event, void *data);
290 static void customPaletteHandleActionEvents(XEvent *event, void *data);
291 static void customPalettePositionSelection(W_ColorPanel *panel, int x, int y);
292 static void customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y);
293 static void customPaletteMenuCallback(WMWidget *w, void *data);
294 static void customPaletteHistoryCallback(WMWidget *w, void *data);
296 static void customPaletteMenuNewFromFile(W_ColorPanel *panel);
297 static void customPaletteMenuRename(W_ColorPanel *panel);
298 static void customPaletteMenuRemove(W_ColorPanel *panel);
300 static void colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text, int state, WMRect *rect);
301 static void colorListSelect(WMWidget *w, void *data);
302 static void colorListColorMenuCallback(WMWidget *w, void *data);
303 static void colorListListMenuCallback(WMWidget *w, void *data);
304 static void colorListListMenuNew(W_ColorPanel *panel);
306 static void wheelInit(W_ColorPanel *panel);
307 static void grayInit(W_ColorPanel *panel);
308 static void rgbInit(W_ColorPanel *panel);
309 static void cmykInit(W_ColorPanel *panel);
310 static void hsbInit(W_ColorPanel *panel);
313 static WMColorPanel*
314 makeColorPanel(WMScreen *scrPtr, char *name)
316 WMColorPanel *panel;
317 RImage *image;
318 WMPixmap *pixmap;
319 RColor from;
320 RColor to;
321 WMColor *textcolor;
322 int i;
323 int x,y;
326 panel = wmalloc(sizeof(WMColorPanel));
327 memset(panel, 0, sizeof(WMColorPanel));
329 panel->font8 = WMSystemFontOfSize(scrPtr, 8);
330 panel->font12 = WMSystemFontOfSize(scrPtr, 12);
332 panel->win = WMCreateWindowWithStyle(scrPtr, name, WMTitledWindowMask | WMClosableWindowMask | WMResizableWindowMask);
333 WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
334 WMSetWindowTitle(panel->win, "Colors");
337 /* Set Default ColorPanel Mode(s) */
338 panel->mode = WMWheelModeColorPanel;
339 panel->lastChanged = WMWheelModeColorPanel;
340 panel->slidersmode = WMRGBModeColorPanel;
341 panel->configurationPath = wstrappend(wusergnusteppath(), "/Library/Colors/");
343 /* Some Generic Purpose Widgets */
344 panel->colorWell = WMCreateColorWell(panel->win);
345 WMResizeWidget(panel->colorWell, 134, 36);
346 WSetColorWellBordered(panel->colorWell, False);
347 WMMoveWidget(panel->colorWell, 56, 4);
349 panel->magnifyBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
350 WMResizeWidget(panel->magnifyBtn, 46, 36);
351 WMMoveWidget(panel->magnifyBtn, 6,4);
352 WMSetButtonAction(panel->magnifyBtn, magnifyPutCursor, panel);
353 WMSetButtonImagePosition(panel->magnifyBtn, WIPImageOnly);
354 WMSetButtonImage(panel->magnifyBtn, scrPtr->magnifyIcon);
356 panel->wheelBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
357 WMResizeWidget(panel->wheelBtn, 46, 32);
358 WMMoveWidget(panel->wheelBtn, 6, 44);
359 WMSetButtonAction(panel->wheelBtn, modeButtonCallback, panel);
360 WMSetButtonImagePosition(panel->wheelBtn, WIPImageOnly);
361 WMSetButtonImage(panel->wheelBtn, scrPtr->wheelIcon);
363 panel->slidersBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
364 WMResizeWidget(panel->slidersBtn, 46, 32);
365 WMMoveWidget(panel->slidersBtn, 52, 44);
366 WMSetButtonAction(panel->slidersBtn, modeButtonCallback, panel);
367 WMSetButtonImagePosition(panel->slidersBtn, WIPImageOnly);
368 WMSetButtonImage(panel->slidersBtn, scrPtr->rgbIcon);
370 panel->customPaletteBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
371 WMResizeWidget(panel->customPaletteBtn, 46, 32);
372 WMMoveWidget(panel->customPaletteBtn, 98, 44);
373 WMSetButtonAction(panel->customPaletteBtn, modeButtonCallback, panel);
374 WMSetButtonImagePosition(panel->customPaletteBtn, WIPImageOnly);
375 WMSetButtonImage(panel->customPaletteBtn, scrPtr->customPaletteIcon);
377 panel->colorListBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask);
378 WMResizeWidget(panel->colorListBtn, 46, 32);
379 WMMoveWidget(panel->colorListBtn, 144, 44);
380 WMSetButtonAction(panel->colorListBtn, modeButtonCallback, panel);
381 WMSetButtonImagePosition(panel->colorListBtn, WIPImageOnly);
382 WMSetButtonImage(panel->colorListBtn, scrPtr->colorListIcon);
384 /* Let's Group some of them together */
385 WMGroupButtons(panel->wheelBtn, panel->slidersBtn);
386 WMGroupButtons(panel->wheelBtn, panel->customPaletteBtn);
387 WMGroupButtons(panel->wheelBtn, panel->colorListBtn);
389 /* Widgets for the ColorWheel Panel */
390 panel->wheelFrm = WMCreateFrame(panel->win);
391 WMSetFrameRelief(panel->wheelFrm, WRFlat);
392 WMResizeWidget(panel->wheelFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
393 WMMoveWidget(panel->wheelFrm, 5, 80);
395 panel->wheelView = W_CreateView(W_VIEW(panel->wheelFrm));
396 /* XXX Can we create a view ? */
397 W_ResizeView(panel->wheelView, colorWheelSize+4, colorWheelSize+4);
398 W_MoveView(panel->wheelView, 0, 0);
400 /* Create an event handler to handle expose/click events in the ColorWheel */
401 WMCreateEventHandler(panel->wheelView, ButtonPressMask|ButtonReleaseMask|EnterWindowMask
402 |LeaveWindowMask|ButtonMotionMask, wheelHandleActionEvents, panel);
404 WMCreateEventHandler(panel->wheelView, ExposureMask, wheelHandleEvents, panel);
406 panel->wheelBrightnessS = WMCreateSlider(panel->wheelFrm);
407 WMResizeWidget(panel->wheelBrightnessS, 16, 153);
408 WMMoveWidget(panel->wheelBrightnessS, 5+colorWheelSize+14, 1);
409 WMSetSliderMinValue(panel->wheelBrightnessS, 0);
410 WMSetSliderMaxValue(panel->wheelBrightnessS, 255);
411 WMSetSliderAction(panel->wheelBrightnessS, wheelBrightnessSliderCallback, panel);
412 WMSetSliderKnobThickness(panel->wheelBrightnessS, knobThickness);
415 /* Widgets for the Slider Panels */
416 panel->slidersFrm = WMCreateFrame(panel->win);
417 WMSetFrameRelief(panel->slidersFrm, WRFlat);
418 WMResizeWidget(panel->slidersFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
419 WMMoveWidget(panel->slidersFrm, 4, 80);
421 panel->seperatorFrm = WMCreateFrame(panel->slidersFrm);
422 WMSetFrameRelief(panel->seperatorFrm, WRPushed);
423 WMResizeWidget(panel->seperatorFrm, PWIDTH - 8, 2);
424 WMMoveWidget(panel->seperatorFrm, 0, 1);
426 panel->grayBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask);
427 WMResizeWidget(panel->grayBtn, 46, 24);
428 WMMoveWidget(panel->grayBtn, 1, 8);
429 WMSetButtonAction(panel->grayBtn, modeButtonCallback, panel);
430 WMSetButtonImagePosition(panel->grayBtn, WIPImageOnly);
431 WMSetButtonImage(panel->grayBtn, scrPtr->grayIcon);
433 panel->rgbBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask);
434 WMResizeWidget(panel->rgbBtn, 46, 24);
435 WMMoveWidget(panel->rgbBtn, 47, 8);
436 WMSetButtonAction(panel->rgbBtn, modeButtonCallback, panel);
437 WMSetButtonImagePosition(panel->rgbBtn, WIPImageOnly);
438 WMSetButtonImage(panel->rgbBtn, scrPtr->rgbIcon);
440 panel->cmykBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask);
441 WMResizeWidget(panel->cmykBtn, 46, 24);
442 WMMoveWidget(panel->cmykBtn, 93, 8);
443 WMSetButtonAction(panel->cmykBtn, modeButtonCallback, panel);
444 WMSetButtonImagePosition(panel->cmykBtn, WIPImageOnly);
445 WMSetButtonImage(panel->cmykBtn, scrPtr->cmykIcon);
447 panel->hsbBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask);
448 WMResizeWidget(panel->hsbBtn, 46, 24);
449 WMMoveWidget(panel->hsbBtn, 139, 8);
450 WMSetButtonAction(panel->hsbBtn, modeButtonCallback, panel);
451 WMSetButtonImagePosition(panel->hsbBtn, WIPImageOnly);
452 WMSetButtonImage(panel->hsbBtn, scrPtr->hsbIcon);
454 /* Let's Group the Slider Panel Buttons Together */
455 WMGroupButtons(panel->grayBtn, panel->rgbBtn);
456 WMGroupButtons(panel->grayBtn, panel->cmykBtn);
457 WMGroupButtons(panel->grayBtn, panel->hsbBtn);
459 textcolor = WMDarkGrayColor(scrPtr);
461 /* Widgets for GrayScale Panel */
462 panel->grayFrm = WMCreateFrame(panel->slidersFrm);
463 WMSetFrameRelief(panel->grayFrm, WRFlat);
464 WMResizeWidget(panel->grayFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
465 WMMoveWidget(panel->grayFrm, 0, 34);
467 panel->grayMinL = WMCreateLabel(panel->grayFrm);
468 WMResizeWidget(panel->grayMinL, 20, 10);
469 WMMoveWidget(panel->grayMinL, 2, 2);
470 WMSetLabelText(panel->grayMinL, "0");
471 WMSetLabelTextAlignment(panel->grayMinL, WALeft);
472 WMSetLabelTextColor(panel->grayMinL, textcolor);
473 WMSetLabelFont(panel->grayMinL, panel->font8);
475 panel->grayMaxL = WMCreateLabel(panel->grayFrm);
476 WMResizeWidget(panel->grayMaxL, 40, 10);
477 WMMoveWidget(panel->grayMaxL, 104, 2);
478 WMSetLabelText(panel->grayMaxL, "100");
479 WMSetLabelTextAlignment(panel->grayMaxL, WARight);
480 WMSetLabelTextColor(panel->grayMaxL, textcolor);
481 WMSetLabelFont(panel->grayMaxL, panel->font8);
483 panel->grayBrightnessS = WMCreateSlider(panel->grayFrm);
484 WMResizeWidget(panel->grayBrightnessS, 141, 16);
485 WMMoveWidget(panel->grayBrightnessS, 2, 14);
486 WMSetSliderMinValue(panel->grayBrightnessS, 0);
487 WMSetSliderMaxValue(panel->grayBrightnessS, 100);
488 WMSetSliderKnobThickness(panel->grayBrightnessS, knobThickness);
489 WMSetSliderAction(panel->grayBrightnessS, grayBrightnessSliderCallback, panel);
491 from.red = 0;
492 from.green = 0;
493 from.blue = 0;
495 to.red = 255;
496 to.green = 255;
497 to.blue = 255;
499 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
500 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
501 RDestroyImage(image);
502 W_PaintText(W_VIEW(panel->grayBrightnessS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scrPtr->white), False, "Brightness", strlen("Brightness"));
503 WMSetSliderImage(panel->grayBrightnessS, pixmap);
504 WMReleasePixmap(pixmap);
506 panel->grayBrightnessT = WMCreateTextField(panel->grayFrm);
507 WMResizeWidget(panel->grayBrightnessT, 40, 18);
508 WMMoveWidget(panel->grayBrightnessT, 146, 13);
509 WMSetTextFieldAlignment(panel->grayBrightnessT, WALeft);
510 WMAddNotificationObserver(grayBrightnessTextFieldCallback, panel, \
511 WMTextDidEndEditingNotification, panel->grayBrightnessT);
513 image = RCreateImage(13,13,False);
514 for (i=0; i < 7; i++) {
515 for (x=0; x < 13; x++) {
516 for (y=0; y < 13; y++) {
517 image->data[0][y*13+x] = 255/6*i;
518 image->data[1][y*13+x] = 255/6*i;
519 image->data[2][y*13+x] = 255/6*i;
522 panel->grayPresetBtn[i] = WMCreateCommandButton(panel->grayFrm);
523 WMResizeWidget(panel->grayPresetBtn[i], 20, 24);
524 WMMoveWidget(panel->grayPresetBtn[i], 2+(i*20), 34);
525 WMSetButtonAction(panel->grayPresetBtn[i], grayPresetButtonCallback, panel);
526 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
527 WMSetButtonImage(panel->grayPresetBtn[i], pixmap);
528 WMSetButtonImagePosition(panel->grayPresetBtn[i], WIPImageOnly);
529 WMReleasePixmap(pixmap);
531 RDestroyImage(image);
532 /* End of GrayScale Panel */
534 /* Widgets for RGB Panel */
535 panel->rgbFrm = WMCreateFrame(panel->slidersFrm);
536 WMSetFrameRelief(panel->rgbFrm, WRFlat);
537 WMResizeWidget(panel->rgbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
538 WMMoveWidget(panel->rgbFrm, 0, 34);
540 panel->rgbMinL = WMCreateLabel(panel->rgbFrm);
541 WMResizeWidget(panel->rgbMinL, 20, 10);
542 WMMoveWidget(panel->rgbMinL, 2, 2);
543 WMSetLabelText(panel->rgbMinL, "0");
544 WMSetLabelTextAlignment(panel->rgbMinL, WALeft);
545 WMSetLabelTextColor(panel->rgbMinL, textcolor);
546 WMSetLabelFont(panel->rgbMinL, panel->font8);
548 panel->rgbMaxL = WMCreateLabel(panel->rgbFrm);
549 WMResizeWidget(panel->rgbMaxL, 40, 10);
550 WMMoveWidget(panel->rgbMaxL, 104, 2);
551 WMSetLabelText(panel->rgbMaxL, "255");
552 WMSetLabelTextAlignment(panel->rgbMaxL, WARight);
553 WMSetLabelTextColor(panel->rgbMaxL, textcolor);
554 WMSetLabelFont(panel->rgbMaxL, panel->font8);
556 panel->rgbRedS = WMCreateSlider(panel->rgbFrm);
557 WMResizeWidget(panel->rgbRedS, 141, 16);
558 WMMoveWidget(panel->rgbRedS, 2, 14);
559 WMSetSliderMinValue(panel->rgbRedS, 0);
560 WMSetSliderMaxValue(panel->rgbRedS, 255);
561 WMSetSliderKnobThickness(panel->rgbRedS, knobThickness);
562 WMSetSliderAction(panel->rgbRedS, rgbSliderCallback, panel);
564 to.red = 255;
565 to.green = 0;
566 to.blue = 0;
568 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
569 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
570 W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scrPtr->white), False, "Red", strlen("Red"));
571 RDestroyImage(image);
572 WMSetSliderImage(panel->rgbRedS, pixmap);
573 WMReleasePixmap(pixmap);
575 panel->rgbRedT = WMCreateTextField(panel->rgbFrm);
576 WMResizeWidget(panel->rgbRedT, 40, 18);
577 WMMoveWidget(panel->rgbRedT, 146, 13);
578 WMSetTextFieldAlignment(panel->rgbRedT, WALeft);
579 WMAddNotificationObserver(rgbTextFieldCallback, panel, \
580 WMTextDidEndEditingNotification, panel->rgbRedT);
583 panel->rgbGreenS = WMCreateSlider(panel->rgbFrm);
584 WMResizeWidget(panel->rgbGreenS, 141, 16);
585 WMMoveWidget(panel->rgbGreenS, 2, 36);
586 WMSetSliderMinValue(panel->rgbGreenS, 0);
587 WMSetSliderMaxValue(panel->rgbGreenS, 255);
588 WMSetSliderKnobThickness(panel->rgbGreenS, knobThickness);
589 WMSetSliderAction(panel->rgbGreenS, rgbSliderCallback, panel);
591 to.red = 0;
592 to.green = 255;
593 to.blue = 0;
595 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
596 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
597 W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scrPtr->white), False, "Green", strlen("Green"));
598 RDestroyImage(image);
599 WMSetSliderImage(panel->rgbGreenS, pixmap);
600 WMReleasePixmap(pixmap);
602 panel->rgbGreenT = WMCreateTextField(panel->rgbFrm);
603 WMResizeWidget(panel->rgbGreenT, 40, 18);
604 WMMoveWidget(panel->rgbGreenT, 146, 35);
605 WMSetTextFieldAlignment(panel->rgbGreenT, WALeft);
606 WMAddNotificationObserver(rgbTextFieldCallback, panel, \
607 WMTextDidEndEditingNotification, panel->rgbGreenT);
610 panel->rgbBlueS = WMCreateSlider(panel->rgbFrm);
611 WMResizeWidget(panel->rgbBlueS, 141, 16);
612 WMMoveWidget(panel->rgbBlueS, 2, 58);
613 WMSetSliderMinValue(panel->rgbBlueS, 0);
614 WMSetSliderMaxValue(panel->rgbBlueS, 255);
615 WMSetSliderKnobThickness(panel->rgbBlueS, knobThickness);
616 WMSetSliderAction(panel->rgbBlueS, rgbSliderCallback, panel);
618 to.red = 0;
619 to.green = 0;
620 to.blue = 255;
622 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
623 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
624 W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scrPtr->white), False, "Blue", strlen("Blue"));
625 RDestroyImage(image);
626 WMSetSliderImage(panel->rgbBlueS, pixmap);
627 WMReleasePixmap(pixmap);
629 panel->rgbBlueT = WMCreateTextField(panel->rgbFrm);
630 WMResizeWidget(panel->rgbBlueT, 40, 18);
631 WMMoveWidget(panel->rgbBlueT, 146, 57);
632 WMSetTextFieldAlignment(panel->rgbBlueT, WALeft);
633 WMAddNotificationObserver(rgbTextFieldCallback, panel, \
634 WMTextDidEndEditingNotification, panel->rgbBlueT);
635 /* End of RGB Panel */
637 /* Widgets for CMYK Panel */
638 panel->cmykFrm = WMCreateFrame(panel->slidersFrm);
639 WMSetFrameRelief(panel->cmykFrm, WRFlat);
640 WMResizeWidget(panel->cmykFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
641 WMMoveWidget(panel->cmykFrm, 0, 34);
643 panel->cmykMinL = WMCreateLabel(panel->cmykFrm);
644 WMResizeWidget(panel->cmykMinL, 20, 10);
645 WMMoveWidget(panel->cmykMinL, 2, 2);
646 WMSetLabelText(panel->cmykMinL, "0");
647 WMSetLabelTextAlignment(panel->cmykMinL, WALeft);
648 WMSetLabelTextColor(panel->cmykMinL, textcolor);
649 WMSetLabelFont(panel->cmykMinL, panel->font8);
651 panel->cmykMaxL = WMCreateLabel(panel->cmykFrm);
652 WMResizeWidget(panel->cmykMaxL, 40, 10);
653 WMMoveWidget(panel->cmykMaxL, 104, 2);
654 WMSetLabelText(panel->cmykMaxL, "100");
655 WMSetLabelTextAlignment(panel->cmykMaxL, WARight);
656 WMSetLabelTextColor(panel->cmykMaxL, textcolor);
657 WMSetLabelFont(panel->cmykMaxL, panel->font8);
659 panel->cmykCyanS = WMCreateSlider(panel->cmykFrm);
660 WMResizeWidget(panel->cmykCyanS, 141, 16);
661 WMMoveWidget(panel->cmykCyanS, 2, 14);
662 WMSetSliderMinValue(panel->cmykCyanS, 0);
663 WMSetSliderMaxValue(panel->cmykCyanS, 100);
664 WMSetSliderKnobThickness(panel->cmykCyanS, knobThickness);
665 WMSetSliderAction(panel->cmykCyanS, cmykSliderCallback, panel);
667 from.red = 255;
668 from.green = 255;
669 from.blue = 255;
671 to.red = 0;
672 to.green = 255;
673 to.blue = 255;
675 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
676 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
677 W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scrPtr->black), False, "Cyan", strlen("Cyan"));
678 RDestroyImage(image);
679 WMSetSliderImage(panel->cmykCyanS, pixmap);
680 WMReleasePixmap(pixmap);
682 panel->cmykCyanT = WMCreateTextField(panel->cmykFrm);
683 WMResizeWidget(panel->cmykCyanT, 40, 18);
684 WMMoveWidget(panel->cmykCyanT, 146, 13);
685 WMSetTextFieldAlignment(panel->cmykCyanT, WALeft);
686 WMAddNotificationObserver(cmykTextFieldCallback, panel, \
687 WMTextDidEndEditingNotification, panel->cmykCyanT);
690 panel->cmykMagentaS = WMCreateSlider(panel->cmykFrm);
691 WMResizeWidget(panel->cmykMagentaS, 141, 16);
692 WMMoveWidget(panel->cmykMagentaS, 2, 36);
693 WMSetSliderMinValue(panel->cmykMagentaS, 0);
694 WMSetSliderMaxValue(panel->cmykMagentaS, 100);
695 WMSetSliderKnobThickness(panel->cmykMagentaS, knobThickness);
696 WMSetSliderAction(panel->cmykMagentaS, cmykSliderCallback, panel);
698 to.red = 255;
699 to.green = 0;
700 to.blue = 255;
702 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
703 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
704 W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scrPtr->black), False, "Magenta", strlen("Magenta"));
705 RDestroyImage(image);
706 WMSetSliderImage(panel->cmykMagentaS, pixmap);
707 WMReleasePixmap(pixmap);
709 panel->cmykMagentaT = WMCreateTextField(panel->cmykFrm);
710 WMResizeWidget(panel->cmykMagentaT, 40, 18);
711 WMMoveWidget(panel->cmykMagentaT, 146, 35);
712 WMSetTextFieldAlignment(panel->cmykMagentaT, WALeft);
713 WMAddNotificationObserver(cmykTextFieldCallback, panel, \
714 WMTextDidEndEditingNotification, panel->cmykMagentaT);
717 panel->cmykYellowS = WMCreateSlider(panel->cmykFrm);
718 WMResizeWidget(panel->cmykYellowS, 141, 16);
719 WMMoveWidget(panel->cmykYellowS, 2, 58);
720 WMSetSliderMinValue(panel->cmykYellowS, 0);
721 WMSetSliderMaxValue(panel->cmykYellowS, 100);
722 WMSetSliderKnobThickness(panel->cmykYellowS, knobThickness);
723 WMSetSliderAction(panel->cmykYellowS, cmykSliderCallback, panel);
725 to.red = 255;
726 to.green = 255;
727 to.blue = 0;
729 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
730 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
731 W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scrPtr->black), False, "Yellow", strlen("Yellow"));
732 RDestroyImage(image);
733 WMSetSliderImage(panel->cmykYellowS, pixmap);
734 WMReleasePixmap(pixmap);
736 panel->cmykYellowT = WMCreateTextField(panel->cmykFrm);
737 WMResizeWidget(panel->cmykYellowT, 40, 18);
738 WMMoveWidget(panel->cmykYellowT, 146, 57);
739 WMSetTextFieldAlignment(panel->cmykYellowT, WALeft);
740 WMAddNotificationObserver(cmykTextFieldCallback, panel, \
741 WMTextDidEndEditingNotification, panel->cmykYellowT);
744 panel->cmykBlackS = WMCreateSlider(panel->cmykFrm);
745 WMResizeWidget(panel->cmykBlackS, 141, 16);
746 WMMoveWidget(panel->cmykBlackS, 2, 80);
747 WMSetSliderMinValue(panel->cmykBlackS, 0);
748 WMSetSliderMaxValue(panel->cmykBlackS, 100);
749 WMSetSliderValue(panel->cmykBlackS, 0);
750 WMSetSliderKnobThickness(panel->cmykBlackS, knobThickness);
751 WMSetSliderAction(panel->cmykBlackS, cmykSliderCallback, panel);
753 to.red = 0;
754 to.green = 0;
755 to.blue = 0;
757 image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
758 pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
759 W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scrPtr->black), False, "Black", strlen("Black"));
760 RDestroyImage(image);
761 WMSetSliderImage(panel->cmykBlackS, pixmap);
762 WMReleasePixmap(pixmap);
764 panel->cmykBlackT = WMCreateTextField(panel->cmykFrm);
765 WMResizeWidget(panel->cmykBlackT, 40, 18);
766 WMMoveWidget(panel->cmykBlackT, 146, 79);
767 WMSetTextFieldAlignment(panel->cmykBlackT, WALeft);
768 WMAddNotificationObserver(cmykTextFieldCallback, panel, \
769 WMTextDidEndEditingNotification, panel->cmykBlackT);
770 /* End of CMYK Panel */
772 /* Widgets for HSB Panel */
773 panel->hsbFrm = WMCreateFrame(panel->slidersFrm);
774 WMSetFrameRelief(panel->hsbFrm, WRFlat);
775 WMResizeWidget(panel->hsbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
776 WMMoveWidget(panel->hsbFrm, 0, 34);
778 panel->hsbHueS = WMCreateSlider(panel->hsbFrm);
779 WMResizeWidget(panel->hsbHueS, 141, 16);
780 WMMoveWidget(panel->hsbHueS, 2, 14);
781 WMSetSliderMinValue(panel->hsbHueS, 0);
782 WMSetSliderMaxValue(panel->hsbHueS, 359);
783 WMSetSliderKnobThickness(panel->hsbHueS, knobThickness);
784 WMSetSliderAction(panel->hsbHueS, hsbSliderCallback, panel);
786 panel->hsbHueT = WMCreateTextField(panel->hsbFrm);
787 WMResizeWidget(panel->hsbHueT, 40, 18);
788 WMMoveWidget(panel->hsbHueT, 146, 13);
789 WMSetTextFieldAlignment(panel->hsbHueT, WALeft);
790 WMAddNotificationObserver(hsbTextFieldCallback, panel, \
791 WMTextDidEndEditingNotification, panel->hsbHueT);
794 panel->hsbSaturationS = WMCreateSlider(panel->hsbFrm);
795 WMResizeWidget(panel->hsbSaturationS, 141, 16);
796 WMMoveWidget(panel->hsbSaturationS, 2, 36);
797 WMSetSliderMinValue(panel->hsbSaturationS, 0);
798 WMSetSliderMaxValue(panel->hsbSaturationS, 100);
799 WMSetSliderKnobThickness(panel->hsbSaturationS, knobThickness);
800 WMSetSliderAction(panel->hsbSaturationS, hsbSliderCallback, panel);
802 panel->hsbSaturationT = WMCreateTextField(panel->hsbFrm);
803 WMResizeWidget(panel->hsbSaturationT, 40, 18);
804 WMMoveWidget(panel->hsbSaturationT, 146, 35);
805 WMSetTextFieldAlignment(panel->hsbSaturationT, WALeft);
806 WMAddNotificationObserver(hsbTextFieldCallback, panel, \
807 WMTextDidEndEditingNotification, panel->hsbSaturationT);
810 panel->hsbBrightnessS = WMCreateSlider(panel->hsbFrm);
811 WMResizeWidget(panel->hsbBrightnessS, 141, 16);
812 WMMoveWidget(panel->hsbBrightnessS, 2, 58);
813 WMSetSliderMinValue(panel->hsbBrightnessS, 0);
814 WMSetSliderMaxValue(panel->hsbBrightnessS, 100);
815 WMSetSliderKnobThickness(panel->hsbBrightnessS, knobThickness);
816 WMSetSliderAction(panel->hsbBrightnessS, hsbSliderCallback, panel);
818 panel->hsbBrightnessT = WMCreateTextField(panel->hsbFrm);
819 WMResizeWidget(panel->hsbBrightnessT, 40, 18);
820 WMMoveWidget(panel->hsbBrightnessT, 146, 57);
821 WMSetTextFieldAlignment(panel->hsbBrightnessT, WALeft);
822 WMAddNotificationObserver(hsbTextFieldCallback, panel, \
823 WMTextDidEndEditingNotification, panel->hsbBrightnessT);
824 /* End of HSB Panel */
827 WMReleaseColor(textcolor);
829 /* Widgets for the CustomPalette Panel */
830 panel->customPaletteFrm = WMCreateFrame(panel->win);
831 WMSetFrameRelief(panel->customPaletteFrm, WRFlat);
832 WMResizeWidget(panel->customPaletteFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
833 WMMoveWidget(panel->customPaletteFrm, 5, 80);
835 panel->customPaletteHistoryBtn = WMCreatePopUpButton(panel->customPaletteFrm);
836 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, "Spectrum");
837 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn)-1);
838 WMSetPopUpButtonAction(panel->customPaletteHistoryBtn, customPaletteHistoryCallback, panel);
839 WMResizeWidget(panel->customPaletteHistoryBtn, PWIDTH - 8, 20);
840 WMMoveWidget(panel->customPaletteHistoryBtn, 0, 0);
842 panel->customPaletteContentFrm = WMCreateFrame(panel->customPaletteFrm);
843 WMSetFrameRelief(panel->customPaletteContentFrm, WRSunken);
844 WMResizeWidget(panel->customPaletteContentFrm, PWIDTH - 8, PHEIGHT - 156);
845 WMMoveWidget(panel->customPaletteContentFrm, 0, 23);
847 panel->customPaletteContentView = W_CreateView(W_VIEW(panel->customPaletteContentFrm));
848 /* XXX Can we create a view ? */
849 W_ResizeView(panel->customPaletteContentView, customPaletteWidth, customPaletteHeight);
850 W_MoveView(panel->customPaletteContentView, 2, 2);
852 /* Create an event handler to handle expose/click events in the CustomPalette */
853 WMCreateEventHandler(panel->customPaletteContentView, ButtonPressMask|ButtonReleaseMask|EnterWindowMask
854 |LeaveWindowMask|ButtonMotionMask, customPaletteHandleActionEvents, panel);
856 WMCreateEventHandler(panel->customPaletteContentView, ExposureMask, customPaletteHandleEvents, panel);
858 panel->customPaletteMenuBtn = WMCreatePopUpButton(panel->customPaletteFrm);
859 WMSetPopUpButtonPullsDown(panel->customPaletteMenuBtn, 1);
860 WMSetPopUpButtonText(panel->customPaletteMenuBtn, "Palette");
861 WMSetPopUpButtonAction(panel->customPaletteMenuBtn, customPaletteMenuCallback, panel);
862 WMResizeWidget(panel->customPaletteMenuBtn, PWIDTH - 8, 20);
863 WMMoveWidget(panel->customPaletteMenuBtn, 0, PHEIGHT - 130);
865 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from File...");
866 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Rename...");
867 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Remove");
868 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "Copy");
869 WMAddPopUpButtonItem(panel->customPaletteMenuBtn, "New from Clipboard");
871 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, 0);
872 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, 0);
873 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuCopy, 0);
874 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuNewFromClipboard, 0);
876 customRenderSpectrum(panel);
877 panel->currentPalette = 0;
880 /* Widgets for the ColorList Panel */
881 panel->colorListFrm = WMCreateFrame(panel->win);
882 WMSetFrameRelief(panel->colorListFrm, WRFlat);
883 WMResizeWidget(panel->colorListFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
884 WMMoveWidget(panel->colorListFrm, 5, 80);
886 panel->colorListHistoryBtn = WMCreatePopUpButton(panel->colorListFrm);
887 WMAddPopUpButtonItem(panel->colorListHistoryBtn, "X11-Colors");
888 WMSetPopUpButtonSelectedItem(panel->colorListHistoryBtn, WMGetPopUpButtonNumberOfItems(panel->colorListHistoryBtn)-1);
889 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn, colorListHistoryCallback, panel); */
890 WMResizeWidget(panel->colorListHistoryBtn, PWIDTH - 8, 20);
891 WMMoveWidget(panel->colorListHistoryBtn, 0, 0);
893 panel->colorListContentLst = WMCreateList(panel->colorListFrm);
894 WMSetListAction(panel->colorListContentLst, colorListSelect, panel);
895 WMSetListUserDrawProc(panel->colorListContentLst, colorListPaintItem);
896 WMResizeWidget(panel->colorListContentLst, PWIDTH - 8, PHEIGHT - 156);
897 WMMoveWidget(panel->colorListContentLst, 0, 23);
898 WMHangData(panel->colorListContentLst, panel);
900 panel->colorListColorMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
901 WMSetPopUpButtonPullsDown(panel->colorListColorMenuBtn, 1);
902 WMSetPopUpButtonText(panel->colorListColorMenuBtn, "Color");
903 WMSetPopUpButtonAction(panel->colorListColorMenuBtn, colorListColorMenuCallback, panel);
904 WMResizeWidget(panel->colorListColorMenuBtn, (PWIDTH - 16)/2, 20);
905 WMMoveWidget(panel->colorListColorMenuBtn, 0, PHEIGHT - 130);
907 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Add...");
908 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Rename...");
909 WMAddPopUpButtonItem(panel->colorListColorMenuBtn, "Remove");
911 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuAdd, 0);
912 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRename, 0);
913 WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRemove, 0);
915 panel->colorListListMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
916 WMSetPopUpButtonPullsDown(panel->colorListListMenuBtn, 1);
917 WMSetPopUpButtonText(panel->colorListListMenuBtn, "List");
918 WMSetPopUpButtonAction(panel->colorListListMenuBtn, colorListListMenuCallback, panel);
919 WMResizeWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2, 20);
920 WMMoveWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2 + 8, PHEIGHT - 130);
922 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "New...");
923 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Rename...");
924 WMAddPopUpButtonItem(panel->colorListListMenuBtn, "Remove");
926 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRename, 0);
927 WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRemove, 0);
929 WMRealizeWidget(panel->win);
930 WMMapSubwidgets(panel->win);
932 WMMapSubwidgets(panel->wheelFrm);
933 WMMapSubwidgets(panel->slidersFrm);
934 WMMapSubwidgets(panel->grayFrm);
935 WMMapSubwidgets(panel->rgbFrm);
936 WMMapSubwidgets(panel->cmykFrm);
937 WMMapSubwidgets(panel->hsbFrm);
938 WMMapSubwidgets(panel->customPaletteFrm);
939 WMMapSubwidgets(panel->customPaletteContentFrm);
940 WMMapSubwidgets(panel->colorListFrm);
942 readConfiguration(panel);
943 readXColors(panel);
945 return panel;
949 WMColorPanel*
950 WMGetColorPanel(WMScreen *scrPtr)
952 WMColorPanel *panel;
954 if (scrPtr->sharedColorPanel)
955 return scrPtr->sharedColorPanel;
957 panel = makeColorPanel(scrPtr, "colorPanel");
959 scrPtr->sharedColorPanel = panel;
961 return panel;
965 void
966 WMFreeColorPanel(WMColorPanel *panel)
968 W_Screen *scr = WMWidgetScreen(panel->win);
970 if (panel == scr->sharedColorPanel) {
971 WMWidgetScreen(panel->win)->sharedColorPanel = NULL;
973 WMRemoveNotificationObserver(panel);
974 WMUnmapWidget(panel->win);
975 WMDestroyWidget(panel->win);
976 if (panel->font8)
977 WMReleaseFont(panel->font8);
978 if (panel->font12)
979 WMReleaseFont(panel->font12);
980 if (panel->magnifyGlass->pixmap)
981 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
982 if (panel->wheelMtrx)
983 wheelDestroyMatrix(panel->wheelMtrx);
984 if (panel->wheelImg)
985 XFreePixmap(scr->display, panel->wheelImg);
986 if (panel->selectionImg)
987 XFreePixmap(scr->display, panel->selectionImg);
988 if (panel->selectionBackImg)
989 XFreePixmap(scr->display, panel->selectionBackImg);
990 if (panel->customPaletteImg)
991 RDestroyImage(panel->customPaletteImg);
992 if (panel->lastBrowseDir)
993 free(panel->lastBrowseDir);
994 if (panel->configurationPath)
995 free(panel->configurationPath);
997 free(panel);
1002 WMRunColorPanel(WMColorPanel *panel, WMWindow *owner, RColor color)
1004 WMScreen *scr = WMWidgetScreen(panel->win);
1005 XEvent event;
1006 RHSVColor hsvcolor;
1007 GC bgc = W_GC(scr->black);
1008 GC wgc = W_GC(scr->white);
1010 WMChangePanelOwner(panel->win, owner);
1012 WMSetColorPanelColor(panel, color);
1013 panel->wheelMtrx = wheelInitMatrix(panel); /* Needs to be done After Color is set */
1015 /* Maybe put this in sub-function ... Initialising selection images */
1016 RRGBtoHSV(&color, &hsvcolor);
1017 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 + (hsvcolor.saturation/255.0) * cos( hsvcolor.hue*M_PI/180.0)));
1018 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 + (hsvcolor.saturation/255.0) * sin(-hsvcolor.hue*M_PI/180.0)));
1019 wheelUpdateBrightnessGradientFromHSV(panel, hsvcolor);
1020 WMSetSliderValue(panel->wheelBrightnessS, 255 - hsvcolor.value);
1022 panel->selectionImg = XCreatePixmap(scr->display, W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
1023 XFillRectangle(scr->display, panel->selectionImg, bgc, 0, 0, 4, 4);
1024 XFillRectangle(scr->display, panel->selectionImg, wgc, 1, 1, 2, 2);
1025 /* End of initialisation section */
1027 panel->palx = customPaletteWidth/2;
1028 panel->paly = customPaletteHeight/2;
1030 WMSetPickerMode(panel, WMWheelModeColorPanel);
1032 panel->flags.done = 0;
1034 WMMapWidget(panel->win);
1036 while (!panel->flags.done) {
1037 WMNextEvent(scr->display, &event);
1038 WMHandleEvent(&event);
1041 WMCloseWindow(panel->win);
1043 return 0;
1048 static void
1049 readConfiguration(W_ColorPanel *panel)
1051 /* XXX Doesn't take care of "invalid" files */
1053 DIR *dPtr;
1054 struct dirent *dp;
1055 struct stat stat_buf;
1058 if (stat(panel->configurationPath, &stat_buf)!=0) {
1059 if (mkdir(panel->configurationPath, S_IRWXU|S_IRGRP|S_IROTH|S_IXGRP|S_IXOTH)!=0) {
1060 wsyserror("ColorPanel could not create directory %s needed to store configurations", panel->configurationPath);
1061 WMSetPopUpButtonEnabled(panel->customPaletteMenuBtn, False);
1062 WMSetPopUpButtonEnabled(panel->colorListColorMenuBtn, False);
1063 WMSetPopUpButtonEnabled(panel->colorListListMenuBtn, False);
1064 WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win, "File Error", "Could not create ColorPanel configuration directory", "OK", NULL, NULL);
1066 return;
1069 dPtr = opendir(panel->configurationPath);
1070 while ((dp = readdir(dPtr)) != NULL) {
1071 if (dp->d_name[0] != '.')
1072 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, dp->d_name);
1074 (void)closedir(dPtr);
1078 static void
1079 readXColors(W_ColorPanel *panel)
1081 struct stat stat_buf;
1082 FILE *rgbtxt;
1083 char line[MAX_LENGTH];
1084 int red, green, blue;
1085 char name[48];
1086 RColor *color;
1087 WMListItem *item;
1089 if (stat(RGBTXT, &stat_buf) != 0) {
1090 wwarning("Cannot find file %s", RGBTXT);
1091 return;
1093 else {
1094 rgbtxt = fopen(RGBTXT, "r");
1095 if (rgbtxt) {
1096 while (fgets(line, MAX_LENGTH, rgbtxt)) {
1097 if (sscanf(line, "%d%d%d %[^\n]", &red, &green, &blue, name)) {
1098 color = wmalloc(sizeof(RColor));
1099 color->red = (unsigned char)red;
1100 color->green = (unsigned char)green;
1101 color->blue = (unsigned char)blue;
1102 item = WMAddListItem(panel->colorListContentLst, name);
1103 item->clientData = (void *)color;
1106 fclose(rgbtxt);
1108 else {
1109 wsyserror("Unable to open file %s for reading", RGBTXT);
1115 void
1116 WMSetPickerMode(WMColorPanel *panel, WMColorPanelMode mode)
1118 W_Screen *scr = WMWidgetScreen(panel->win);
1120 if (mode != WMWheelModeColorPanel) {
1121 WMUnmapWidget(panel->wheelFrm);
1122 if (panel->selectionBackImg) {
1123 XFreePixmap(WMWidgetScreen(panel->win)->display, panel->selectionBackImg);
1124 panel->selectionBackImg = None;
1127 if (mode != WMGrayModeColorPanel)
1128 WMUnmapWidget(panel->grayFrm);
1129 if (mode != WMRGBModeColorPanel)
1130 WMUnmapWidget(panel->rgbFrm);
1131 if (mode != WMCMYKModeColorPanel)
1132 WMUnmapWidget(panel->cmykFrm);
1133 if (mode != WMHSBModeColorPanel)
1134 WMUnmapWidget(panel->hsbFrm);
1135 if (mode != WMCustomPaletteModeColorPanel) {
1136 WMUnmapWidget(panel->customPaletteFrm);
1137 if (panel->selectionBackImg) {
1138 XFreePixmap(WMWidgetScreen(panel->win)->display, panel->selectionBackImg);
1139 panel->selectionBackImg = None;
1142 if (mode != WMColorListModeColorPanel)
1143 WMUnmapWidget(panel->colorListFrm);
1144 if ((mode != WMGrayModeColorPanel) && (mode != WMRGBModeColorPanel) && \
1145 (mode != WMCMYKModeColorPanel) && (mode != WMHSBModeColorPanel))
1146 WMUnmapWidget(panel->slidersFrm);
1147 else
1148 panel->slidersmode = mode;
1150 if (mode == WMWheelModeColorPanel) {
1151 WMMapWidget(panel->wheelFrm);
1152 WMSetButtonSelected(panel->wheelBtn, True);
1153 if (panel->lastChanged != WMWheelModeColorPanel)
1154 wheelInit(panel);
1155 wheelRender(panel);
1156 wheelPaint(panel);
1157 } else if (mode == WMGrayModeColorPanel) {
1158 WMMapWidget(panel->slidersFrm);
1159 WMSetButtonSelected(panel->slidersBtn, True);
1160 WMMapWidget(panel->grayFrm);
1161 WMSetButtonSelected(panel->grayBtn, True);
1162 WMSetButtonImage(panel->slidersBtn, scr->grayIcon);
1163 if (panel->lastChanged != WMGrayModeColorPanel)
1164 grayInit(panel);
1165 } else if (mode == WMRGBModeColorPanel) {
1166 WMMapWidget(panel->slidersFrm);
1167 WMSetButtonSelected(panel->slidersBtn, True);
1168 WMMapWidget(panel->rgbFrm);
1169 WMSetButtonSelected(panel->rgbBtn, True);
1170 WMSetButtonImage(panel->slidersBtn, scr->rgbIcon);
1171 if (panel->lastChanged != WMRGBModeColorPanel)
1172 rgbInit(panel);
1173 } else if (mode == WMCMYKModeColorPanel) {
1174 WMMapWidget(panel->slidersFrm);
1175 WMSetButtonSelected(panel->slidersBtn, True);
1176 WMMapWidget(panel->cmykFrm);
1177 WMSetButtonSelected(panel->cmykBtn, True);
1178 WMSetButtonImage(panel->slidersBtn, scr->cmykIcon);
1179 if (panel->lastChanged != WMCMYKModeColorPanel)
1180 cmykInit(panel);
1181 } else if (mode == WMHSBModeColorPanel) {
1182 WMMapWidget(panel->slidersFrm);
1183 WMSetButtonSelected(panel->slidersBtn, True);
1184 WMMapWidget(panel->hsbFrm);
1185 WMSetButtonSelected(panel->hsbBtn, True);
1186 WMSetButtonImage(panel->slidersBtn, scr->hsbIcon);
1187 if (panel->lastChanged != WMHSBModeColorPanel)
1188 hsbInit(panel);
1189 } else if (mode == WMCustomPaletteModeColorPanel) {
1190 WMMapWidget(panel->customPaletteFrm);
1191 WMSetButtonSelected(panel->customPaletteBtn, True);
1192 customSetPalette(panel);
1193 } else if (mode == WMColorListModeColorPanel) {
1194 WMMapWidget(panel->colorListFrm);
1195 WMSetButtonSelected(panel->colorListBtn, True);
1199 panel->mode = mode;
1202 void
1203 WMSetColorPanelColor(WMColorPanel *panel, RColor color)
1205 WMScreen *scr = WMWidgetScreen(panel->win);
1206 WMColor *wellcolor;
1207 int originalHue;
1209 wellcolor = WMCreateRGBColor(scr, color.red << 8, color.green << 8, color.blue << 8, True);
1210 WMSetColorWellColor(panel->colorWell, wellcolor);
1211 WMReleaseColor(wellcolor);
1213 panel->color = color;
1215 /* If color was set by HSB-Panel do not convert back to hsv */
1216 if (panel->lastChanged != WMHSBModeColorPanel) {
1218 /* if color is black, hue is undetermined, so it must be restored */
1219 if ((panel->color.red == 0) &&
1220 (panel->color.green == 0) &&
1221 (panel->color.blue == 0) &&
1222 (panel->hsvcolor.hue <= 359))
1224 originalHue = panel->hsvcolor.hue;
1225 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1226 panel->hsvcolor.hue = originalHue;
1227 } else {
1228 RRGBtoHSV(&panel->color, &panel->hsvcolor);
1233 static void
1234 modeButtonCallback(WMWidget *w, void *data)
1236 W_ColorPanel *panel = (W_ColorPanel*)(data);
1238 if (w == panel->wheelBtn)
1239 WMSetPickerMode(panel, WMWheelModeColorPanel);
1240 else if (w == panel->slidersBtn)
1241 WMSetPickerMode(panel, panel->slidersmode);
1242 else if (w == panel->customPaletteBtn)
1243 WMSetPickerMode(panel, WMCustomPaletteModeColorPanel);
1244 else if (w == panel->colorListBtn)
1245 WMSetPickerMode(panel, WMColorListModeColorPanel);
1246 else if (w == panel->grayBtn)
1247 WMSetPickerMode(panel, WMGrayModeColorPanel);
1248 else if (w == panel->rgbBtn)
1249 WMSetPickerMode(panel, WMRGBModeColorPanel);
1250 else if (w == panel->cmykBtn)
1251 WMSetPickerMode(panel, WMCMYKModeColorPanel);
1252 else if (w == panel->hsbBtn)
1253 WMSetPickerMode(panel, WMHSBModeColorPanel);
1257 /****************** Magnifying Cursor Functions *******************/
1258 static Pixmap
1259 magnifyGetImage(WMScreen *scr, int x, int y)
1261 XImage *image;
1262 Pixmap pixmap;
1263 int x0, y0, w0, h0;
1264 int displayWidth = DisplayWidth(scr->display, scr->screen);
1265 int displayHeight = DisplayHeight(scr->display, scr->screen);
1266 const int half_mask_width = (Cursor_mask_width +1)/2;
1267 const int half_mask_height = (Cursor_mask_height +1)/2;
1269 /* Coordinate correction for back pixmap */
1270 x0 = 0; y0 = 0; w0 = Cursor_mask_width; h0 = Cursor_mask_height;
1272 if (x < half_mask_width) {
1273 if (x < 0) x = 0;
1274 x0 = half_mask_width - x;
1275 w0 = Cursor_mask_width - x0;
1278 if (x > displayWidth - half_mask_width) {
1279 if (x > displayWidth) x = displayWidth;
1280 w0 = Cursor_mask_width - (half_mask_width - (displayWidth - x));
1283 if (y < half_mask_height) {
1284 if (y < 0) y = 0;
1285 y0 = half_mask_height - y;
1286 h0 = Cursor_mask_height - y0;
1289 if (y > displayHeight - half_mask_height) {
1290 if (y > displayHeight) y = displayHeight;
1291 h0 = Cursor_mask_height - (half_mask_height - (displayHeight - y));
1294 image = XGetImage(scr->display, scr->rootWin, x + x0 - Cursor_x_hot,
1295 y + y0 - Cursor_y_hot, w0, h0, AllPlanes, ZPixmap);
1297 pixmap = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1298 Cursor_mask_height, scr->depth);
1299 XPutImage(scr->display, pixmap, scr->copyGC, image, 0, 0, x0, y0, w0, h0);
1301 return pixmap;
1305 static Pixmap
1306 magnifyGetStorePixmap(WMColorPanel *panel, int x1, int y1, int x2, int y2)
1309 * (x1, y1) = topleft corner of existing rectangle
1310 * (x2, y2) = topleft corner of new position
1313 W_Screen *scr = WMWidgetScreen(panel->win);
1314 Pixmap pixmap;
1315 int xa, ya, xb, yb, w, h;
1317 if (x1 < x2) {
1318 xa = x2 - x1;
1319 xb = 0;
1320 } else {
1321 xa = 0;
1322 xb = x1 - x2;
1325 if (y1 < y2) {
1326 ya = y2 - y1;
1327 yb = 0;
1328 } else {
1329 ya = 0;
1330 yb = y1 - y2;
1333 w = Cursor_mask_width - abs(x1-x2);
1334 h = Cursor_mask_height - abs(y1-y2);
1336 /* Get pixmap from screen */
1337 pixmap = magnifyGetImage(scr, x2, y2);
1339 /* Copy previously stored pixmap on covered part of above pixmap */
1340 if (panel->magnifyGlass->valid)
1342 XCopyArea(scr->display, panel->magnifyGlass->pixmap, pixmap,
1343 scr->copyGC, xa, ya, w, h, xb, yb);
1345 /* Free it, so we can reuse it */
1346 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1349 return pixmap;
1353 static Pixmap
1354 magnifyCreatePixmap(WMColorPanel *panel)
1356 W_Screen *scr = WMWidgetScreen(panel->win);
1357 int u, v;
1358 int i, j;
1359 int ofs;
1360 Pixmap magPix;
1361 Pixmap backPix;
1362 RImage *pixelImg;
1363 const int half_mask_width = Cursor_mask_width/2;
1364 const int half_mask_height = Cursor_mask_height/2;
1368 * Get image
1371 /* Rectangle that's going to be the background */
1372 backPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
1373 Cursor_mask_height , scr->depth);
1374 XCopyArea(scr->display, panel->magnifyGlass->pixmap, backPix, scr->copyGC,
1375 0, 0, Cursor_mask_width, Cursor_mask_height, 0, 0);
1378 * Magnify image
1381 magPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width +2,
1382 Cursor_mask_height +2, scr->depth);
1384 for (u=0; u<5+1; u++) /* Copy an area of 5x5 pixels from the center */
1385 for (v=0; v<5+1; v++)
1386 for (i=u*5; i < (u+1)*5; i++) /* magnify it 5 times */
1387 for (j=v*5; j < (v+1)*5; j++)
1388 XCopyArea(scr->display, backPix, magPix, scr->copyGC, u +9, v +9, 1, 1, i, j);
1390 /* Get color under hotspot */
1391 ofs = half_mask_width + half_mask_height * Cursor_mask_width;
1392 pixelImg = RCreateImageFromDrawable(scr->rcontext, backPix, backPix);
1393 panel->magnifyGlass->color.red = pixelImg->data[0][ofs];
1394 panel->magnifyGlass->color.green = pixelImg->data[1][ofs];
1395 panel->magnifyGlass->color.blue = pixelImg->data[2][ofs];
1396 RDestroyImage(pixelImg);
1398 /* Copy the magnified pixmap, with the clip mask, to the background pixmap */
1399 XSetClipMask(scr->display, scr->clipGC, panel->magnifyGlass->mask);
1400 XSetClipOrigin(scr->display, scr->clipGC, 0, 0);
1402 XCopyArea(scr->display, magPix, backPix, scr->clipGC, 2, 2, Cursor_mask_width,
1403 Cursor_mask_height, 0, 0); /* (2,2) puts center pixel on center of glass */
1405 XFreePixmap(scr->display, magPix);
1407 return backPix;
1411 static WMView*
1412 magnifyCreateView(W_ColorPanel *panel)
1414 W_Screen *scr = WMWidgetScreen(panel->win);
1415 WMView *magView;
1417 magView = W_CreateTopView(scr);
1418 magView->self = panel;
1420 W_ResizeView(magView, Cursor_mask_width, Cursor_mask_height);
1422 magView->attribFlags |= CWOverrideRedirect | CWSaveUnder;
1423 magView->attribs.event_mask = StructureNotifyMask;
1424 magView->attribs.override_redirect = True;
1425 magView->attribs.save_under = True;
1427 W_RealizeView(magView);
1428 W_MapView(magView);
1430 return magView;
1434 static Cursor
1435 magnifyGrabPointer(W_ColorPanel *panel)
1437 W_Screen *scr = WMWidgetScreen(panel->win);
1438 Pixmap magPixmap, magPixmap2;
1439 Cursor magCursor;
1440 XColor fgColor = {0, 0,0,0, DoRed|DoGreen|DoBlue};
1441 XColor bgColor = {0, 0xbf00, 0xa000, 0x5000, DoRed|DoGreen|DoBlue};
1443 /* Cursor creation stuff */
1444 magPixmap = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1445 Cursor_bits, Cursor_width, Cursor_height, 1, 0, 1);
1446 magPixmap2 = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
1447 Cursor_shape_bits, Cursor_width, Cursor_height, 1, 0, 1);
1449 magCursor = XCreatePixmapCursor(scr->display, magPixmap, magPixmap2,
1450 &fgColor, &bgColor, Cursor_x_hot, Cursor_y_hot);
1452 XFreePixmap(scr->display, magPixmap);
1453 XFreePixmap(scr->display, magPixmap2);
1455 XRecolorCursor(scr->display, magCursor, &fgColor, &bgColor);
1457 /* Set up Pointer */
1458 XGrabPointer (scr->display, panel->magnifyGlass->view->window, True,
1459 PointerMotionMask | ButtonPressMask,
1460 GrabModeAsync, GrabModeAsync,
1461 scr->rootWin, magCursor, CurrentTime);
1463 return magCursor;
1467 static WMPoint
1468 magnifyInitialize(W_ColorPanel *panel)
1470 W_Screen *scr = WMWidgetScreen(panel->win);
1471 int x, y, u, v;
1472 unsigned int mask;
1473 Pixmap pixmap;
1474 WMPoint point;
1476 XQueryPointer(scr->display, scr->rootWin, &scr->rootWin,
1477 &W_VIEW(panel->win)->window, &x, &y, &u, &v, &mask);
1480 /* Clipmask to make magnified view-contents circular */
1481 panel->magnifyGlass->mask = XCreatePixmapFromBitmapData(scr->display,
1482 W_DRAWABLE(scr), Cursor_mask_bits,
1483 Cursor_mask_width, Cursor_mask_height, 1, 0, 1);
1485 /* Draw initial magnified part */
1486 panel->magnifyGlass->valid = False;
1487 /* also free's magnifyGlass->pixmap */
1488 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(panel, x, y, x, y);
1489 panel->magnifyGlass->valid = True;
1491 pixmap = magnifyCreatePixmap(panel);
1492 W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot +1, y - Cursor_y_hot +1);
1494 XSetWindowBackgroundPixmap(scr->display, panel->magnifyGlass->view->window, pixmap);
1495 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1496 XFlush(scr->display);
1498 XFreePixmap(scr->display, pixmap);
1500 point.x = x;
1501 point.y = y;
1503 return point;
1507 static void
1508 magnifyPutCursor(WMWidget *w, void *data)
1510 W_ColorPanel *panel = (W_ColorPanel*)(data);
1511 W_Screen *scr = WMWidgetScreen(panel->win);
1512 Cursor magCursor;
1513 int x, y;
1514 Pixmap pixmap;
1515 XEvent event;
1516 WMPoint initialPosition;
1518 /* Destroy wheelBackImg, so it'll update properly */
1519 if (panel->selectionBackImg) {
1520 XFreePixmap(WMWidgetScreen(panel->win)->display, panel->selectionBackImg);
1521 panel->selectionBackImg = None;
1524 /* Create magnifying glass */
1525 panel->magnifyGlass = wmalloc(sizeof(MovingView));
1527 panel->magnifyGlass->view = magnifyCreateView(panel);
1528 magCursor = magnifyGrabPointer(panel);
1530 initialPosition = magnifyInitialize(panel);
1531 x = initialPosition.x;
1532 y = initialPosition.y;
1535 while(panel->magnifyGlass->valid)
1537 WMNextEvent(scr->display, &event);
1539 switch (event.type)
1541 case ButtonPress:
1542 if (event.xbutton.button == Button1) {
1543 WMSetColorPanelColor(panel, panel->magnifyGlass->color);
1544 switch (panel->mode) {
1545 case WMWheelModeColorPanel:
1546 wheelInit(panel);
1547 wheelRender(panel);
1548 wheelPaint(panel);
1549 break;
1550 case WMGrayModeColorPanel:
1551 grayInit(panel);
1552 break;
1553 case WMRGBModeColorPanel:
1554 rgbInit(panel);
1555 break;
1556 case WMCMYKModeColorPanel:
1557 cmykInit(panel);
1558 break;
1559 case WMHSBModeColorPanel:
1560 hsbInit(panel);
1561 break;
1562 default:
1563 break;
1565 panel->lastChanged = panel->mode;
1568 panel->magnifyGlass->valid = False;
1569 WMSetButtonSelected(panel->magnifyBtn, False);
1570 break;
1572 case MotionNotify:
1573 /* Get a "dirty rectangle" */
1574 panel->magnifyGlass->pixmap = magnifyGetStorePixmap(
1575 panel, x+1, y+1, /* Cool, a circular reference ! */
1576 event.xmotion.x_root+1, event.xmotion.y_root+1); /* also free's magnifyGlass->pixmap */
1578 /* Update coordinates */
1579 x = event.xmotion.x_root;
1580 y = event.xmotion.y_root;
1582 /* Move view */
1583 W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot +1, y - Cursor_y_hot +1);
1585 /* Put new image (with magn.) in view */
1586 pixmap = magnifyCreatePixmap(panel);
1587 XSetWindowBackgroundPixmap(scr->display, panel->magnifyGlass->view->window, pixmap);
1588 XClearWindow(scr->display, panel->magnifyGlass->view->window);
1590 XFreePixmap(scr->display, pixmap);
1591 break;
1593 default:
1594 WMHandleEvent(&event);
1595 break;
1596 } /* of switch */
1598 panel->magnifyGlass->valid = False;
1600 XUngrabPointer(scr->display, CurrentTime);
1601 XFreeCursor(scr->display, magCursor);
1602 W_DestroyView(panel->magnifyGlass->view);
1604 XFreePixmap(scr->display, panel->magnifyGlass->mask);
1605 XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
1606 free(panel->magnifyGlass);
1611 /****************** WheelMatrix Functions ************************/
1613 static wheelMatrix*
1614 wheelCreateMatrix(unsigned int width, unsigned int height)
1616 wheelMatrix *matrix = NULL;
1617 int i;
1619 assert((width > 0) && (height > 0));
1621 matrix = malloc(sizeof(wheelMatrix));
1622 if (!matrix) {
1623 RErrorCode = RERR_NOMEMORY;
1624 return NULL;
1627 memset(matrix, 0, sizeof(wheelMatrix));
1628 matrix->width = width;
1629 matrix->height = height;
1630 for (i = 0; i < 3; i++) {
1631 matrix->data[i] = malloc(width*height*sizeof(unsigned char));
1632 if (!matrix->data[i])
1633 goto error;
1636 return matrix;
1638 error:
1639 for (i = 0; i < 3; i++) {
1640 if (matrix->data[i])
1641 free(matrix->data[i]);
1643 if (matrix)
1644 free(matrix);
1645 RErrorCode = RERR_NOMEMORY;
1646 return NULL;
1650 static void
1651 wheelDestroyMatrix(wheelMatrix *matrix)
1653 int i;
1655 assert (matrix!=NULL);
1657 for (i = 0; i < 3; i++) {
1658 if (matrix->data[i])
1659 free(matrix->data[i]);
1661 free(matrix);
1665 static wheelMatrix*
1666 wheelInitMatrix(W_ColorPanel *panel)
1668 int i;
1669 int x,y;
1670 wheelMatrix *matrix;
1671 unsigned char *rp, *gp, *bp;
1672 RHSVColor cur_hsv;
1673 RColor cur_rgb;
1674 long ofs[4];
1675 float hue;
1676 int sat;
1677 float xcor, ycor;
1678 int dhue[4];
1680 matrix = wheelCreateMatrix(colorWheelSize+4, colorWheelSize+4);
1681 if (!matrix)
1682 return NULL;
1684 RRGBtoHSV(&panel->color, &cur_hsv);
1686 for (i = 0; i < 256; i++)
1687 matrix->values[i] = (unsigned char)(rint(i*cur_hsv.value/255));
1689 cur_hsv.value = 255;
1691 ofs[0] = -1;
1692 ofs[1] = -(colorWheelSize + 4);
1693 /* ofs[2] = 0; superfluous
1694 ofs[3] = 0;
1696 for (y = 0; y < (colorWheelSize+4)/2; y++) {
1697 for (x = y; x < (colorWheelSize+4-y); x++) {
1698 xcor = ((float)(2.0*x - 4.0) / colorWheelSize) - 1;
1699 ycor = ((float)(2.0*y - 4.0) / colorWheelSize) - 1;
1701 sat = rint(255.0 * sqrt((xcor*xcor) + (ycor*ycor)));
1705 /* offsets are counterclockwise (in triangles) */
1706 if (y < (colorWheelSize+4)/2)
1707 ofs[0]++;
1708 /* top quarter */
1709 ofs[1] += colorWheelSize + 4; /* left quarter */
1712 ofs[2] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[0]; /* bottom quarter */
1713 ofs[3] = (colorWheelSize + 4) * (colorWheelSize + 4) - 1 - ofs[1]; /* right quarter */
1715 if (sat < 256) {
1716 cur_hsv.saturation = (unsigned char)sat;
1718 if (xcor != 0)
1719 hue = atan(ycor/xcor);
1720 else {
1721 if (ycor > 0)
1722 hue = M_PI * 0.5;
1723 else
1724 hue = M_PI * 1.5;
1727 if (xcor < 0)
1728 hue += M_PI;
1729 if ((xcor > 0) && (ycor < 0))
1730 hue += M_PI * 2.0;
1732 hue = -hue; /* Reverse direction of ColorWheel */
1734 if (hue < 0)
1735 hue += M_PI * 2.0;
1737 dhue[0] = (hue*360) / (M_PI * 2.0);
1739 for (i = 0; i < 4; i++) {
1741 if (i > 0)
1742 dhue[i] = (dhue[i-1] + 90) % 360;
1744 if ((i == 1) || (i == 3))
1745 dhue[i] = 360 - dhue[i];
1747 if (i == 2)
1748 dhue[i] = 360 - dhue[i] + 180;
1750 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1751 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1752 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1754 cur_hsv.hue = dhue[i];
1755 RHSVtoRGB(&cur_hsv, &cur_rgb);
1757 *rp = (unsigned char)(cur_rgb.red);
1758 *gp = (unsigned char)(cur_rgb.green);
1759 *bp = (unsigned char)(cur_rgb.blue);
1762 else {
1763 for (i = 0; i < 4; i++) {
1764 rp = matrix->data[0] + (ofs[i] * sizeof(unsigned char));
1765 gp = matrix->data[1] + (ofs[i] * sizeof(unsigned char));
1766 bp = matrix->data[2] + (ofs[i] * sizeof(unsigned char));
1768 *rp = (unsigned char)(0);
1769 *gp = (unsigned char)(0);
1770 *bp = (unsigned char)(0);
1774 if (y < (colorWheelSize+4)/2)
1775 ofs[0] += 2*y+1;
1777 ofs[1] += 1 - (colorWheelSize + 4) * (colorWheelSize + 4 - 1 - 2*y);
1780 return matrix;
1783 /****************** ColorWheel Functions *******************/
1785 static void
1786 wheelRender(W_ColorPanel *panel)
1788 W_Screen *scr = WMWidgetScreen(panel->win);
1789 int x,y;
1790 RImage *image;
1791 unsigned char *rp, *gp, *bp;
1792 RColor gray;
1793 unsigned long ofs;
1795 image = RCreateImage(colorWheelSize+4, colorWheelSize+4, False);
1796 if (!image)
1797 return;
1799 gray.red = gray.green = gray.blue = 0xaa;
1801 for (x = 0; x < colorWheelSize+4; x++) {
1802 for (y = 0; y < colorWheelSize+4; y++) {
1804 ofs = (y * image->width) + x;
1805 rp = image->data[0] + ofs;
1806 gp = image->data[1] + ofs;
1807 bp = image->data[2] + ofs;
1809 if (wheelInsideColorWheel(panel, ofs)) {
1810 *rp = (unsigned int)(panel->wheelMtrx->values[ panel->wheelMtrx->data[0][ofs] ]);
1811 *gp = (unsigned int)(panel->wheelMtrx->values[ panel->wheelMtrx->data[1][ofs] ]);
1812 *bp = (unsigned int)(panel->wheelMtrx->values[ panel->wheelMtrx->data[2][ofs] ]);
1814 else {
1815 *rp = (unsigned char)(gray.red);
1816 *gp = (unsigned char)(gray.green);
1817 *bp = (unsigned char)(gray.blue);
1822 if (panel->wheelImg)
1823 XFreePixmap(scr->display, panel->wheelImg);
1825 panel->wheelImg = XCreatePixmap(scr->display, W_DRAWABLE(scr), colorWheelSize+4, colorWheelSize+4, scr->depth);
1826 RConvertImage(scr->rcontext, image, &panel->wheelImg);
1828 /* Check backimage existence. If it doesn't exist, allocate it and fill it */
1829 if (!panel->selectionBackImg) {
1830 panel->selectionBackImg = XCreatePixmap(scr->display, W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
1831 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg, scr->copyGC,
1832 panel->colx -2, panel->coly -2, 4, 4, 0, 0); /* -2 is for hot spot correction */
1835 RDestroyImage(image);
1838 static Bool
1839 wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs)
1841 return ((panel->wheelMtrx->data[0][ofs] != 0) &&
1842 (panel->wheelMtrx->data[1][ofs] != 0) &&
1843 (panel->wheelMtrx->data[2][ofs] != 0));
1846 static void
1847 wheelPaint (W_ColorPanel *panel)
1849 W_Screen *scr = WMWidgetScreen(panel->win);
1851 XCopyArea(scr->display, panel->wheelImg, panel->wheelView->window, scr->copyGC,
1852 0, 0, colorWheelSize+4, colorWheelSize+4, 0, 0);
1854 /* Draw selection image */
1855 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window, scr->copyGC,
1856 0, 0, 4, 4, panel->colx -2, panel->coly -2);
1859 static void
1860 wheelHandleEvents(XEvent *event, void *data)
1862 W_ColorPanel *panel = (W_ColorPanel*)data;
1864 switch (event->type) {
1865 case Expose:
1866 if (event->xexpose.count != 0)
1867 break;
1868 wheelPaint(panel);
1869 break;
1873 static void
1874 wheelHandleActionEvents(XEvent *event, void *data)
1876 W_ColorPanel *panel = (W_ColorPanel*)data;
1878 switch (event->type) {
1879 case ButtonPress:
1880 if (getPickerPart(panel, event->xbutton.x, event->xbutton.y) == COLORWHEEL_PART) {
1881 panel->flags.dragging = 1;
1882 wheelPositionSelection(panel, event->xbutton.x, event->xbutton.y);
1884 break;
1886 case ButtonRelease:
1887 panel->flags.dragging = 0;
1888 break;
1890 case MotionNotify:
1891 if (panel->flags.dragging) {
1892 if (getPickerPart(panel, event->xmotion.x, event->xmotion.y) == COLORWHEEL_PART) {
1893 wheelPositionSelection(panel, event->xmotion.x, event->xmotion.y);
1895 else
1896 wheelPositionSelectionOutBounds(panel, event->xmotion.x, event->xmotion.y);
1898 break;
1903 static int
1904 getPickerPart(W_ColorPanel *panel, int x, int y)
1906 int lx, ly;
1907 unsigned long ofs;
1909 lx = x;
1910 ly = y;
1912 if (panel->mode == WMWheelModeColorPanel) {
1913 if ((lx >= 2) && (lx <= 2+colorWheelSize) && (ly >= 2) && (ly <= 2+colorWheelSize)) {
1914 ofs = ly*panel->wheelMtrx->width+lx;
1916 if (wheelInsideColorWheel(panel, ofs))
1917 return COLORWHEEL_PART;
1921 if (panel->mode == WMCustomPaletteModeColorPanel) {
1922 if ((lx >= 2) && (lx < customPaletteWidth-2) && (ly >= 2) && (ly < customPaletteHeight-2)) {
1923 return CUSTOMPALETTE_PART;
1927 return 0;
1931 static void
1932 wheelBrightnessSliderCallback(WMWidget *w, void *data)
1934 int i;
1935 unsigned int v;
1936 int value;
1937 unsigned long ofs;
1938 RColor cur_rgb;
1940 W_ColorPanel *panel = (W_ColorPanel*)data;
1942 value = 255-WMGetSliderValue(panel->wheelBrightnessS);
1944 for (i = 0; i < 256; i++) {
1945 /* We divide by 128 in advance, and check whether that number divides
1946 * by 2 properly. If not, we add one to round the number correctly
1948 v = (i*value) >> 7;
1949 #ifdef EASTEREGG
1950 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + v);
1951 #else
1952 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) +(v & 0x01));
1953 #endif
1956 ofs = (panel->coly * panel->wheelMtrx->width) + panel->colx;
1958 if (!wheelInsideColorWheel(panel, ofs)) {
1959 panel->hsvcolor.saturation = 255;
1960 panel->hsvcolor.value = value;
1961 RHSVtoRGB(&panel->hsvcolor, &cur_rgb);
1963 panel->color = cur_rgb;
1965 else {
1966 panel->color.red = panel->wheelMtrx->values[ panel->wheelMtrx->data[0][ofs] ];
1967 panel->color.green = panel->wheelMtrx->values[ panel->wheelMtrx->data[1][ofs] ];
1968 panel->color.blue = panel->wheelMtrx->values[ panel->wheelMtrx->data[2][ofs] ];
1971 wheelRender(panel);
1972 wheelPaint(panel);
1973 wheelUpdateSelection(panel);
1977 static void
1978 wheelUpdateSelection(W_ColorPanel *panel)
1980 W_Screen *scr = WMWidgetScreen(panel->win);
1982 WMSetColorPanelColor(panel, panel->color);
1983 panel->lastChanged = WMWheelModeColorPanel;
1985 /* Redraw color selector (and make a backup of the part it will cover) */
1986 XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg, scr->copyGC,
1987 panel->colx -2, panel->coly -2, 4, 4, 0, 0); /* "-2" is correction for hotspot location */
1988 XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window, scr->copyGC,
1989 0, 0, 4, 4, panel->colx -2, panel->coly -2); /* see above */
1992 static void
1993 wheelUndrawSelection(W_ColorPanel *panel)
1995 W_Screen *scr = WMWidgetScreen(panel->win);
1997 XCopyArea(scr->display, panel->selectionBackImg, panel->wheelView->window, scr->copyGC,
1998 0, 0, 4, 4, panel->colx -2, panel->coly -2); /* see above */
2001 static void
2002 wheelPositionSelection(W_ColorPanel *panel, int x, int y)
2004 unsigned long ofs = (y * panel->wheelMtrx->width)+ x;
2007 panel->color.red = panel->wheelMtrx->values[ panel->wheelMtrx->data[0][ofs] ];
2008 panel->color.green = panel->wheelMtrx->values[ panel->wheelMtrx->data[1][ofs] ];
2009 panel->color.blue = panel->wheelMtrx->values[ panel->wheelMtrx->data[2][ofs] ];
2011 wheelUndrawSelection(panel);
2013 panel->colx = x;
2014 panel->coly = y;
2016 wheelUpdateSelection(panel);
2017 wheelUpdateBrightnessGradientFromLocation(panel);
2020 static void
2021 wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2023 RHSVColor cur_hsv;
2024 float hue;
2025 float xcor, ycor;
2027 xcor = ((x*2.0) / (colorWheelSize+4)) - 1.0;
2028 ycor = ((y*2.0) / (colorWheelSize+4)) - 1.0;
2030 cur_hsv.saturation = 255;
2031 cur_hsv.value = 255 - WMGetSliderValue(panel->wheelBrightnessS);
2033 if (xcor != 0)
2034 hue = atan(ycor/xcor);
2035 else {
2036 if (ycor > 0)
2037 hue = M_PI * 0.5;
2038 else
2039 hue = M_PI * 1.5;
2042 if (xcor < 0)
2043 hue += M_PI;
2044 if ((xcor > 0) && (ycor < 0))
2045 hue += M_PI * 2.0;
2047 hue = -hue;
2049 if (hue < 0)
2050 hue += M_PI * 2.0;
2052 cur_hsv.hue = (hue*180.0)/(M_PI);
2053 RHSVtoRGB(&cur_hsv, &panel->color);
2055 wheelUndrawSelection(panel);
2057 panel->colx = 2 + rint((colorWheelSize * (1.0 + cos( cur_hsv.hue*M_PI/180))) /2.0); /* "+2" because of "colorWheelSize + 4" */
2058 panel->coly = 2 + rint((colorWheelSize * (1.0 + sin(-cur_hsv.hue*M_PI/180))) /2.0);
2060 wheelUpdateSelection(panel);
2061 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
2064 static void
2065 wheelUpdateBrightnessGradientFromHSV(W_ColorPanel *panel, RHSVColor topColor)
2067 RColor from;
2069 /* Update Brightness-Slider */
2070 topColor.value = 255;
2071 RHSVtoRGB(&topColor, &from);
2073 wheelUpdateBrightnessGradient(panel, from);
2076 static void
2077 wheelUpdateBrightnessGradientFromLocation(W_ColorPanel *panel)
2079 RColor from;
2080 unsigned long ofs;
2082 ofs = panel->coly * panel->wheelMtrx->width + panel->colx;
2084 from.red = panel->wheelMtrx->data[0][ofs];
2085 from.green = panel->wheelMtrx->data[1][ofs];
2086 from.blue = panel->wheelMtrx->data[2][ofs];
2088 wheelUpdateBrightnessGradient(panel, from);
2091 static void
2092 wheelUpdateBrightnessGradient(W_ColorPanel *panel, RColor topColor)
2094 RColor to;
2095 RImage *sliderImg;
2096 WMPixmap *sliderPxmp;
2098 to.red = to.green = to.blue = 0;
2100 sliderImg = RRenderGradient(16, 153, &topColor, &to, RGRD_VERTICAL);
2101 sliderPxmp = WMCreatePixmapFromRImage(WMWidgetScreen(panel->win), sliderImg, 0);
2102 RDestroyImage(sliderImg);
2103 WMSetSliderImage(panel->wheelBrightnessS, sliderPxmp);
2104 WMReleasePixmap(sliderPxmp);
2107 /****************** Grayscale Panel Functions ***************/
2109 static void
2110 grayBrightnessSliderCallback(WMWidget *w, void *data)
2112 RColor color;
2113 int value;
2114 char tmp[4];
2116 W_ColorPanel *panel = (W_ColorPanel*)data;
2118 value = WMGetSliderValue(panel->grayBrightnessS);
2120 sprintf(tmp, "%d", value);
2122 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2123 color.red = color.green = color.blue = rint(2.55*value);
2125 WMSetColorPanelColor(panel, color);
2126 panel->lastChanged = WMGrayModeColorPanel;
2129 static void
2130 grayPresetButtonCallback(WMWidget *w, void *data)
2132 RColor color;
2133 char tmp[4];
2134 int value;
2135 int i=0;
2137 W_ColorPanel *panel = (W_ColorPanel*)data;
2139 while (i < 7) {
2140 if (w == panel->grayPresetBtn[i])
2141 break;
2142 i++;
2145 value = rint(100.0/6.0*i);
2146 sprintf(tmp, "%d", value);
2148 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2149 color.red = color.green = color.blue = rint(255.0*i/6.0);
2151 WMSetSliderValue(panel->grayBrightnessS, rint(100.0*i/6.0));
2153 WMSetColorPanelColor(panel, color);
2154 panel->lastChanged = WMGrayModeColorPanel;
2157 static void
2158 grayBrightnessTextFieldCallback(void *observerData, WMNotification *notification)
2160 RColor color;
2161 char tmp[4];
2162 int value;
2163 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2165 value = atoi(WMGetTextFieldText(panel->grayBrightnessT));
2166 if (value > 100)
2167 value = 100;
2168 if (value < 0)
2169 value = 0;
2171 sprintf(tmp, "%d", value);
2172 WMSetTextFieldText(panel->grayBrightnessT, tmp);
2173 WMSetSliderValue(panel->grayBrightnessS, value);
2175 color.red = color.green = color.blue = rint(255.0*value/100.0);
2176 WMSetColorPanelColor(panel, color);
2177 panel->lastChanged = WMGrayModeColorPanel;
2180 /******************* RGB Panel Functions *****************/
2182 static void
2183 rgbSliderCallback(WMWidget *w, void *data)
2185 RColor color;
2186 int value[3];
2187 char tmp[4];
2189 W_ColorPanel *panel = (W_ColorPanel*)data;
2191 value[0] = WMGetSliderValue(panel->rgbRedS);
2192 value[1] = WMGetSliderValue(panel->rgbGreenS);
2193 value[2] = WMGetSliderValue(panel->rgbBlueS);
2195 sprintf(tmp, "%d", value[0]);
2196 WMSetTextFieldText(panel->rgbRedT, tmp);
2197 sprintf(tmp, "%d", value[1]);
2198 WMSetTextFieldText(panel->rgbGreenT, tmp);
2199 sprintf(tmp, "%d", value[2]);
2200 WMSetTextFieldText(panel->rgbBlueT, tmp);
2202 color.red = value[0];
2203 color.green = value[1];
2204 color.blue = value[2];
2206 WMSetColorPanelColor(panel, color);
2207 panel->lastChanged = WMRGBModeColorPanel;
2210 static void
2211 rgbTextFieldCallback(void *observerData, WMNotification *notification)
2213 RColor color;
2214 int value[3];
2215 char tmp[4];
2216 int n;
2217 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2219 value[0] = atoi(WMGetTextFieldText(panel->rgbRedT));
2220 value[1] = atoi(WMGetTextFieldText(panel->rgbGreenT));
2221 value[2] = atoi(WMGetTextFieldText(panel->rgbBlueT));
2223 for (n=0; n < 3; n++) {
2224 if (value[n] > 255)
2225 value[n] = 255;
2226 if (value[n] < 0)
2227 value[n] = 0;
2230 sprintf(tmp, "%d", value[0]);
2231 WMSetTextFieldText(panel->rgbRedT, tmp);
2232 sprintf(tmp, "%d", value[1]);
2233 WMSetTextFieldText(panel->rgbGreenT, tmp);
2234 sprintf(tmp, "%d", value[2]);
2235 WMSetTextFieldText(panel->rgbBlueT, tmp);
2237 WMSetSliderValue(panel->rgbRedS, value[0]);
2238 WMSetSliderValue(panel->rgbGreenS, value[1]);
2239 WMSetSliderValue(panel->rgbBlueS, value[2]);
2241 color.red = value[0];
2242 color.green = value[1];
2243 color.blue = value[2];
2245 WMSetColorPanelColor(panel, color);
2246 panel->lastChanged = WMRGBModeColorPanel;
2250 /******************* CMYK Panel Functions *****************/
2252 static void
2253 cmykSliderCallback(WMWidget *w, void *data)
2255 RColor color;
2256 int value[4];
2257 char tmp[4];
2259 W_ColorPanel *panel = (W_ColorPanel*)data;
2261 value[0] = WMGetSliderValue(panel->cmykCyanS);
2262 value[1] = WMGetSliderValue(panel->cmykMagentaS);
2263 value[2] = WMGetSliderValue(panel->cmykYellowS);
2264 value[3] = WMGetSliderValue(panel->cmykBlackS);
2266 sprintf(tmp, "%d", value[0]);
2267 WMSetTextFieldText(panel->cmykCyanT, tmp);
2268 sprintf(tmp, "%d", value[1]);
2269 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2270 sprintf(tmp, "%d", value[2]);
2271 WMSetTextFieldText(panel->cmykYellowT, tmp);
2272 sprintf(tmp, "%d", value[3]);
2273 WMSetTextFieldText(panel->cmykBlackT, tmp);
2275 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2276 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3] / 100.0)));
2277 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] / 100.0)));
2279 WMSetColorPanelColor(panel, color);
2280 panel->lastChanged = WMCMYKModeColorPanel;
2283 static void
2284 cmykTextFieldCallback(void *observerData, WMNotification *notification)
2286 RColor color;
2287 int value[4];
2288 char tmp[4];
2289 int n;
2290 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2292 value[0] = atoi(WMGetTextFieldText(panel->cmykCyanT));
2293 value[1] = atoi(WMGetTextFieldText(panel->cmykMagentaT));
2294 value[2] = atoi(WMGetTextFieldText(panel->cmykYellowT));
2295 value[3] = atoi(WMGetTextFieldText(panel->cmykBlackT));
2297 for (n=0; n < 4; n++) {
2298 if (value[n] > 100)
2299 value[n] = 100;
2300 if (value[n] < 0)
2301 value[n] = 0;
2304 sprintf(tmp, "%d", value[0]);
2305 WMSetTextFieldText(panel->cmykCyanT, tmp);
2306 sprintf(tmp, "%d", value[1]);
2307 WMSetTextFieldText(panel->cmykMagentaT, tmp);
2308 sprintf(tmp, "%d", value[2]);
2309 WMSetTextFieldText(panel->cmykYellowT, tmp);
2310 sprintf(tmp, "%d", value[3]);
2311 WMSetTextFieldText(panel->cmykBlackT, tmp);
2313 WMSetSliderValue(panel->cmykCyanS, value[0]);
2314 WMSetSliderValue(panel->cmykMagentaS, value[1]);
2315 WMSetSliderValue(panel->cmykYellowS, value[2]);
2316 WMSetSliderValue(panel->cmykBlackS, value[3]);
2318 color.red = rint((255.0 - (value[0] * 2.55)) * (1.0 - (value[3] / 100.0)));
2319 color.green = rint((255.0 - (value[1] * 2.55)) * (1.0 - (value[3] / 100.0)));
2320 color.blue = rint((255.0 - (value[2] * 2.55)) * (1.0 - (value[3] / 100.0)));
2322 WMSetColorPanelColor(panel, color);
2323 panel->lastChanged = WMCMYKModeColorPanel;
2326 /********************** HSB Panel Functions ***********************/
2328 static void
2329 hsbSliderCallback(WMWidget *w, void *data)
2331 RColor color;
2332 int value[3];
2333 char tmp[4];
2335 W_ColorPanel *panel = (W_ColorPanel*)data;
2337 value[0] = WMGetSliderValue(panel->hsbHueS);
2338 value[1] = WMGetSliderValue(panel->hsbSaturationS);
2339 value[2] = WMGetSliderValue(panel->hsbBrightnessS);
2341 sprintf(tmp, "%d", value[0]);
2342 WMSetTextFieldText(panel->hsbHueT, tmp);
2343 sprintf(tmp, "%d", value[1]);
2344 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2345 sprintf(tmp, "%d", value[2]);
2346 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2348 panel->hsvcolor.hue = value[0];
2349 panel->hsvcolor.saturation = value[1]*2.55;
2350 panel->hsvcolor.value = value[2]*2.55;
2352 RHSVtoRGB(&panel->hsvcolor, &color);
2354 panel->lastChanged = WMHSBModeColorPanel;
2355 WMSetColorPanelColor(panel, color);
2357 if (w != panel->hsbBrightnessS)
2358 hsbUpdateBrightnessGradient(panel);
2359 if (w != panel->hsbSaturationS)
2360 hsbUpdateSaturationGradient(panel);
2361 if (w != panel->hsbHueS)
2362 hsbUpdateHueGradient(panel);
2365 static void
2366 hsbTextFieldCallback(void *observerData, WMNotification *notification)
2368 RColor color;
2369 int value[3];
2370 char tmp[4];
2371 int n;
2372 W_ColorPanel *panel = (W_ColorPanel*)observerData;
2374 value[0] = atoi(WMGetTextFieldText(panel->hsbHueT));
2375 value[1] = atoi(WMGetTextFieldText(panel->hsbSaturationT));
2376 value[2] = atoi(WMGetTextFieldText(panel->hsbBrightnessT));
2378 if (value[0] > 359)
2379 value[0] = 359;
2380 if (value[0] < 0)
2381 value[0] = 0;
2383 for (n=1; n < 3; n++) {
2384 if (value[n] > 100)
2385 value[n] = 100;
2386 if (value[n] < 0)
2387 value[n] = 0;
2390 sprintf(tmp, "%d", value[0]);
2391 WMSetTextFieldText(panel->hsbHueT, tmp);
2392 sprintf(tmp, "%d", value[1]);
2393 WMSetTextFieldText(panel->hsbSaturationT, tmp);
2394 sprintf(tmp, "%d", value[2]);
2395 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
2397 WMSetSliderValue(panel->hsbHueS, value[0]);
2398 WMSetSliderValue(panel->hsbSaturationS, value[1]);
2399 WMSetSliderValue(panel->hsbBrightnessS, value[2]);
2401 panel->hsvcolor.hue = value[0];
2402 panel->hsvcolor.saturation = value[1]*2.55;
2403 panel->hsvcolor.value = value[2]*2.55;
2405 RHSVtoRGB(&panel->hsvcolor, &color);
2407 panel->lastChanged = WMHSBModeColorPanel;
2408 WMSetColorPanelColor(panel, color);
2410 hsbUpdateBrightnessGradient(panel);
2411 hsbUpdateSaturationGradient(panel);
2412 hsbUpdateHueGradient(panel);
2415 static void
2416 hsbUpdateBrightnessGradient(W_ColorPanel *panel)
2418 W_Screen *scr = WMWidgetScreen(panel->win);
2419 RColor from;
2420 RColor to;
2421 RHSVColor hsvcolor;
2422 RImage *sliderImg;
2423 WMPixmap *sliderPxmp;
2425 from.red = from.green = from.blue = 0;
2426 hsvcolor = panel->hsvcolor;
2427 hsvcolor.value = 255;
2429 RHSVtoRGB(&hsvcolor, &to);
2431 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2432 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2433 RDestroyImage(sliderImg);
2434 W_PaintText(W_VIEW(panel->hsbBrightnessS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scr->white), False, "Brightness", strlen("Brightness"));
2435 WMSetSliderImage(panel->hsbBrightnessS, sliderPxmp);
2436 WMReleasePixmap(sliderPxmp);
2439 static void
2440 hsbUpdateSaturationGradient(W_ColorPanel *panel)
2442 W_Screen *scr = WMWidgetScreen(panel->win);
2443 RColor from;
2444 RColor to;
2445 RHSVColor hsvcolor;
2446 RImage *sliderImg;
2447 WMPixmap *sliderPxmp;
2449 hsvcolor = panel->hsvcolor;
2450 hsvcolor.saturation = 0;
2451 RHSVtoRGB(&hsvcolor, &from);
2453 hsvcolor.saturation = 255;
2454 RHSVtoRGB(&hsvcolor, &to);
2456 sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
2457 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2458 RDestroyImage(sliderImg);
2459 if (hsvcolor.value < 128)
2460 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scr->white), False, "Saturation", strlen("Saturation"));
2461 else
2462 W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scr->black), False, "Saturation", strlen("Saturation"));
2464 WMSetSliderImage(panel->hsbSaturationS, sliderPxmp);
2465 WMReleasePixmap(sliderPxmp);
2468 static void
2469 hsbUpdateHueGradient(W_ColorPanel *panel)
2471 W_Screen *scr = WMWidgetScreen(panel->win);
2472 RColor **colors = NULL;
2473 RHSVColor hsvcolor;
2474 RImage *sliderImg;
2475 WMPixmap *sliderPxmp;
2476 int i;
2478 hsvcolor = panel->hsvcolor;
2480 colors = malloc(sizeof(RColor*)*(8));
2481 for (i=0; i<7; i++) {
2482 hsvcolor.hue = (360*i)/6;
2483 colors[i] = malloc(sizeof(RColor));
2484 RHSVtoRGB(&hsvcolor, colors[i]);
2486 colors[7] = NULL;
2488 sliderImg = RRenderMultiGradient(141, 16, colors, RGRD_HORIZONTAL);
2489 sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
2490 RDestroyImage(sliderImg);
2491 if (hsvcolor.value < 128)
2492 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scr->white), False, "Hue", strlen("Hue"));
2493 else
2494 W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, W_GC(scr->black), False, "Hue", strlen("Hue"));
2496 WMSetSliderImage(panel->hsbHueS, sliderPxmp);
2497 WMReleasePixmap(sliderPxmp);
2499 for (i=0; i<7; i++) {
2500 if (colors[i])
2501 free(colors[i]);
2503 if (colors)
2504 free(colors);
2507 /*************** Custom Palette Functions ****************/
2509 static void
2510 customRenderSpectrum(W_ColorPanel *panel)
2512 RImage *spectrum;
2513 int hue, sat, val;
2514 int x,y;
2515 unsigned long ofs;
2516 unsigned char *rp, *gp, *bp;
2517 RColor color;
2518 RHSVColor cur_hsv;
2520 spectrum = RCreateImage(SPECTRUM_WIDTH, SPECTRUM_HEIGHT, 0);
2522 for (y=0; y<360; y++) {
2523 val = 255;
2524 sat = 0;
2525 hue = y;
2526 for (x=0; x<511; x++) {
2527 ofs = (y * 511) + x;
2529 cur_hsv.hue = hue;
2530 cur_hsv.saturation = sat;
2531 cur_hsv.value = val;
2533 RHSVtoRGB (&cur_hsv, &color);
2535 rp = spectrum->data[0] + ofs;
2536 gp = spectrum->data[1] + ofs;
2537 bp = spectrum->data[2] + ofs;
2539 *rp = (unsigned char)color.red;
2540 *gp = (unsigned char)color.green;
2541 *bp = (unsigned char)color.blue;
2543 if (x<255)
2544 sat++;
2546 if (x>255)
2547 val--;
2550 if (panel->customPaletteImg) {
2551 RDestroyImage(panel->customPaletteImg);
2552 panel->customPaletteImg = NULL;
2554 panel->customPaletteImg = spectrum;
2559 static void
2560 customSetPalette(W_ColorPanel *panel)
2562 W_Screen *scr = WMWidgetScreen(panel->win);
2563 RImage *scaledImg;
2564 Pixmap image;
2565 int item;
2567 image = XCreatePixmap(scr->display, W_DRAWABLE(scr), customPaletteWidth, customPaletteHeight, scr->depth);
2569 scaledImg = RScaleImage(panel->customPaletteImg, customPaletteWidth, customPaletteHeight);
2570 RConvertImage(scr->rcontext, scaledImg, &image);
2571 RDestroyImage(scaledImg);
2573 XCopyArea(scr->display, image, panel->customPaletteContentView->window, scr->copyGC, 0, 0, customPaletteWidth, customPaletteHeight, 0, 0);
2575 /* Check backimage existence. If it doesn't exist, allocate it and fill it */
2576 if (!panel->selectionBackImg) {
2577 panel->selectionBackImg = XCreatePixmap(scr->display, panel->customPaletteContentView->window, 4, 4, scr->depth);
2580 XCopyArea(scr->display, image, panel->selectionBackImg, scr->copyGC, panel->palx-2, panel->paly-2, 4, 4, 0, 0);
2581 XCopyArea(scr->display, panel->selectionImg, panel->customPaletteContentView->window, scr->copyGC, 0 , 0, 4, 4, panel->palx-2, panel->paly-2);
2582 XFreePixmap(scr->display, image);
2584 panel->palXRatio = (float)(panel->customPaletteImg->width) / (float)(customPaletteWidth);
2585 panel->palYRatio = (float)(panel->customPaletteImg->height) / (float)(customPaletteHeight);
2587 item = WMGetPopUpButtonSelectedItem (panel->customPaletteHistoryBtn);
2589 /* if palette != "Spectrum", we are allowed to rename and remove it */
2590 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, (item > 0) );
2591 WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, (item > 0) );
2595 static void
2596 customPalettePositionSelection(W_ColorPanel *panel, int x, int y)
2598 W_Screen *scr = WMWidgetScreen(panel->win);
2599 unsigned long ofs;
2602 /* undraw selection */
2603 XCopyArea(scr->display, panel->selectionBackImg, panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4, panel->palx-2, panel->paly-2);
2605 panel->palx = x;
2606 panel->paly = y;
2608 ofs = rint(x * panel->palXRatio) + rint(y * panel->palYRatio) * panel->customPaletteImg->width;
2610 panel->color.red = panel->customPaletteImg->data[0][ofs];
2611 panel->color.green = panel->customPaletteImg->data[1][ofs];
2612 panel->color.blue = panel->customPaletteImg->data[2][ofs];
2614 WMSetColorPanelColor(panel, panel->color);
2615 panel->lastChanged = WMCustomPaletteModeColorPanel;
2617 /* Redraw color selector (and make a backup of the part it will cover) */
2618 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 */
2619 XCopyArea(scr->display, panel->selectionImg, panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4, panel->palx-2, panel->paly-2); /* see above */
2623 static void
2624 customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
2626 if (x < 2)
2627 x = 2;
2628 if (y < 2)
2629 y = 2;
2630 if (x >= customPaletteWidth)
2631 x = customPaletteWidth -2;
2632 if (y >= customPaletteHeight)
2633 y = customPaletteHeight -2;
2635 customPalettePositionSelection(panel, x, y);
2639 static void
2640 customPaletteHandleEvents(XEvent *event, void *data)
2642 W_ColorPanel *panel = (W_ColorPanel*)data;
2644 switch (event->type) {
2645 case Expose:
2646 if (event->xexpose.count != 0)
2647 break;
2648 customSetPalette(panel);
2649 break;
2653 static void
2654 customPaletteHandleActionEvents(XEvent *event, void *data)
2656 W_ColorPanel *panel = (W_ColorPanel*)data;
2657 int x, y;
2659 switch (event->type) {
2660 case ButtonPress:
2661 x = event->xbutton.x;
2662 y = event->xbutton.y;
2664 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2665 panel->flags.dragging = 1;
2666 customPalettePositionSelection(panel, x, y);
2668 break;
2670 case ButtonRelease:
2671 panel->flags.dragging = 0;
2672 break;
2674 case MotionNotify:
2675 x = event->xmotion.x;
2676 y = event->xmotion.y;
2678 if (panel->flags.dragging) {
2679 if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
2680 customPalettePositionSelection(panel, x, y);
2682 else
2683 customPalettePositionSelectionOutBounds(panel, x, y);
2685 break;
2690 static void
2691 customPaletteMenuCallback(WMWidget *w, void *data)
2693 W_ColorPanel *panel = (W_ColorPanel*)data;
2694 int item = WMGetPopUpButtonSelectedItem(panel->customPaletteMenuBtn);
2696 switch (item) {
2697 case CPmenuNewFromFile:
2698 customPaletteMenuNewFromFile(panel);
2699 break;
2700 case CPmenuRename:
2701 customPaletteMenuRename(panel);
2702 break;
2703 case CPmenuRemove:
2704 customPaletteMenuRemove(panel);
2705 break;
2706 case CPmenuCopy:
2707 break;
2708 case CPmenuNewFromClipboard:
2709 break;
2714 static void
2715 customPaletteMenuNewFromFile(W_ColorPanel *panel)
2717 W_Screen *scr = WMWidgetScreen(panel->win);
2718 WMOpenPanel *browseP;
2719 char *filepath;
2720 char *filename = NULL;
2721 char *spath;
2722 char *tmp;
2723 int i;
2724 RImage *tmpImg = NULL;
2726 if ((!panel->lastBrowseDir) || (strcmp(panel->lastBrowseDir,"\0") == 0))
2727 spath = wexpandpath(wgethomedir());
2728 else
2729 spath = wexpandpath(panel->lastBrowseDir);
2731 browseP = WMGetOpenPanel(scr);
2732 WMSetFilePanelCanChooseDirectories(browseP, 0);
2733 WMSetFilePanelCanChooseFiles(browseP, 1);
2735 /* Get a filename */
2736 if (WMRunModalOpenPanelForDirectory(browseP, panel->win, spath,
2737 "Open Palette",
2738 RSupportedFileFormats()) ) {
2739 filepath = WMGetFilePanelFileName(browseP);
2741 /* Get seperation position between path and filename */
2742 i = strrchr(filepath, '/') - filepath + 1;
2743 if (i > strlen(filepath))
2744 i = strlen(filepath);
2746 /* Store last browsed path */
2747 if (panel->lastBrowseDir)
2748 free(panel->lastBrowseDir);
2749 panel->lastBrowseDir = wmalloc((i+1)*sizeof(char));
2750 strncpy(panel->lastBrowseDir, filepath, i);
2751 panel->lastBrowseDir[i] = '\0';
2753 /* Get filename from path */
2754 filename = wstrdup(filepath + i);
2756 /* Check for duplicate files, and rename it if there are any */
2757 tmp = wstrappend(panel->configurationPath, filename);
2758 while (access (tmp, F_OK) == 0) {
2759 char *newName;
2761 free(tmp);
2763 newName = generateNewFilename(filename);
2764 free(filename);
2765 filename = newName;
2767 tmp = wstrappend(panel->configurationPath, filename);
2769 free(tmp);
2771 /* Copy the image to $(gnustepdir)/Library/Colors/ & Add the filename to the history menu */
2772 if (fetchFile (panel->configurationPath, filepath, filename) == 0) {
2774 /* filepath is a "local" path now the file has been copied */
2775 free(filepath);
2776 filepath = wstrappend(panel->configurationPath, filename);
2778 /* load the image & add menu entries */
2779 tmpImg = RLoadImage(scr->rcontext, filepath, 0);
2780 if (tmpImg) {
2781 if (panel->customPaletteImg)
2782 RDestroyImage(panel->customPaletteImg);
2783 panel->customPaletteImg = tmpImg;
2785 customSetPalette(panel);
2786 WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, filename);
2788 panel->currentPalette = WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn)-1;
2790 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
2791 panel->currentPalette);
2794 else
2796 tmp = wstrappend(panel->configurationPath, filename);
2798 i = remove(tmp); /* Delete the file, it doesn't belong here */
2799 WMRunAlertPanel(scr, panel->win, "File Error", "Invalid file format !", "OK", NULL, NULL);
2800 if (i != 0) {
2801 wsyserror("can't remove file %s", tmp);
2802 WMRunAlertPanel(scr, panel->win, "File Error", "Couldn't remove file from Configuration Directory !", "OK", NULL, NULL);
2804 free(tmp);
2806 free(filepath);
2807 free(filename);
2809 WMFreeFilePanel(browseP);
2811 free(spath);
2815 static void
2816 customPaletteMenuRename(W_ColorPanel *panel)
2818 W_Screen *scr = WMWidgetScreen(panel->win);
2819 char *toName = NULL;
2820 char *fromName;
2821 char *toPath, *fromPath;
2822 int item;
2823 int index;
2825 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
2826 fromName = WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item);
2828 toName = WMRunInputPanel(scr, panel->win, "Rename", "Rename palette to:",
2829 fromName, "OK", "Cancel");
2831 if (toName) {
2833 /* As some people do certain stupid things... */
2834 if (strcmp(toName, fromName) == 0) {
2835 free(toName);
2836 return;
2839 /* For normal people */
2840 fromPath = wstrappend(panel->configurationPath, fromName);
2841 toPath = wstrappend(panel->configurationPath, toName);
2843 if (access (toPath, F_OK) == 0) { /* Careful, this palette exists already */
2844 if (WMRunAlertPanel(scr, panel->win, "Warning",
2845 "Palette already exists !\n\nOverwrite ?", "No", "Yes", NULL) == 1) {
2846 /* "No" = 0, "Yes" = 1 */
2847 int items = WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn);
2849 remove(toPath);
2851 /* Remove from History list too */
2852 index = 1;
2853 while ((index < items) &&
2854 (strcmp(WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, index), toName) != 0 ))
2855 index++;
2857 if (index < items) {
2858 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, index);
2859 if (index < item)
2860 item--;
2863 } else {
2864 free(fromPath);
2865 free(toName);
2866 free(toPath);
2868 return;
2872 if ( rename(fromPath, toPath) != 0)
2873 wsyserror("Couldn't rename palette %s to %s\n", fromName, toName);
2874 else {
2875 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
2876 WMInsertPopUpButtonItem(panel->customPaletteHistoryBtn, item, toName);
2878 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item);
2880 free(fromPath);
2881 free(toPath);
2882 free(toName);
2887 static void
2888 customPaletteMenuRemove(W_ColorPanel *panel)
2890 W_Screen *scr = WMWidgetScreen(panel->win);
2891 char *text;
2892 char *tmp;
2893 int choice;
2894 int item;
2896 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
2898 tmp = wstrappend( "This will permanently remove the palette ",
2899 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
2900 text = wstrappend( tmp, ".\n\nAre you sure you want to remove this palette ?");
2901 free(tmp);
2903 choice = WMRunAlertPanel(scr, panel->win, NULL, text, "Yes", "No", NULL);
2904 /* returns 0 (= "Yes") or 1 (="No") */
2905 free(text);
2907 if (choice == 0) {
2909 tmp = wstrappend(panel->configurationPath,
2910 WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
2912 if ( remove(tmp) != 0)
2913 wsyserror("Couldn't remove palette %s\n", tmp);
2914 free(tmp);
2916 WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item-1); /* item -1 always exists */
2917 customPaletteHistoryCallback(panel->customPaletteHistoryBtn, panel);
2918 customSetPalette(panel);
2920 WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
2925 static void
2926 customPaletteHistoryCallback(WMWidget *w, void *data)
2928 W_ColorPanel *panel = (W_ColorPanel*)data;
2929 W_Screen *scr = WMWidgetScreen(panel->win);
2930 int item;
2931 char *filename;
2932 RImage *tmp = NULL;
2934 item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
2935 if (item == panel->currentPalette)
2936 return;
2938 if (item == 0)
2939 customRenderSpectrum(panel);
2940 else {
2941 /* Load file from configpath */
2942 filename = wstrappend( panel->configurationPath, WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item) );
2944 /* XXX To do: Check existence of file and remove it from the history if it doesn't exist */
2946 tmp = RLoadImage(scr->rcontext, filename, 0);
2947 if (tmp) {
2948 if (panel->customPaletteImg) {
2949 RDestroyImage(panel->customPaletteImg);
2950 panel->customPaletteImg = NULL;
2952 panel->customPaletteImg = tmp;
2954 free(filename);
2956 customSetPalette(panel);
2958 panel->currentPalette = item;
2962 /*************** Panel Initialisation Functions *****************/
2964 static void
2965 wheelInit(W_ColorPanel *panel)
2967 RHSVColor cur_hsv;
2968 int i;
2969 int v;
2971 RRGBtoHSV(&panel->color, &cur_hsv);
2973 WMSetSliderValue(panel->wheelBrightnessS, 255-cur_hsv.value);
2974 wheelUpdateBrightnessGradientFromHSV(panel, cur_hsv);
2976 panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 + (cur_hsv.saturation/255.0) * cos( cur_hsv.hue*M_PI/180.0)));
2977 panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 + (cur_hsv.saturation/255.0) * sin(-cur_hsv.hue*M_PI/180.0)));
2979 for (i = 0; i < 256; i++) {
2980 /* We divide by 128 in advance, and check whether that number divides
2981 * by 2 properly. If not, we add one to round the number correctly
2983 v = (i*cur_hsv.value) >> 7;
2984 panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) + (v & 1));
2988 static void
2989 grayInit(W_ColorPanel *panel)
2991 RHSVColor cur_hsv;
2992 int value;
2993 char tmp[4];
2995 RRGBtoHSV(&panel->color, &cur_hsv);
2997 value = rint(cur_hsv.value/2.55);
2998 WMSetSliderValue(panel->grayBrightnessS, value);
3000 sprintf(tmp, "%d", value);
3001 WMSetTextFieldText(panel->grayBrightnessT, tmp);
3004 static void
3005 rgbInit(W_ColorPanel *panel)
3007 char tmp[4];
3009 WMSetSliderValue(panel->rgbRedS,panel->color.red);
3010 WMSetSliderValue(panel->rgbGreenS,panel->color.green);
3011 WMSetSliderValue(panel->rgbBlueS,panel->color.blue);
3013 sprintf(tmp, "%d", panel->color.red);
3014 WMSetTextFieldText(panel->rgbRedT, tmp);
3015 sprintf(tmp, "%d", panel->color.green);
3016 WMSetTextFieldText(panel->rgbGreenT, tmp);
3017 sprintf(tmp, "%d", panel->color.blue);
3018 WMSetTextFieldText(panel->rgbBlueT, tmp);
3021 static void
3022 cmykInit(W_ColorPanel *panel)
3024 int value[3];
3025 char tmp[4];
3027 value[0] = rint((255-panel->color.red)/2.55);
3028 value[1] = rint((255-panel->color.green)/2.55);
3029 value[2] = rint((255-panel->color.blue)/2.55);
3031 WMSetSliderValue(panel->cmykCyanS, value[0]);
3032 WMSetSliderValue(panel->cmykMagentaS, value[1]);
3033 WMSetSliderValue(panel->cmykYellowS, value[2]);
3034 WMSetSliderValue(panel->cmykBlackS, 0);
3036 sprintf(tmp, "%d", value[0]);
3037 WMSetTextFieldText(panel->cmykCyanT, tmp);
3038 sprintf(tmp, "%d", value[1]);
3039 WMSetTextFieldText(panel->cmykMagentaT, tmp);
3040 sprintf(tmp, "%d", value[2]);
3041 WMSetTextFieldText(panel->cmykYellowT, tmp);
3042 WMSetTextFieldText(panel->cmykBlackT, "0");
3045 static void
3046 hsbInit(W_ColorPanel *panel)
3048 int value[3];
3049 char tmp[4];
3051 value[0] = panel->hsvcolor.hue;
3052 value[1] = rint(panel->hsvcolor.saturation/2.55);
3053 value[2] = rint(panel->hsvcolor.value/2.55);
3055 WMSetSliderValue(panel->hsbHueS,value[0]);
3056 WMSetSliderValue(panel->hsbSaturationS,value[1]);
3057 WMSetSliderValue(panel->hsbBrightnessS,value[2]);
3059 sprintf(tmp, "%d", value[0]);
3060 WMSetTextFieldText(panel->hsbHueT, tmp);
3061 sprintf(tmp, "%d", value[1]);
3062 WMSetTextFieldText(panel->hsbSaturationT, tmp);
3063 sprintf(tmp, "%d", value[2]);
3064 WMSetTextFieldText(panel->hsbBrightnessT, tmp);
3066 hsbUpdateBrightnessGradient(panel);
3067 hsbUpdateSaturationGradient(panel);
3068 hsbUpdateHueGradient(panel);
3074 /************************* ColorList Panel Functions **********************/
3076 static void
3077 colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text, int state, WMRect *rect)
3079 int width, height, x, y;
3080 RColor color = *((RColor *)WMGetListItem(lPtr, index)->clientData);
3081 WMScreen *scr = WMWidgetScreen(lPtr);
3082 Display *dpy = WMScreenDisplay(scr);
3083 W_ColorPanel *panel = WMGetHangedData(lPtr);
3084 WMColor *white = WMWhiteColor(scr);
3085 WMColor *black = WMBlackColor(scr);
3086 WMColor *fillColor;
3088 width = rect->size.width;
3089 height = rect->size.height;
3090 x = rect->pos.x;
3091 y = rect->pos.y;
3093 if (state & WLDSSelected)
3094 WMPaintColorSwatch(white, d, x +15, y, width -15, height);
3095 else
3096 XClearArea(dpy, d, x +15, y, width -15, height, False);
3098 fillColor = WMCreateRGBColor(scr, color.red*256, color.green*256, color.blue*256, False);
3100 WMSetColorInGC(fillColor, WMColorGC(fillColor));
3101 WMPaintColorSwatch(fillColor, d, x, y, 15, 15);
3102 WMReleaseColor(fillColor);
3104 WMDrawString(scr, d, WMColorGC(black), panel->font12, x+18, y, text, strlen(text));
3106 WMReleaseColor(white);
3107 WMReleaseColor(black);
3111 static void
3112 colorListSelect(WMWidget *w, void *data)
3114 W_ColorPanel *panel = (W_ColorPanel *)data;
3115 RColor color = *((RColor *)WMGetListSelectedItem(w)->clientData);
3117 panel->lastChanged = WMColorListModeColorPanel;
3118 WMSetColorPanelColor(panel, color);
3122 static void
3123 colorListColorMenuCallback(WMWidget *w, void *data)
3125 W_ColorPanel *panel = (W_ColorPanel *)data;
3126 int item = WMGetPopUpButtonSelectedItem(panel->colorListColorMenuBtn);
3128 switch (item) {
3129 case CLmenuAdd:
3130 break;
3131 case CLmenuRename:
3132 break;
3133 case CLmenuRemove:
3134 break;
3139 static void
3140 colorListListMenuCallback(WMWidget *w, void *data)
3142 W_ColorPanel *panel = (W_ColorPanel *)data;
3143 int item = WMGetPopUpButtonSelectedItem(panel->colorListListMenuBtn);
3145 switch (item) {
3146 case CLmenuAdd:
3147 /* New Color List */
3148 colorListListMenuNew(panel);
3149 break;
3150 case CLmenuRename:
3151 break;
3152 case CLmenuRemove:
3153 break;
3158 static void
3159 colorListListMenuNew(W_ColorPanel *panel)
3165 /************************** Common utility functions ************************/
3167 static int
3168 fetchFile(char *toPath, char *srcFile, char *destFile)
3170 int src, dest;
3171 int n;
3172 char *tmp;
3173 char buf[BUFSIZE];
3175 if ((src = open(srcFile, O_RDONLY)) == 0) {
3176 wsyserror("Could not open %s", srcFile);
3177 return -1;
3180 tmp = wstrappend(toPath, destFile);
3181 if ((dest = open( tmp, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == 0) {
3182 wsyserror("Could not create %s", tmp);
3183 free(tmp);
3184 return -1;
3186 free(tmp);
3189 /* Copy the file */
3190 while ((n = read(src, buf, BUFSIZE)) > 0)
3192 if (write (dest, buf, n) != n) {
3193 wsyserror("Write error on file %s", destFile);
3194 return -1;
3198 return 0;
3202 char*
3203 generateNewFilename(char *curName)
3205 int n;
3206 char c;
3207 int baseLen;
3208 char *ptr;
3209 char *newName;
3211 ptr = curName;
3213 while ((ptr = strrchr(ptr, '{')) && !(sscanf(ptr, "{%i}%c", &n, &c)==1)) {
3214 ptr++;
3216 if (!ptr)
3217 return wstrappend(curName, " {1}");
3219 baseLen = ptr - curName -1;
3221 newName = wmalloc(baseLen + 16);
3222 strncpy(newName, curName, baseLen);
3223 newName[baseLen] = 0;
3225 sprintf(&newName[baseLen], " {%i}", n+1);
3227 return newName;