7
#define XDND_COLOR_DATA_TYPE "application/X-color"
9
char *WMColorWellDidChangeNotification = "WMColorWellDidChangeNotification";
12
typedef struct W_ColorWell {
26
unsigned int active:1;
27
unsigned int bordered:1;
33
static char *_ColorWellActivatedNotification = "_ColorWellActivatedNotification";
37
static void destroyColorWell(ColorWell *cPtr);
38
static void paintColorWell(ColorWell *cPtr);
40
static void handleEvents(XEvent *event, void *data);
42
static void handleDragEvents(XEvent *event, void *data);
44
static void handleActionEvents(XEvent *event, void *data);
46
static void willResizeColorWell();
50
W_ViewDelegate _ColorWellViewDelegate = {
59
static WMArray* dropDataTypes(WMView *self);
60
static WMDragOperationType wantedDropOperation(WMView *self);
61
static Bool acceptDropOperation(WMView *self, WMDragOperationType operation);
62
static WMData* fetchDragData(WMView *self, char *type);
64
static WMDragSourceProcs _DragSourceProcs = {
75
static WMArray* requiredDataTypes(WMView *self,
76
WMDragOperationType requestedOperation, WMArray *sourceDataTypes);
77
static WMDragOperationType allowedOperation(WMView *self,
78
WMDragOperationType requestedOperation, WMArray *sourceDataTypes);
79
static void performDragOperation(WMView *self, WMArray *dropDatas,
80
WMArray *operationsList, WMPoint* dropLocation);
82
static WMDragDestinationProcs _DragDestinationProcs = {
87
performDragOperation ,
92
#define DEFAULT_WIDTH 60
93
#define DEFAULT_HEIGHT 30
94
#define DEFAULT_BORDER_WIDTH 6
102
colorChangedObserver(void *data, WMNotification *notification)
104
WMColorPanel *panel = (WMColorPanel*)WMGetNotificationObject(notification);
105
WMColorWell *cPtr = (WMColorWell*)data;
108
if (!cPtr->flags.active)
111
color = WMGetColorPanelColor(panel);
113
WMSetColorWellColor(cPtr, color);
114
WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
119
updateColorCallback(void *self, void *data)
121
WMColorPanel *panel = (WMColorPanel*)self;
122
WMColorWell *cPtr = (ColorWell*)data;
125
color = WMGetColorPanelColor(panel);
126
WMSetColorWellColor(cPtr, color);
127
WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
133
activatedObserver(void *data, WMNotification *notification)
136
WMColorWell *cPtr = (WMColorWell*)data;
138
if (!cPtr->flags.active || WMGetNotificationObject(notification) == cPtr)
141
W_SetViewBackgroundColor(cPtr->view, WMWidgetScreen(cPtr)->gray);
142
paintColorWell(cPtr);
144
cPtr->flags.active = 0;
153
WMArray *types = WMCreateArray(1);
154
WMAddToArray(types, XDND_COLOR_DATA_TYPE);
160
WMCreateColorWell(WMWidget *parent)
164
cPtr = wmalloc(sizeof(ColorWell));
165
memset(cPtr, 0, sizeof(ColorWell));
167
cPtr->widgetClass = WC_ColorWell;
169
cPtr->view = W_CreateView(W_VIEW(parent));
174
cPtr->view->self = cPtr;
176
cPtr->view->delegate = &_ColorWellViewDelegate;
178
cPtr->colorView = W_CreateView(cPtr->view);
179
if (!cPtr->colorView) {
180
W_DestroyView(cPtr->view);
184
cPtr->colorView->self = cPtr;
186
WMCreateEventHandler(cPtr->view, ExposureMask|StructureNotifyMask
187
|ClientMessageMask, handleEvents, cPtr);
189
WMCreateEventHandler(cPtr->colorView, ExposureMask, handleEvents, cPtr);
191
WMCreateDragHandler(cPtr->colorView, handleDragEvents, cPtr);
193
WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents,
196
cPtr->colorView->flags.mapWhenRealized = 1;
198
cPtr->flags.bordered = 1;
200
W_ResizeView(cPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
202
WMAddNotificationObserver(activatedObserver, cPtr,
203
_ColorWellActivatedNotification, NULL);
205
cPtr->color = WMBlackColor(WMWidgetScreen(cPtr));
207
WMAddNotificationObserver(colorChangedObserver, cPtr,
208
WMColorPanelColorChangedNotification, NULL);
210
WMSetViewDragSourceProcs(cPtr->colorView, &_DragSourceProcs);
211
WMSetViewDragDestinationProcs(cPtr->colorView, &_DragDestinationProcs);
213
cPtr->xdndTypes = getXdndTypeArray();
214
WMRegisterViewForDraggedTypes(cPtr->colorView, cPtr->xdndTypes);
221
WMSetColorWellColor(WMColorWell *cPtr, WMColor *color)
224
WMReleaseColor(cPtr->color);
226
cPtr->color = WMRetainColor(color);
228
if (cPtr->colorView->flags.realized && cPtr->colorView->flags.mapped)
229
paintColorWell(cPtr);
234
WMGetColorWellColor(WMColorWell *cPtr)
241
WSetColorWellBordered(WMColorWell *cPtr, Bool flag)
243
flag = ((flag==0) ? 0 : 1);
244
if (cPtr->flags.bordered != flag) {
245
cPtr->flags.bordered = flag;
246
W_ResizeView(cPtr->view, cPtr->view->size.width, cPtr->view->size.height);
252
willResizeColorWell(W_ViewDelegate *self, WMView *view,
253
unsigned int *width, unsigned int *height)
255
WMColorWell *cPtr = (WMColorWell*)view->self;
258
if (cPtr->flags.bordered) {
260
if (*width < MIN_WIDTH)
262
if (*height < MIN_HEIGHT)
263
*height = MIN_HEIGHT;
265
bw = (int)((float)WMIN(*width, *height)*0.24);
267
W_ResizeView(cPtr->colorView, *width-2*bw, *height-2*bw);
269
if (cPtr->colorView->pos.x!=bw || cPtr->colorView->pos.y!=bw)
270
W_MoveView(cPtr->colorView, bw, bw);
272
W_ResizeView(cPtr->colorView, *width, *height);
274
W_MoveView(cPtr->colorView, 0, 0);
280
paintColorWell(ColorWell *cPtr)
282
W_Screen *scr = cPtr->view->screen;
284
W_DrawRelief(scr, cPtr->view->window, 0, 0, cPtr->view->size.width,
285
cPtr->view->size.height, WRRaised);
287
W_DrawRelief(scr, cPtr->colorView->window, 0, 0,
288
cPtr->colorView->size.width, cPtr->colorView->size.height,
292
WMPaintColorSwatch(cPtr->color, cPtr->colorView->window,
293
2, 2, cPtr->colorView->size.width-4,
294
cPtr->colorView->size.height-4);
300
handleEvents(XEvent *event, void *data)
302
ColorWell *cPtr = (ColorWell*)data;
304
CHECK_CLASS(data, WC_ColorWell);
307
switch (event->type) {
309
if (event->xexpose.count!=0)
311
paintColorWell(cPtr);
315
destroyColorWell(cPtr);
323
dropDataTypes(WMView *self)
325
return ((ColorWell*)self->self)->xdndTypes;
329
static WMDragOperationType
330
wantedDropOperation(WMView *self)
332
return WDOperationCopy;
337
acceptDropOperation(WMView *self, WMDragOperationType operation)
339
return (operation == WDOperationCopy);
344
fetchDragData(WMView *self, char *type)
346
char *color = WMGetColorRGBDescription(((WMColorWell*)self->self)->color);
349
data = WMCreateDataWithBytes(color, strlen(color)+1);
357
makeDragPixmap(WMColorWell *cPtr)
359
WMScreen *scr = cPtr->view->screen;
362
pix = XCreatePixmap(scr->display, W_DRAWABLE(scr), 16, 16, scr->depth);
364
XFillRectangle(scr->display, pix, WMColorGC(cPtr->color), 0, 0, 15, 15);
366
XDrawRectangle(scr->display, pix, WMColorGC(scr->black), 0, 0, 15, 15);
368
return WMCreatePixmapFromXPixmaps(scr, pix, None, 16, 16, scr->depth);
373
handleDragEvents(XEvent *event, void *data)
375
WMColorWell *cPtr = (ColorWell*)data;
377
if (event->type == ButtonPress && event->xbutton.button == Button1) {
378
/* initialise drag icon */
379
WMSetViewDragImage(cPtr->colorView, makeDragPixmap(cPtr));
382
WMDragImageFromView(cPtr->colorView, event);
387
handleActionEvents(XEvent *event, void *data)
389
WMColorWell *cPtr = (ColorWell*)data;
390
WMScreen *scr = WMWidgetScreen(cPtr);
391
WMColorPanel *cpanel;
393
if (cPtr->flags.active)
394
W_SetViewBackgroundColor(cPtr->view, scr->gray);
396
W_SetViewBackgroundColor(cPtr->view, scr->white);
397
paintColorWell(cPtr);
399
cPtr->flags.active ^= 1;
401
if (cPtr->flags.active) {
402
WMPostNotificationName(_ColorWellActivatedNotification, cPtr, NULL);
404
cpanel = WMGetColorPanel(scr);
406
WMSetColorPanelAction(cpanel, updateColorCallback, cPtr);
409
WMSetColorPanelColor(cpanel, cPtr->color);
410
WMShowColorPanel(cpanel);
415
destroyColorWell(ColorWell *cPtr)
417
WMRemoveNotificationObserver(cPtr);
420
WMReleaseColor(cPtr->color);
422
WMFreeArray(cPtr->xdndTypes);
429
dropIsOk(WMDragOperationType request, WMArray *sourceDataTypes)
431
WMArrayIterator iter;
434
if (request == WDOperationCopy) {
435
WM_ITERATE_ARRAY(sourceDataTypes, type, iter) {
436
if (type != NULL && strcmp(type, XDND_COLOR_DATA_TYPE)==0) {
447
requiredDataTypes(WMView *self, WMDragOperationType request, WMArray *sourceDataTypes)
449
if (dropIsOk(request, sourceDataTypes))
450
return ((ColorWell*)self->self)->xdndTypes;
456
static WMDragOperationType
457
allowedOperation(WMView *self, WMDragOperationType request, WMArray *sourceDataTypes)
459
if (dropIsOk(request, sourceDataTypes))
460
return WDOperationCopy;
462
return WDOperationNone;
467
performDragOperation(WMView *self, WMArray *dropData, WMArray *operations,
468
WMPoint* dropLocation)
474
/* only one operation requested (WDOperationCopy) implies only one data */
475
data = (WMData*)WMGetFromArray(dropData, 0);
478
colorName = (char*)WMDataBytes(data);
479
color = WMCreateNamedColor(W_VIEW_SCREEN(self), colorName, True);
480
WMSetColorWellColor(self->self, color);
481
WMReleaseColor(color);