8 char *WMColorWellDidChangeNotification
= "WMColorWellDidChangeNotification";
11 typedef struct W_ColorWell
{
25 unsigned int active
:1;
26 unsigned int bordered
:1;
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
= {
56 static unsigned draggingSourceOperation(WMView
*self
, Bool local
);
58 static WMData
* fetchDragData(WMView
*self
, char *type
);
60 static WMDragSourceProcs _DragSourceProcs
= {
61 draggingSourceOperation
,
68 static unsigned draggingEntered(WMView
*self
, WMDraggingInfo
*info
);
69 static unsigned draggingUpdated(WMView
*self
, WMDraggingInfo
*info
);
70 static void draggingExited(WMView
*self
, WMDraggingInfo
*info
);
71 static char *prepareForDragOperation(WMView
*self
, WMDraggingInfo
*info
);
72 static Bool
performDragOperation(WMView
*self
, WMDraggingInfo
*info
,
74 static void concludeDragOperation(WMView
*self
, WMDraggingInfo
*info
);
76 static WMDragDestinationProcs _DragDestinationProcs
= {
80 prepareForDragOperation
,
86 #define DEFAULT_WIDTH 60
87 #define DEFAULT_HEIGHT 30
88 #define DEFAULT_BORDER_WIDTH 6
96 colorChangedObserver(void *data
, WMNotification
*notification
)
98 WMColorPanel
*panel
= (WMColorPanel
*)WMGetNotificationObject(notification
);
99 WMColorWell
*cPtr
= (WMColorWell
*)data
;
102 if (!cPtr
->flags
.active
)
105 color
= WMGetColorPanelColor(panel
);
107 WMSetColorWellColor(cPtr
, color
);
108 WMPostNotificationName(WMColorWellDidChangeNotification
, cPtr
, NULL
);
113 updateColorCallback(void *self
, void *data
)
115 WMColorPanel
*panel
= (WMColorPanel
*)self
;
116 WMColorWell
*cPtr
= (ColorWell
*)data
;
119 color
= WMGetColorPanelColor(panel
);
120 WMSetColorWellColor(cPtr
, color
);
121 WMPostNotificationName(WMColorWellDidChangeNotification
, cPtr
, NULL
);
127 activatedObserver(void *data
, WMNotification
*notification
)
130 WMColorWell *cPtr = (WMColorWell*)data;
132 if (!cPtr->flags.active || WMGetNotificationObject(notification) == cPtr)
135 W_SetViewBackgroundColor(cPtr->view, WMWidgetScreen(cPtr)->gray);
136 paintColorWell(cPtr);
138 cPtr->flags.active = 0;
145 WMCreateColorWell(WMWidget
*parent
)
149 cPtr
= wmalloc(sizeof(ColorWell
));
150 memset(cPtr
, 0, sizeof(ColorWell
));
152 cPtr
->widgetClass
= WC_ColorWell
;
154 cPtr
->view
= W_CreateView(W_VIEW(parent
));
159 cPtr
->view
->self
= cPtr
;
161 cPtr
->view
->delegate
= &_ColorWellViewDelegate
;
163 cPtr
->colorView
= W_CreateView(cPtr
->view
);
164 if (!cPtr
->colorView
) {
165 W_DestroyView(cPtr
->view
);
169 cPtr
->colorView
->self
= cPtr
;
171 WMCreateEventHandler(cPtr
->view
, ExposureMask
|StructureNotifyMask
172 |ClientMessageMask
, handleEvents
, cPtr
);
174 WMCreateEventHandler(cPtr
->colorView
, ExposureMask
, handleEvents
, cPtr
);
176 WMCreateEventHandler(cPtr
->colorView
, ButtonPressMask
|ButtonMotionMask
177 |EnterWindowMask
, handleDragEvents
, cPtr
);
179 WMCreateEventHandler(cPtr
->view
, ButtonPressMask
, handleActionEvents
,
182 cPtr
->colorView
->flags
.mapWhenRealized
= 1;
184 cPtr
->flags
.bordered
= 1;
186 W_ResizeView(cPtr
->view
, DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
188 WMAddNotificationObserver(activatedObserver
, cPtr
,
189 _ColorWellActivatedNotification
, NULL
);
191 cPtr
->color
= WMBlackColor(WMWidgetScreen(cPtr
));
193 WMAddNotificationObserver(colorChangedObserver
, cPtr
,
194 WMColorPanelColorChangedNotification
, NULL
);
196 WMSetViewDragSourceProcs(cPtr
->view
, &_DragSourceProcs
);
197 WMSetViewDragDestinationProcs(cPtr
->view
, &_DragDestinationProcs
);
200 char *types
[2] = {"application/X-color", NULL
};
202 WMRegisterViewForDraggedTypes(cPtr
->view
, types
);
210 WMSetColorWellColor(WMColorWell
*cPtr
, WMColor
*color
)
213 WMReleaseColor(cPtr
->color
);
215 cPtr
->color
= WMRetainColor(color
);
217 if (cPtr
->colorView
->flags
.realized
&& cPtr
->colorView
->flags
.mapped
)
218 paintColorWell(cPtr
);
223 WMGetColorWellColor(WMColorWell
*cPtr
)
230 WSetColorWellBordered(WMColorWell
*cPtr
, Bool flag
)
232 if (cPtr
->flags
.bordered
!= flag
) {
233 cPtr
->flags
.bordered
= flag
;
234 W_ResizeView(cPtr
->view
, cPtr
->view
->size
.width
, cPtr
->view
->size
.height
);
239 #define MIN(a,b) ((a) > (b) ? (b) : (a))
242 willResizeColorWell(W_ViewDelegate
*self
, WMView
*view
,
243 unsigned int *width
, unsigned int *height
)
245 WMColorWell
*cPtr
= (WMColorWell
*)view
->self
;
248 if (cPtr
->flags
.bordered
) {
250 if (*width
< MIN_WIDTH
)
252 if (*height
< MIN_HEIGHT
)
253 *height
= MIN_HEIGHT
;
255 bw
= (int)((float)MIN(*width
, *height
)*0.24);
257 W_ResizeView(cPtr
->colorView
, *width
-2*bw
, *height
-2*bw
);
259 if (cPtr
->colorView
->pos
.x
!=bw
|| cPtr
->colorView
->pos
.y
!=bw
)
260 W_MoveView(cPtr
->colorView
, bw
, bw
);
262 W_ResizeView(cPtr
->colorView
, *width
, *height
);
264 W_MoveView(cPtr
->colorView
, 0, 0);
270 paintColorWell(ColorWell
*cPtr
)
272 W_Screen
*scr
= cPtr
->view
->screen
;
274 W_DrawRelief(scr
, cPtr
->view
->window
, 0, 0, cPtr
->view
->size
.width
,
275 cPtr
->view
->size
.height
, WRRaised
);
277 W_DrawRelief(scr
, cPtr
->colorView
->window
, 0, 0,
278 cPtr
->colorView
->size
.width
, cPtr
->colorView
->size
.height
,
282 WMPaintColorSwatch(cPtr
->color
, cPtr
->colorView
->window
,
283 2, 2, cPtr
->colorView
->size
.width
-4,
284 cPtr
->colorView
->size
.height
-4);
290 handleEvents(XEvent
*event
, void *data
)
292 ColorWell
*cPtr
= (ColorWell
*)data
;
294 CHECK_CLASS(data
, WC_ColorWell
);
297 switch (event
->type
) {
299 if (event
->xexpose
.count
!=0)
301 paintColorWell(cPtr
);
305 destroyColorWell(cPtr
);
313 draggingSourceOperation(WMView
*self
, Bool local
)
315 return WDOperationCopy
;
320 fetchDragData(WMView
*self
, char *type
)
322 char *color
= WMGetColorRGBDescription(((WMColorWell
*)self
->self
)->color
);
325 data
= WMCreateDataWithBytes(color
, strlen(color
)+1);
334 makeDragPixmap(WMColorWell
*cPtr
)
336 WMScreen
*scr
= cPtr
->view
->screen
;
339 pix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), 16, 16, scr
->depth
);
341 XFillRectangle(scr
->display
, pix
, WMColorGC(cPtr
->color
), 0, 0, 15, 15);
343 XDrawRectangle(scr
->display
, pix
, WMColorGC(scr
->black
), 0, 0, 15, 15);
345 return WMCreatePixmapFromXPixmaps(scr
, pix
, None
, 16, 16, scr
->depth
);
350 handleDragEvents(XEvent
*event
, void *data
)
352 WMColorWell
*cPtr
= (ColorWell
*)data
;
354 switch (event
->type
) {
356 if (event
->xbutton
.button
== Button1
) {
357 cPtr
->ipoint
.x
= event
->xbutton
.x
;
358 cPtr
->ipoint
.y
= event
->xbutton
.y
;
363 if (event
->xmotion
.state
& Button1Mask
) {
364 if (abs(cPtr
->ipoint
.x
- event
->xmotion
.x
) > 4
365 || abs(cPtr
->ipoint
.y
- event
->xmotion
.y
) > 4) {
368 char *types
[2] = {"application/X-color", NULL
};
372 pixmap
= makeDragPixmap(cPtr
);
374 WMDragImageFromView(cPtr
->view
, pixmap
, types
,
375 wmkpoint(event
->xmotion
.x_root
,
376 event
->xmotion
.y_root
),
380 WMReleasePixmap(pixmap
);
389 handleActionEvents(XEvent
*event
, void *data
)
391 WMColorWell
*cPtr
= (ColorWell
*)data
;
392 WMScreen
*scr
= WMWidgetScreen(cPtr
);
393 WMColorPanel
*cpanel
;
395 if (cPtr
->flags
.active
)
396 W_SetViewBackgroundColor(cPtr
->view
, scr
->gray
);
398 W_SetViewBackgroundColor(cPtr
->view
, scr
->white
);
399 paintColorWell(cPtr
);
401 cPtr
->flags
.active
^= 1;
403 if (cPtr
->flags
.active
) {
404 WMPostNotificationName(_ColorWellActivatedNotification
, cPtr
, NULL
);
406 cpanel
= WMGetColorPanel(scr
);
408 WMSetColorPanelAction(cpanel
, updateColorCallback
, cPtr
);
411 WMSetColorPanelColor(cpanel
, cPtr
->color
);
412 WMShowColorPanel(cpanel
);
417 destroyColorWell(ColorWell
*cPtr
)
419 WMRemoveNotificationObserver(cPtr
);
422 WMReleaseColor(cPtr
->color
);
430 draggingEntered(WMView
*self
, WMDraggingInfo
*info
)
432 return WDOperationCopy
;
437 draggingUpdated(WMView
*self
, WMDraggingInfo
*info
)
439 return WDOperationCopy
;
444 draggingExited(WMView
*self
, WMDraggingInfo
*info
)
451 prepareForDragOperation(WMView
*self
, WMDraggingInfo
*info
)
453 return "application/X-color";
458 performDragOperation(WMView
*self
, WMDraggingInfo
*info
, WMData
*data
)
460 char *colorName
= (char*)WMDataBytes(data
);
463 color
= WMCreateNamedColor(W_VIEW_SCREEN(self
), colorName
, True
);
465 WMSetColorWellColor(self
->self
, color
);
467 WMReleaseColor(color
);
474 concludeDragOperation(WMView
*self
, WMDraggingInfo
*info
)