4 #define XDND_COLOR_DATA_TYPE "application/X-color"
6 char *WMColorWellDidChangeNotification
= "WMColorWellDidChangeNotification";
8 typedef struct W_ColorWell
{
22 unsigned int active
:1;
23 unsigned int bordered
:1;
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
= {
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
= {
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
= {
81 #define DEFAULT_WIDTH 60
82 #define DEFAULT_HEIGHT 30
83 #define DEFAULT_BORDER_WIDTH 6
88 static void colorChangedObserver(void *data
, WMNotification
* notification
)
90 WMColorPanel
*panel
= (WMColorPanel
*) WMGetNotificationObject(notification
);
91 WMColorWell
*cPtr
= (WMColorWell
*) data
;
94 if (!cPtr
->flags
.active
)
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
;
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)
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
);
136 WMColorWell
*WMCreateColorWell(WMWidget
* parent
)
140 cPtr
= wmalloc(sizeof(ColorWell
));
142 cPtr
->widgetClass
= WC_ColorWell
;
144 cPtr
->view
= W_CreateView(W_VIEW(parent
));
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
);
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
);
191 void WMSetColorWellColor(WMColorWell
* cPtr
, WMColor
* 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
)
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
;
221 /* Parameter not used, but tell the compiler that it is ok */
224 if (cPtr
->flags
.bordered
) {
226 if (*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
);
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
);
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
) {
266 if (event
->xexpose
.count
!= 0)
268 paintColorWell(cPtr
);
272 destroyColorWell(cPtr
);
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 */
288 return WDOperationCopy
;
291 static Bool
acceptDropOperation(WMView
* self
, WMDragOperationType operation
)
293 /* Parameter not used, but tell the compiler that it is ok */
296 return (operation
== WDOperationCopy
);
299 static WMData
*fetchDragData(WMView
* self
, char *type
)
301 char *color
= WMGetColorRGBDescription(((WMColorWell
*) self
->self
)->color
);
304 /* Parameter not used, but tell the compiler that it is ok */
307 data
= WMCreateDataWithBytes(color
, strlen(color
) + 1);
313 static WMPixmap
*makeDragPixmap(WMColorWell
* cPtr
)
315 WMScreen
*scr
= cPtr
->view
->screen
;
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 */
348 if (cPtr
->flags
.active
)
349 W_SetViewBackgroundColor(cPtr
->view
, scr
->gray
);
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
);
364 WMSetColorPanelColor(cpanel
, cPtr
->color
);
365 WMShowColorPanel(cpanel
);
368 static void destroyColorWell(ColorWell
* cPtr
)
370 WMRemoveNotificationObserver(cPtr
);
373 WMReleaseColor(cPtr
->color
);
375 WMFreeArray(cPtr
->xdndTypes
);
380 static Bool
dropIsOk(WMDragOperationType request
, WMArray
* sourceDataTypes
)
382 WMArrayIterator iter
;
385 if (request
== WDOperationCopy
) {
386 WM_ITERATE_ARRAY(sourceDataTypes
, type
, iter
) {
387 if (type
!= NULL
&& strcmp(type
, XDND_COLOR_DATA_TYPE
) == 0) {
396 static WMArray
*requiredDataTypes(WMView
* self
, WMDragOperationType request
, WMArray
* sourceDataTypes
)
398 if (dropIsOk(request
, sourceDataTypes
))
399 return ((ColorWell
*) self
->self
)->xdndTypes
;
404 static WMDragOperationType
allowedOperation(WMView
* self
, WMDragOperationType request
, WMArray
* sourceDataTypes
)
406 /* Parameter not used, but tell the compiler that it is ok */
409 if (dropIsOk(request
, sourceDataTypes
))
410 return WDOperationCopy
;
412 return WDOperationNone
;
415 static void performDragOperation(WMView
* self
, WMArray
* dropData
, WMArray
* operations
, WMPoint
* dropLocation
)
421 /* Parameter not used, but tell the compiler that it is ok */
425 /* only one operation requested (WDOperationCopy) implies only one data */
426 data
= (WMData
*) WMGetFromArray(dropData
, 0);
429 colorName
= (char *)WMDataBytes(data
);
430 color
= WMCreateNamedColor(W_VIEW_SCREEN(self
), colorName
, True
);
431 WMSetColorWellColor(self
->self
, color
);
432 WMReleaseColor(color
);