Update Serbian translation from master branch
[wmaker-crm.git] / WINGs / wcolorwell.c
blobb71d5ba413d4cc7de45ed2c508aac9741ad6d063
2 #include "WINGsP.h"
4 #define XDND_COLOR_DATA_TYPE "application/X-color"
6 const 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
84 #define MIN_WIDTH 16
85 #define MIN_HEIGHT 8
87 static void colorChangedObserver(void *data, WMNotification * notification)
89 WMColorPanel *panel = (WMColorPanel *) WMGetNotificationObject(notification);
90 WMColorWell *cPtr = (WMColorWell *) data;
91 WMColor *color;
93 if (!cPtr->flags.active)
94 return;
96 color = WMGetColorPanelColor(panel);
98 WMSetColorWellColor(cPtr, color);
99 WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
102 static void updateColorCallback(void *self, void *data)
104 WMColorPanel *panel = (WMColorPanel *) self;
105 WMColorWell *cPtr = (ColorWell *) data;
106 WMColor *color;
108 color = WMGetColorPanelColor(panel);
109 WMSetColorWellColor(cPtr, color);
110 WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
113 static WMArray *getXdndTypeArray(void)
115 WMArray *types = WMCreateArray(1);
116 WMAddToArray(types, XDND_COLOR_DATA_TYPE);
117 return types;
120 WMColorWell *WMCreateColorWell(WMWidget * parent)
122 ColorWell *cPtr;
124 cPtr = wmalloc(sizeof(ColorWell));
126 cPtr->widgetClass = WC_ColorWell;
128 cPtr->view = W_CreateView(W_VIEW(parent));
129 if (!cPtr->view) {
130 wfree(cPtr);
131 return NULL;
133 cPtr->view->self = cPtr;
135 cPtr->view->delegate = &_ColorWellViewDelegate;
137 cPtr->colorView = W_CreateView(cPtr->view);
138 if (!cPtr->colorView) {
139 W_DestroyView(cPtr->view);
140 wfree(cPtr);
141 return NULL;
143 cPtr->colorView->self = cPtr;
145 WMCreateEventHandler(cPtr->view, ExposureMask | StructureNotifyMask
146 | ClientMessageMask, handleEvents, cPtr);
148 WMCreateEventHandler(cPtr->colorView, ExposureMask, handleEvents, cPtr);
150 WMCreateDragHandler(cPtr->colorView, handleDragEvents, cPtr);
152 WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents, cPtr);
153 WMCreateEventHandler(cPtr->colorView, ButtonPressMask, handleActionEvents, cPtr);
155 cPtr->colorView->flags.mapWhenRealized = 1;
157 cPtr->flags.bordered = 1;
159 W_ResizeView(cPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
161 cPtr->color = WMBlackColor(WMWidgetScreen(cPtr));
163 WMAddNotificationObserver(colorChangedObserver, cPtr, WMColorPanelColorChangedNotification, NULL);
165 WMSetViewDragSourceProcs(cPtr->colorView, &_DragSourceProcs);
166 WMSetViewDragDestinationProcs(cPtr->colorView, &_DragDestinationProcs);
168 cPtr->xdndTypes = getXdndTypeArray();
169 WMRegisterViewForDraggedTypes(cPtr->colorView, cPtr->xdndTypes);
171 return cPtr;
174 void WMSetColorWellColor(WMColorWell * cPtr, WMColor * color)
176 if (cPtr->color && cPtr->color != color) {
177 WMReleaseColor(cPtr->color);
178 cPtr->color = WMRetainColor(color);
181 if (cPtr->colorView->flags.realized && cPtr->colorView->flags.mapped)
182 paintColorWell(cPtr);
185 WMColor *WMGetColorWellColor(WMColorWell * cPtr)
187 return cPtr->color;
190 void WSetColorWellBordered(WMColorWell * cPtr, Bool flag)
192 flag = ((flag == 0) ? 0 : 1);
193 if (cPtr->flags.bordered != flag) {
194 cPtr->flags.bordered = flag;
195 W_ResizeView(cPtr->view, cPtr->view->size.width, cPtr->view->size.height);
199 static void willResizeColorWell(W_ViewDelegate * self, WMView * view, unsigned int *width, unsigned int *height)
201 WMColorWell *cPtr = (WMColorWell *) view->self;
202 int bw;
204 /* Parameter not used, but tell the compiler that it is ok */
205 (void) self;
207 if (cPtr->flags.bordered) {
209 if (*width < MIN_WIDTH)
210 *width = MIN_WIDTH;
211 if (*height < MIN_HEIGHT)
212 *height = MIN_HEIGHT;
214 bw = (int)((float)WMIN(*width, *height) * 0.24F);
216 W_ResizeView(cPtr->colorView, *width - 2 * bw, *height - 2 * bw);
218 if (cPtr->colorView->pos.x != bw || cPtr->colorView->pos.y != bw)
219 W_MoveView(cPtr->colorView, bw, bw);
220 } else {
221 W_ResizeView(cPtr->colorView, *width, *height);
223 W_MoveView(cPtr->colorView, 0, 0);
227 static void paintColorWell(ColorWell * cPtr)
229 W_Screen *scr = cPtr->view->screen;
231 W_DrawRelief(scr, cPtr->view->window, 0, 0, cPtr->view->size.width, cPtr->view->size.height, WRRaised);
233 W_DrawRelief(scr, cPtr->colorView->window, 0, 0,
234 cPtr->colorView->size.width, cPtr->colorView->size.height, WRSunken);
236 if (cPtr->color)
237 WMPaintColorSwatch(cPtr->color, cPtr->colorView->window,
238 2, 2, cPtr->colorView->size.width - 4, cPtr->colorView->size.height - 4);
241 static void handleEvents(XEvent * event, void *data)
243 ColorWell *cPtr = (ColorWell *) data;
245 CHECK_CLASS(data, WC_ColorWell);
247 switch (event->type) {
248 case Expose:
249 if (event->xexpose.count != 0)
250 break;
251 paintColorWell(cPtr);
252 break;
254 case DestroyNotify:
255 destroyColorWell(cPtr);
256 break;
261 static WMArray *dropDataTypes(WMView * self)
263 return ((ColorWell *) self->self)->xdndTypes;
266 static WMDragOperationType wantedDropOperation(WMView * self)
268 /* Parameter not used, but tell the compiler that it is ok */
269 (void) self;
271 return WDOperationCopy;
274 static Bool acceptDropOperation(WMView * self, WMDragOperationType operation)
276 /* Parameter not used, but tell the compiler that it is ok */
277 (void) self;
279 return (operation == WDOperationCopy);
282 static WMData *fetchDragData(WMView * self, char *type)
284 char *color = WMGetColorRGBDescription(((WMColorWell *) self->self)->color);
285 WMData *data;
287 /* Parameter not used, but tell the compiler that it is ok */
288 (void) type;
290 data = WMCreateDataWithBytes(color, strlen(color) + 1);
291 wfree(color);
293 return data;
296 static WMPixmap *makeDragPixmap(WMColorWell * cPtr)
298 WMScreen *scr = cPtr->view->screen;
299 Pixmap pix;
301 pix = XCreatePixmap(scr->display, W_DRAWABLE(scr), 16, 16, scr->depth);
303 XFillRectangle(scr->display, pix, WMColorGC(cPtr->color), 0, 0, 15, 15);
305 XDrawRectangle(scr->display, pix, WMColorGC(scr->black), 0, 0, 15, 15);
307 return WMCreatePixmapFromXPixmaps(scr, pix, None, 16, 16, scr->depth);
310 static void handleDragEvents(XEvent * event, void *data)
312 WMColorWell *cPtr = (ColorWell *) data;
314 if (event->type == ButtonPress && event->xbutton.button == Button1) {
315 /* initialise drag icon */
316 WMSetViewDragImage(cPtr->colorView, makeDragPixmap(cPtr));
319 WMDragImageFromView(cPtr->colorView, event);
322 static void handleActionEvents(XEvent * event, void *data)
324 WMColorWell *cPtr = (ColorWell *) data;
325 WMScreen *scr = WMWidgetScreen(cPtr);
326 WMColorPanel *cpanel;
328 /* Parameter not used, but tell the compiler that it is ok */
329 (void) event;
331 if (cPtr->flags.active)
332 W_SetViewBackgroundColor(cPtr->view, scr->gray);
333 else
334 W_SetViewBackgroundColor(cPtr->view, scr->white);
335 paintColorWell(cPtr);
337 cPtr->flags.active ^= 1;
339 if (cPtr->flags.active) {
340 WMPostNotificationName(_ColorWellActivatedNotification, cPtr, NULL);
342 cpanel = WMGetColorPanel(scr);
344 WMSetColorPanelAction(cpanel, updateColorCallback, cPtr);
346 if (cPtr->color)
347 WMSetColorPanelColor(cpanel, cPtr->color);
348 WMShowColorPanel(cpanel);
351 static void destroyColorWell(ColorWell * cPtr)
353 WMRemoveNotificationObserver(cPtr);
355 if (cPtr->color)
356 WMReleaseColor(cPtr->color);
358 WMFreeArray(cPtr->xdndTypes);
360 wfree(cPtr);
363 static Bool dropIsOk(WMDragOperationType request, WMArray * sourceDataTypes)
365 WMArrayIterator iter;
366 char *type;
368 if (request == WDOperationCopy) {
369 WM_ITERATE_ARRAY(sourceDataTypes, type, iter) {
370 if (type != NULL && strcmp(type, XDND_COLOR_DATA_TYPE) == 0) {
371 return True;
376 return False;
379 static WMArray *requiredDataTypes(WMView * self, WMDragOperationType request, WMArray * sourceDataTypes)
381 if (dropIsOk(request, sourceDataTypes))
382 return ((ColorWell *) self->self)->xdndTypes;
383 else
384 return NULL;
387 static WMDragOperationType allowedOperation(WMView * self, WMDragOperationType request, WMArray * sourceDataTypes)
389 /* Parameter not used, but tell the compiler that it is ok */
390 (void) self;
392 if (dropIsOk(request, sourceDataTypes))
393 return WDOperationCopy;
394 else
395 return WDOperationNone;
398 static void performDragOperation(WMView * self, WMArray * dropData, WMArray * operations, WMPoint * dropLocation)
400 char *colorName;
401 WMColor *color;
402 WMData *data;
404 /* Parameter not used, but tell the compiler that it is ok */
405 (void) operations;
406 (void) dropLocation;
408 /* only one operation requested (WDOperationCopy) implies only one data */
409 data = (WMData *) WMGetFromArray(dropData, 0);
411 if (data != NULL) {
412 colorName = (char *)WMDataBytes(data);
413 color = WMCreateNamedColor(W_VIEW_SCREEN(self), colorName, True);
414 WMSetColorWellColor(self->self, color);
415 WMReleaseColor(color);