WINGs: Added 'const' attribute to function 'WMCreateHashTable'
[wmaker-crm.git] / WINGs / wcolorwell.c
bloba4b94ff5309f9f2c204c61894ffbe4d3fe4c68fd
2 #include "WINGsP.h"
4 #define XDND_COLOR_DATA_TYPE "application/X-color"
6 char *WMColorWellDidChangeNotification = "WMColorWellDidChangeNotification";
8 typedef struct W_ColorWell {
9 W_Class widgetClass;
10 WMView *view;
12 WMView *colorView;
14 WMColor *color;
16 WMAction *action;
17 void *clientData;
19 WMPoint ipoint;
21 struct {
22 unsigned int active:1;
23 unsigned int bordered:1;
24 } flags;
26 WMArray *xdndTypes;
27 } ColorWell;
29 static char *_ColorWellActivatedNotification = "_ColorWellActivatedNotification";
31 static void destroyColorWell(ColorWell * cPtr);
32 static void paintColorWell(ColorWell * cPtr);
34 static void handleEvents(XEvent * event, void *data);
36 static void handleDragEvents(XEvent * event, void *data);
38 static void handleActionEvents(XEvent * event, void *data);
40 static void willResizeColorWell(W_ViewDelegate * self, WMView * view, unsigned int *width, unsigned int *height);
42 W_ViewDelegate _ColorWellViewDelegate = {
43 NULL,
44 NULL,
45 NULL,
46 NULL,
47 willResizeColorWell
50 static WMArray *dropDataTypes(WMView * self);
51 static WMDragOperationType wantedDropOperation(WMView * self);
52 static Bool acceptDropOperation(WMView * self, WMDragOperationType operation);
53 static WMData *fetchDragData(WMView * self, char *type);
55 static WMDragSourceProcs _DragSourceProcs = {
56 dropDataTypes,
57 wantedDropOperation,
58 NULL,
59 acceptDropOperation,
60 NULL,
61 NULL,
62 fetchDragData
65 static WMArray *requiredDataTypes(WMView * self,
66 WMDragOperationType requestedOperation, WMArray * sourceDataTypes);
67 static WMDragOperationType allowedOperation(WMView * self,
68 WMDragOperationType requestedOperation, WMArray * sourceDataTypes);
69 static void performDragOperation(WMView * self, WMArray * dropDatas,
70 WMArray * operationsList, WMPoint * dropLocation);
72 static WMDragDestinationProcs _DragDestinationProcs = {
73 NULL,
74 requiredDataTypes,
75 allowedOperation,
76 NULL,
77 performDragOperation,
78 NULL
81 #define DEFAULT_WIDTH 60
82 #define DEFAULT_HEIGHT 30
83 #define DEFAULT_BORDER_WIDTH 6
85 #define MIN_WIDTH 16
86 #define MIN_HEIGHT 8
88 static void colorChangedObserver(void *data, WMNotification * notification)
90 WMColorPanel *panel = (WMColorPanel *) WMGetNotificationObject(notification);
91 WMColorWell *cPtr = (WMColorWell *) data;
92 WMColor *color;
94 if (!cPtr->flags.active)
95 return;
97 color = WMGetColorPanelColor(panel);
99 WMSetColorWellColor(cPtr, color);
100 WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
103 static void updateColorCallback(void *self, void *data)
105 WMColorPanel *panel = (WMColorPanel *) self;
106 WMColorWell *cPtr = (ColorWell *) data;
107 WMColor *color;
109 color = WMGetColorPanelColor(panel);
110 WMSetColorWellColor(cPtr, color);
111 WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
114 static void activatedObserver(void *data, WMNotification * notification)
117 WMColorWell *cPtr = (WMColorWell*)data;
119 if (!cPtr->flags.active || WMGetNotificationObject(notification) == cPtr)
120 return;
122 W_SetViewBackgroundColor(cPtr->view, WMWidgetScreen(cPtr)->gray);
123 paintColorWell(cPtr);
125 cPtr->flags.active = 0;
129 static WMArray *getXdndTypeArray(void)
131 WMArray *types = WMCreateArray(1);
132 WMAddToArray(types, XDND_COLOR_DATA_TYPE);
133 return types;
136 WMColorWell *WMCreateColorWell(WMWidget * parent)
138 ColorWell *cPtr;
140 cPtr = wmalloc(sizeof(ColorWell));
142 cPtr->widgetClass = WC_ColorWell;
144 cPtr->view = W_CreateView(W_VIEW(parent));
145 if (!cPtr->view) {
146 wfree(cPtr);
147 return NULL;
149 cPtr->view->self = cPtr;
151 cPtr->view->delegate = &_ColorWellViewDelegate;
153 cPtr->colorView = W_CreateView(cPtr->view);
154 if (!cPtr->colorView) {
155 W_DestroyView(cPtr->view);
156 wfree(cPtr);
157 return NULL;
159 cPtr->colorView->self = cPtr;
161 WMCreateEventHandler(cPtr->view, ExposureMask | StructureNotifyMask
162 | ClientMessageMask, handleEvents, cPtr);
164 WMCreateEventHandler(cPtr->colorView, ExposureMask, handleEvents, cPtr);
166 WMCreateDragHandler(cPtr->colorView, handleDragEvents, cPtr);
168 WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents, cPtr);
170 cPtr->colorView->flags.mapWhenRealized = 1;
172 cPtr->flags.bordered = 1;
174 W_ResizeView(cPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
176 WMAddNotificationObserver(activatedObserver, cPtr, _ColorWellActivatedNotification, NULL);
178 cPtr->color = WMBlackColor(WMWidgetScreen(cPtr));
180 WMAddNotificationObserver(colorChangedObserver, cPtr, WMColorPanelColorChangedNotification, NULL);
182 WMSetViewDragSourceProcs(cPtr->colorView, &_DragSourceProcs);
183 WMSetViewDragDestinationProcs(cPtr->colorView, &_DragDestinationProcs);
185 cPtr->xdndTypes = getXdndTypeArray();
186 WMRegisterViewForDraggedTypes(cPtr->colorView, cPtr->xdndTypes);
188 return cPtr;
191 void WMSetColorWellColor(WMColorWell * cPtr, WMColor * color)
193 if (cPtr->color)
194 WMReleaseColor(cPtr->color);
196 cPtr->color = WMRetainColor(color);
198 if (cPtr->colorView->flags.realized && cPtr->colorView->flags.mapped)
199 paintColorWell(cPtr);
202 WMColor *WMGetColorWellColor(WMColorWell * cPtr)
204 return cPtr->color;
207 void WSetColorWellBordered(WMColorWell * cPtr, Bool flag)
209 flag = ((flag == 0) ? 0 : 1);
210 if (cPtr->flags.bordered != flag) {
211 cPtr->flags.bordered = flag;
212 W_ResizeView(cPtr->view, cPtr->view->size.width, cPtr->view->size.height);
216 static void willResizeColorWell(W_ViewDelegate * self, WMView * view, unsigned int *width, unsigned int *height)
218 WMColorWell *cPtr = (WMColorWell *) view->self;
219 int bw;
221 /* Parameter not used, but tell the compiler that it is ok */
222 (void) self;
224 if (cPtr->flags.bordered) {
226 if (*width < MIN_WIDTH)
227 *width = MIN_WIDTH;
228 if (*height < MIN_HEIGHT)
229 *height = MIN_HEIGHT;
231 bw = (int)((float)WMIN(*width, *height) * 0.24);
233 W_ResizeView(cPtr->colorView, *width - 2 * bw, *height - 2 * bw);
235 if (cPtr->colorView->pos.x != bw || cPtr->colorView->pos.y != bw)
236 W_MoveView(cPtr->colorView, bw, bw);
237 } else {
238 W_ResizeView(cPtr->colorView, *width, *height);
240 W_MoveView(cPtr->colorView, 0, 0);
244 static void paintColorWell(ColorWell * cPtr)
246 W_Screen *scr = cPtr->view->screen;
248 W_DrawRelief(scr, cPtr->view->window, 0, 0, cPtr->view->size.width, cPtr->view->size.height, WRRaised);
250 W_DrawRelief(scr, cPtr->colorView->window, 0, 0,
251 cPtr->colorView->size.width, cPtr->colorView->size.height, WRSunken);
253 if (cPtr->color)
254 WMPaintColorSwatch(cPtr->color, cPtr->colorView->window,
255 2, 2, cPtr->colorView->size.width - 4, cPtr->colorView->size.height - 4);
258 static void handleEvents(XEvent * event, void *data)
260 ColorWell *cPtr = (ColorWell *) data;
262 CHECK_CLASS(data, WC_ColorWell);
264 switch (event->type) {
265 case Expose:
266 if (event->xexpose.count != 0)
267 break;
268 paintColorWell(cPtr);
269 break;
271 case DestroyNotify:
272 destroyColorWell(cPtr);
273 break;
278 static WMArray *dropDataTypes(WMView * self)
280 return ((ColorWell *) self->self)->xdndTypes;
283 static WMDragOperationType wantedDropOperation(WMView * self)
285 /* Parameter not used, but tell the compiler that it is ok */
286 (void) self;
288 return WDOperationCopy;
291 static Bool acceptDropOperation(WMView * self, WMDragOperationType operation)
293 /* Parameter not used, but tell the compiler that it is ok */
294 (void) self;
296 return (operation == WDOperationCopy);
299 static WMData *fetchDragData(WMView * self, char *type)
301 char *color = WMGetColorRGBDescription(((WMColorWell *) self->self)->color);
302 WMData *data;
304 /* Parameter not used, but tell the compiler that it is ok */
305 (void) type;
307 data = WMCreateDataWithBytes(color, strlen(color) + 1);
308 wfree(color);
310 return data;
313 static WMPixmap *makeDragPixmap(WMColorWell * cPtr)
315 WMScreen *scr = cPtr->view->screen;
316 Pixmap pix;
318 pix = XCreatePixmap(scr->display, W_DRAWABLE(scr), 16, 16, scr->depth);
320 XFillRectangle(scr->display, pix, WMColorGC(cPtr->color), 0, 0, 15, 15);
322 XDrawRectangle(scr->display, pix, WMColorGC(scr->black), 0, 0, 15, 15);
324 return WMCreatePixmapFromXPixmaps(scr, pix, None, 16, 16, scr->depth);
327 static void handleDragEvents(XEvent * event, void *data)
329 WMColorWell *cPtr = (ColorWell *) data;
331 if (event->type == ButtonPress && event->xbutton.button == Button1) {
332 /* initialise drag icon */
333 WMSetViewDragImage(cPtr->colorView, makeDragPixmap(cPtr));
336 WMDragImageFromView(cPtr->colorView, event);
339 static void handleActionEvents(XEvent * event, void *data)
341 WMColorWell *cPtr = (ColorWell *) data;
342 WMScreen *scr = WMWidgetScreen(cPtr);
343 WMColorPanel *cpanel;
345 /* Parameter not used, but tell the compiler that it is ok */
346 (void) event;
348 if (cPtr->flags.active)
349 W_SetViewBackgroundColor(cPtr->view, scr->gray);
350 else
351 W_SetViewBackgroundColor(cPtr->view, scr->white);
352 paintColorWell(cPtr);
354 cPtr->flags.active ^= 1;
356 if (cPtr->flags.active) {
357 WMPostNotificationName(_ColorWellActivatedNotification, cPtr, NULL);
359 cpanel = WMGetColorPanel(scr);
361 WMSetColorPanelAction(cpanel, updateColorCallback, cPtr);
363 if (cPtr->color)
364 WMSetColorPanelColor(cpanel, cPtr->color);
365 WMShowColorPanel(cpanel);
368 static void destroyColorWell(ColorWell * cPtr)
370 WMRemoveNotificationObserver(cPtr);
372 if (cPtr->color)
373 WMReleaseColor(cPtr->color);
375 WMFreeArray(cPtr->xdndTypes);
377 wfree(cPtr);
380 static Bool dropIsOk(WMDragOperationType request, WMArray * sourceDataTypes)
382 WMArrayIterator iter;
383 char *type;
385 if (request == WDOperationCopy) {
386 WM_ITERATE_ARRAY(sourceDataTypes, type, iter) {
387 if (type != NULL && strcmp(type, XDND_COLOR_DATA_TYPE) == 0) {
388 return True;
393 return False;
396 static WMArray *requiredDataTypes(WMView * self, WMDragOperationType request, WMArray * sourceDataTypes)
398 if (dropIsOk(request, sourceDataTypes))
399 return ((ColorWell *) self->self)->xdndTypes;
400 else
401 return NULL;
404 static WMDragOperationType allowedOperation(WMView * self, WMDragOperationType request, WMArray * sourceDataTypes)
406 /* Parameter not used, but tell the compiler that it is ok */
407 (void) self;
409 if (dropIsOk(request, sourceDataTypes))
410 return WDOperationCopy;
411 else
412 return WDOperationNone;
415 static void performDragOperation(WMView * self, WMArray * dropData, WMArray * operations, WMPoint * dropLocation)
417 char *colorName;
418 WMColor *color;
419 WMData *data;
421 /* Parameter not used, but tell the compiler that it is ok */
422 (void) operations;
423 (void) dropLocation;
425 /* only one operation requested (WDOperationCopy) implies only one data */
426 data = (WMData *) WMGetFromArray(dropData, 0);
428 if (data != NULL) {
429 colorName = (char *)WMDataBytes(data);
430 color = WMCreateNamedColor(W_VIEW_SCREEN(self), colorName, True);
431 WMSetColorWellColor(self->self, color);
432 WMReleaseColor(color);