removed listbag added tree bag
[wmaker-crm.git] / WINGs / wcolorwell.c
blobd5a2091dad3624623859659f5cb0cd83a685d206
5 #include "WINGsP.h"
8 char *WMColorWellDidChangeNotification = "WMColorWellDidChangeNotification";
11 typedef struct W_ColorWell {
12 W_Class widgetClass;
13 WMView *view;
15 WMView *colorView;
17 WMColor *color;
19 WMAction *action;
20 void *clientData;
22 WMPoint ipoint;
24 struct {
25 unsigned int active:1;
26 unsigned int bordered:1;
27 } flags;
28 } ColorWell;
30 static char *_ColorWellActivatedNotification = "_ColorWellActivatedNotification";
34 static void destroyColorWell(ColorWell *cPtr);
35 static void paintColorWell(ColorWell *cPtr);
37 static void handleEvents(XEvent *event, void *data);
39 static void handleDragEvents(XEvent *event, void *data);
41 static void handleActionEvents(XEvent *event, void *data);
43 static void willResizeColorWell();
47 W_ViewDelegate _ColorWellViewDelegate = {
48 NULL,
49 NULL,
50 NULL,
51 NULL,
52 willResizeColorWell
56 static unsigned draggingSourceOperation(WMView *self, Bool local);
57 static void beganDragImage(WMView *self, WMPixmap *image, WMPoint point);
58 static void endedDragImage(WMView *self, WMPixmap *image, WMPoint point,
59 Bool deposited);
62 static WMDragSourceProcs _DragSourceProcs = {
63 draggingSourceOperation,
64 beganDragImage,
65 endedDragImage,
66 NULL
70 static unsigned draggingEntered(WMView *self, WMDraggingInfo *info);
71 static unsigned draggingUpdated(WMView *self, WMDraggingInfo *info);
72 static void draggingExited(WMView *self, WMDraggingInfo *info);
73 static Bool prepareForDragOperation(WMView *self, WMDraggingInfo *info);
74 static Bool performDragOperation(WMView *self, WMDraggingInfo *info);
75 static void concludeDragOperation(WMView *self, WMDraggingInfo *info);
77 static WMDragDestinationProcs _DragDestinationProcs = {
78 draggingEntered,
79 draggingUpdated,
80 draggingExited,
81 prepareForDragOperation,
82 performDragOperation,
83 concludeDragOperation
87 #define DEFAULT_WIDTH 60
88 #define DEFAULT_HEIGHT 30
89 #define DEFAULT_BORDER_WIDTH 6
91 #define MIN_WIDTH 16
92 #define MIN_HEIGHT 8
96 static void
97 colorChangedObserver(void *data, WMNotification *notification)
99 WMColorPanel *panel = (WMColorPanel*)WMGetNotificationObject(notification);
100 WMColorWell *cPtr = (WMColorWell*)data;
101 WMColor *color;
103 if (!cPtr->flags.active)
104 return;
106 color = WMGetColorPanelColor(panel);
108 WMSetColorWellColor(cPtr, color);
109 WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
113 static void
114 updateColorCallback(void *self, void *data)
116 WMColorPanel *panel = (WMColorPanel*)self;
117 WMColorWell *cPtr = (ColorWell*)data;
118 WMColor *color;
120 color = WMGetColorPanelColor(panel);
121 WMSetColorWellColor(cPtr, color);
122 WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
127 static void
128 activatedObserver(void *data, WMNotification *notification)
131 WMColorWell *cPtr = (WMColorWell*)data;
133 if (!cPtr->flags.active || WMGetNotificationObject(notification) == cPtr)
134 return;
136 W_SetViewBackgroundColor(cPtr->view, WMWidgetScreen(cPtr)->gray);
137 paintColorWell(cPtr);
139 cPtr->flags.active = 0;
145 WMColorWell*
146 WMCreateColorWell(WMWidget *parent)
148 ColorWell *cPtr;
150 cPtr = wmalloc(sizeof(ColorWell));
151 memset(cPtr, 0, sizeof(ColorWell));
153 cPtr->widgetClass = WC_ColorWell;
155 cPtr->view = W_CreateView(W_VIEW(parent));
156 if (!cPtr->view) {
157 wfree(cPtr);
158 return NULL;
160 cPtr->view->self = cPtr;
162 cPtr->view->delegate = &_ColorWellViewDelegate;
164 cPtr->colorView = W_CreateView(cPtr->view);
165 if (!cPtr->colorView) {
166 W_DestroyView(cPtr->view);
167 wfree(cPtr);
168 return NULL;
170 cPtr->colorView->self = cPtr;
172 WMCreateEventHandler(cPtr->view, ExposureMask|StructureNotifyMask
173 |ClientMessageMask, handleEvents, cPtr);
175 WMCreateEventHandler(cPtr->colorView, ExposureMask, handleEvents, cPtr);
177 WMCreateEventHandler(cPtr->colorView, ButtonPressMask|ButtonMotionMask
178 |EnterWindowMask, handleDragEvents, cPtr);
180 WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents,
181 cPtr);
183 cPtr->colorView->flags.mapWhenRealized = 1;
185 cPtr->flags.bordered = 1;
187 W_ResizeView(cPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
189 WMAddNotificationObserver(activatedObserver, cPtr,
190 _ColorWellActivatedNotification, NULL);
192 cPtr->color = WMBlackColor(WMWidgetScreen(cPtr));
194 WMAddNotificationObserver(colorChangedObserver, cPtr,
195 WMColorPanelColorChangedNotification, NULL);
197 // WMSetViewDragSourceProcs(cPtr->view, &_DragSourceProcs);
198 // WMSetViewDragDestinationProcs(cPtr->view, &_DragDestinationProcs);
201 char *types[2] = {"application/X-color", NULL};
203 //WMRegisterViewForDraggedTypes(cPtr->view, types);
206 return cPtr;
210 void
211 WMSetColorWellColor(WMColorWell *cPtr, WMColor *color)
213 if (cPtr->color)
214 WMReleaseColor(cPtr->color);
216 cPtr->color = WMRetainColor(color);
218 if (cPtr->colorView->flags.realized && cPtr->colorView->flags.mapped)
219 paintColorWell(cPtr);
223 WMColor*
224 WMGetColorWellColor(WMColorWell *cPtr)
226 return cPtr->color;
230 void
231 WSetColorWellBordered(WMColorWell *cPtr, Bool flag)
233 if (cPtr->flags.bordered != flag) {
234 cPtr->flags.bordered = flag;
235 W_ResizeView(cPtr->view, cPtr->view->size.width, cPtr->view->size.height);
240 #define MIN(a,b) ((a) > (b) ? (b) : (a))
242 static void
243 willResizeColorWell(W_ViewDelegate *self, WMView *view,
244 unsigned int *width, unsigned int *height)
246 WMColorWell *cPtr = (WMColorWell*)view->self;
247 int bw;
249 if (cPtr->flags.bordered) {
251 if (*width < MIN_WIDTH)
252 *width = MIN_WIDTH;
253 if (*height < MIN_HEIGHT)
254 *height = MIN_HEIGHT;
256 bw = (int)((float)MIN(*width, *height)*0.24);
258 W_ResizeView(cPtr->colorView, *width-2*bw, *height-2*bw);
260 if (cPtr->colorView->pos.x!=bw || cPtr->colorView->pos.y!=bw)
261 W_MoveView(cPtr->colorView, bw, bw);
262 } else {
263 W_ResizeView(cPtr->colorView, *width, *height);
265 W_MoveView(cPtr->colorView, 0, 0);
270 static void
271 paintColorWell(ColorWell *cPtr)
273 W_Screen *scr = cPtr->view->screen;
275 W_DrawRelief(scr, cPtr->view->window, 0, 0, cPtr->view->size.width,
276 cPtr->view->size.height, WRRaised);
278 W_DrawRelief(scr, cPtr->colorView->window, 0, 0,
279 cPtr->colorView->size.width, cPtr->colorView->size.height,
280 WRSunken);
282 if (cPtr->color)
283 WMPaintColorSwatch(cPtr->color, cPtr->colorView->window,
284 2, 2, cPtr->colorView->size.width-4,
285 cPtr->colorView->size.height-4);
290 static void
291 handleEvents(XEvent *event, void *data)
293 ColorWell *cPtr = (ColorWell*)data;
295 CHECK_CLASS(data, WC_ColorWell);
298 switch (event->type) {
299 case Expose:
300 if (event->xexpose.count!=0)
301 break;
302 paintColorWell(cPtr);
303 break;
305 case DestroyNotify:
306 destroyColorWell(cPtr);
307 break;
313 static unsigned
314 draggingSourceOperation(WMView *self, Bool local)
316 puts("DRAG SOURCE");
317 return 0;
321 static void
322 beganDragImage(WMView *self, WMPixmap *image, WMPoint point)
324 puts("BEGAN DRAG");
328 static void
329 endedDragImage(WMView *self, WMPixmap *image, WMPoint point, Bool deposited)
331 if (deposited)
332 puts("ENDED DRAG SUCCESS");
333 else
334 puts("ENDED DRAG CANCEL");
339 static WMPixmap*
340 makeDragPixmap(WMColorWell *cPtr)
342 WMScreen *scr = cPtr->view->screen;
343 Pixmap pix;
345 pix = XCreatePixmap(scr->display, W_DRAWABLE(scr), 16, 16, scr->depth);
347 XFillRectangle(scr->display, pix, WMColorGC(cPtr->color), 0, 0, 15, 15);
349 XDrawRectangle(scr->display, pix, WMColorGC(scr->black), 0, 0, 15, 15);
351 return WMCreatePixmapFromXPixmaps(scr, pix, None, 16, 16, scr->depth);
355 static void
356 handleDragEvents(XEvent *event, void *data)
358 WMColorWell *cPtr = (ColorWell*)data;
360 switch (event->type) {
361 case ButtonPress:
362 if (event->xbutton.button == Button1) {
363 cPtr->ipoint.x = event->xbutton.x;
364 cPtr->ipoint.y = event->xbutton.y;
366 break;
368 case MotionNotify:
369 if (event->xmotion.state & Button1Mask) {
370 if (abs(cPtr->ipoint.x - event->xmotion.x) > 4
371 || abs(cPtr->ipoint.y - event->xmotion.y) > 4) {
372 WMSize offs;
373 WMPixmap *pixmap;
374 char *types[2] = {"application/X-color", NULL};
376 offs.width = 2;
377 offs.height = 2;
378 pixmap = makeDragPixmap(cPtr);
380 WMDragImageFromView(cPtr->view, pixmap, types,
381 wmkpoint(event->xmotion.x_root,
382 event->xmotion.y_root),
383 offs, event, True);
386 WMReleasePixmap(pixmap);
389 break;
394 static void
395 handleActionEvents(XEvent *event, void *data)
397 WMColorWell *cPtr = (ColorWell*)data;
398 WMScreen *scr = WMWidgetScreen(cPtr);
399 WMColorPanel *cpanel;
401 if (cPtr->flags.active)
402 W_SetViewBackgroundColor(cPtr->view, scr->gray);
403 else
404 W_SetViewBackgroundColor(cPtr->view, scr->white);
405 paintColorWell(cPtr);
407 cPtr->flags.active ^= 1;
409 if (cPtr->flags.active) {
410 WMPostNotificationName(_ColorWellActivatedNotification, cPtr, NULL);
412 cpanel = WMGetColorPanel(scr);
414 WMSetColorPanelAction(cpanel, updateColorCallback, cPtr);
416 if (cPtr->color)
417 WMSetColorPanelColor(cpanel, cPtr->color);
418 WMShowColorPanel(cpanel);
422 static void
423 destroyColorWell(ColorWell *cPtr)
425 WMRemoveNotificationObserver(cPtr);
427 if (cPtr->color)
428 WMReleaseColor(cPtr->color);
430 wfree(cPtr);
435 static unsigned
436 draggingEntered(WMView *self, WMDraggingInfo *info)
438 WMPoint point = WMGetViewScreenPosition(self);
440 printf("%i %i || %i %i %i %i\n", info->location.x, info->location.y,
441 point.x, point.y, W_VIEW_WIDTH(self), W_VIEW_HEIGHT(self));
443 if (info->location.x >= point.x
444 && info->location.y >= point.y
445 && info->location.x < point.x + W_VIEW_WIDTH(self)
446 && info->location.y < point.y + W_VIEW_HEIGHT(self)) {
447 /* self */
448 puts("ENTERED 0");
449 return 0;
450 } else {
451 puts("ENTERED 1");
452 return 1;
457 static unsigned
458 draggingUpdated(WMView *self, WMDraggingInfo *info)
461 WMPoint point = WMGetViewScreenPosition(self);
463 puts("UPDATED");
464 if (info->location.x >= point.x
465 && info->location.y >= point.y
466 && info->location.x < point.x + W_VIEW_WIDTH(self)
467 && info->location.y < point.y + W_VIEW_WIDTH(self)) {
468 return 0;
469 } else {
470 return 1;
475 static void
476 draggingExited(WMView *self, WMDraggingInfo *info)
478 puts("EXITED");
482 static Bool
483 prepareForDragOperation(WMView *self, WMDraggingInfo *info)
485 puts("PREPARING");
486 return True;
490 static Bool
491 performDragOperation(WMView *self, WMDraggingInfo *info)
493 WMData *data;
495 // data = WMGetDroppedData(self);
496 puts("DROPPED");
497 return True;
501 static void
502 concludeDragOperation(WMView *self, WMDraggingInfo *info)
504 puts("FINISHED");