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
);