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 resizeColorWell();
47 W_ViewProcedureTable _ColorWellViewProcedures
= {
55 static WMDragSourceProcs dragProcs
= {
60 #define DEFAULT_WIDTH 60
61 #define DEFAULT_HEIGHT 30
62 #define DEFAULT_BORDER_WIDTH 6
70 colorChangedObserver(void *data
, WMNotification
*notification
)
73 WMColorPanel *panel = (WMColorPanel*)WMGetNotificationObject(notification);
74 WMColorWell *cPtr = (WMColorWell*)data;
77 if (!cPtr->flags.active)
80 color = WMGetColorPanelColor(panel);
82 WMSetColorWellColor(cPtr, color);*/
88 updateColorCallback(void *self
, void *data
)
91 WMColorPanel *panel = (WMColorPanel*)self;
92 WMColorWell *cPtr = (ColorWell*)data;
95 color = WMGetColorPanelColor(panel);
96 WMSetColorWellColor(cPtr, color);*/
102 activatedObserver(void *data
, WMNotification
*notification
)
105 WMColorWell *cPtr = (WMColorWell*)data;
107 if (!cPtr->flags.active || WMGetNotificationObject(notification) == cPtr)
110 W_SetViewBackgroundColor(cPtr->view, WMWidgetScreen(cPtr)->gray);
111 paintColorWell(cPtr);
113 cPtr->flags.active = 0;
120 WMCreateColorWell(WMWidget
*parent
)
124 cPtr
= wmalloc(sizeof(ColorWell
));
125 memset(cPtr
, 0, sizeof(ColorWell
));
127 cPtr
->widgetClass
= WC_ColorWell
;
129 cPtr
->view
= W_CreateView(W_VIEW(parent
));
134 cPtr
->view
->self
= cPtr
;
136 cPtr
->colorView
= W_CreateView(cPtr
->view
);
137 if (!cPtr
->colorView
) {
138 W_DestroyView(cPtr
->view
);
142 cPtr
->colorView
->self
= cPtr
;
144 WMCreateEventHandler(cPtr
->view
, ExposureMask
|StructureNotifyMask
145 |ClientMessageMask
, handleEvents
, cPtr
);
147 WMCreateEventHandler(cPtr
->colorView
, ExposureMask
, handleEvents
, cPtr
);
149 WMCreateEventHandler(cPtr
->colorView
, ButtonPressMask
|ButtonMotionMask
150 |EnterWindowMask
, handleDragEvents
, cPtr
);
152 WMCreateEventHandler(cPtr
->view
, ButtonPressMask
, handleActionEvents
,
155 cPtr
->colorView
->flags
.mapWhenRealized
= 1;
157 cPtr
->flags
.bordered
= 1;
159 resizeColorWell(cPtr
, DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
161 WMAddNotificationObserver(activatedObserver
, cPtr
,
162 _ColorWellActivatedNotification
, NULL
);
164 cPtr
->color
= WMBlackColor(WMWidgetScreen(cPtr
));
166 WMAddNotificationObserver(colorChangedObserver
, cPtr
,
167 WMColorPanelColorChangedNotification
, NULL
);
174 WMSetColorWellColor(WMColorWell
*cPtr
, WMColor
*color
)
177 WMReleaseColor(cPtr
->color
);
179 cPtr
->color
= WMRetainColor(color
);
181 if (cPtr
->colorView
->flags
.realized
&& cPtr
->colorView
->flags
.mapped
)
182 paintColorWell(cPtr
);
187 WMGetColorWellColor(WMColorWell
*cPtr
)
194 WSetColorWellBordered(WMColorWell
*cPtr
, Bool flag
)
196 if (cPtr
->flags
.bordered
!= flag
) {
197 cPtr
->flags
.bordered
= flag
;
198 resizeColorWell(cPtr
, cPtr
->view
->size
.width
, cPtr
->view
->size
.height
);
203 #define MIN(a,b) ((a) > (b) ? (b) : (a))
206 resizeColorWell(WMColorWell
*cPtr
, unsigned int width
, unsigned int height
)
210 if (cPtr
->flags
.bordered
) {
212 if (width
< MIN_WIDTH
)
214 if (height
< MIN_HEIGHT
)
217 bw
= (int)((float)MIN(width
, height
)*0.24);
219 W_ResizeView(cPtr
->view
, width
, height
);
221 W_ResizeView(cPtr
->colorView
, width
-2*bw
, height
-2*bw
);
223 if (cPtr
->colorView
->pos
.x
!=bw
|| cPtr
->colorView
->pos
.y
!=bw
)
224 W_MoveView(cPtr
->colorView
, bw
, bw
);
226 W_ResizeView(cPtr
->view
, width
, height
);
228 W_ResizeView(cPtr
->colorView
, width
, height
);
230 W_MoveView(cPtr
->colorView
, 0, 0);
236 paintColorWell(ColorWell
*cPtr
)
238 W_Screen
*scr
= cPtr
->view
->screen
;
240 W_DrawRelief(scr
, cPtr
->view
->window
, 0, 0, cPtr
->view
->size
.width
,
241 cPtr
->view
->size
.height
, WRRaised
);
243 W_DrawRelief(scr
, cPtr
->colorView
->window
, 0, 0,
244 cPtr
->colorView
->size
.width
, cPtr
->colorView
->size
.height
,
248 WMPaintColorSwatch(cPtr
->color
, cPtr
->colorView
->window
,
249 2, 2, cPtr
->colorView
->size
.width
-4,
250 cPtr
->colorView
->size
.height
-4);
256 handleEvents(XEvent
*event
, void *data
)
258 ColorWell
*cPtr
= (ColorWell
*)data
;
260 CHECK_CLASS(data
, WC_ColorWell
);
263 switch (event
->type
) {
265 if (event
->xexpose
.count
!=0)
267 paintColorWell(cPtr
);
271 destroyColorWell(cPtr
);
279 makeDragPixmap(WMColorWell
*cPtr
)
281 WMScreen
*scr
= cPtr
->view
->screen
;
284 pix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), 16, 16, scr
->depth
);
286 XFillRectangle(scr
->display
, pix
, WMColorGC(cPtr
->color
), 0, 0, 15, 15);
288 XDrawRectangle(scr
->display
, pix
, WMColorGC(scr
->black
), 0, 0, 15, 15);
290 return WMCreatePixmapFromXPixmaps(scr
, pix
, None
, 16, 16, scr
->depth
);
295 slideView(WMView
*view
, int srcX
, int srcY
, int dstX
, int dstY
)
308 dx
= (double)(dstX
-srcX
)/20.0;
309 dy
= (double)(dstY
-srcY
)/20.0;
311 for (i
= 0; i
< 20; i
++) {
312 W_MoveView(view
, x
, y
);
313 XFlush(view
->screen
->display
);
322 dragColor(ColorWell
*cPtr
, XEvent
*event
, WMPixmap
*image
)
325 WMScreen
*scr
= cPtr
->view
->screen
;
326 Display
*dpy
= scr
->display
;
327 XColor black
= {0, 0,0,0, DoRed
|DoGreen
|DoBlue
};
328 XColor green
= {0x0045b045, 0x4500,0xb000,0x4500, DoRed
|DoGreen
|DoBlue
};
329 XColor back
= {0, 0xffff,0xffff,0xffff, DoRed
|DoGreen
|DoBlue
};
331 WMColorWell
*activeWell
= NULL
;
333 dragView
= W_CreateTopView(scr
);
335 W_ResizeView(dragView
, 16, 16);
336 dragView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
337 dragView
->attribs
.event_mask
= StructureNotifyMask
;
338 dragView
->attribs
.override_redirect
= True
;
339 dragView
->attribs
.save_under
= True
;
341 W_MoveView(dragView
, event
->xmotion
.x_root
-8, event
->xmotion
.y_root
-8);
343 W_RealizeView(dragView
);
347 XSetWindowBackgroundPixmap(dpy
, dragView
->window
, WMGetPixmapXID(image
));
348 XClearWindow(dpy
, dragView
->window
);
351 XGrabPointer(dpy
, dragView
->window
, True
,
352 ButtonMotionMask
|ButtonReleaseMask
|EnterWindowMask
,
353 GrabModeSync
, GrabModeAsync
,
354 scr
->rootWin
, scr
->defaultCursor
, CurrentTime
);
360 XAllowEvents(dpy
, SyncPointer
, CurrentTime
);
361 WMNextEvent(dpy
, &ev
);
365 if (activeWell
!= NULL
) {
366 WMSetColorWellColor(activeWell
, cPtr
->color
);
367 WMPostNotificationName(WMColorWellDidChangeNotification
,
370 slideView(dragView
, ev
.xbutton
.x_root
, ev
.xbutton
.y_root
,
371 event
->xmotion
.x_root
, event
->xmotion
.y_root
);
378 view
= W_GetViewForXWindow(dpy
, ev
.xcrossing
.window
);
380 if (view
&& view
->self
&& W_CLASS(view
->self
) == WC_ColorWell
381 && view
->self
!= activeWell
&& view
->self
!= cPtr
) {
383 activeWell
= view
->self
;
384 XRecolorCursor(dpy
, scr
->defaultCursor
, &green
, &back
);
385 } else if (view
->self
!=NULL
&& view
->self
!= activeWell
) {
386 XRecolorCursor(dpy
, scr
->defaultCursor
, &black
, &back
);
392 W_MoveView(dragView
, ev
.xmotion
.x_root
-8, ev
.xmotion
.y_root
-8);
400 XUngrabPointer(dpy
, CurrentTime
);
401 XRecolorCursor(dpy
, scr
->defaultCursor
, &black
, &back
);
403 W_DestroyView(dragView
);
408 handleDragEvents(XEvent
*event
, void *data
)
410 WMColorWell
*cPtr
= (ColorWell
*)data
;
412 switch (event
->type
) {
414 if (event
->xbutton
.button
== Button1
) {
415 cPtr
->ipoint
.x
= event
->xbutton
.x
;
416 cPtr
->ipoint
.y
= event
->xbutton
.y
;
421 if (event
->xmotion
.state
& Button1Mask
) {
422 if (abs(cPtr
->ipoint
.x
- event
->xmotion
.x
) > 4
423 || abs(cPtr
->ipoint
.y
- event
->xmotion
.y
) > 4) {
429 pixmap
= makeDragPixmap(cPtr
);
432 WMDragImageFromView(cPtr->view, pixmap, cPtr->view->pos,
436 dragColor(cPtr
, event
, pixmap
);
438 WMReleasePixmap(pixmap
);
447 handleActionEvents(XEvent
*event
, void *data
)
449 WMColorWell
*cPtr
= (ColorWell
*)data
;
450 WMScreen
*scr
= WMWidgetScreen(cPtr
);
451 WMColorPanel
*cpanel
;
453 if (cPtr
->flags
.active
)
454 W_SetViewBackgroundColor(cPtr
->view
, scr
->gray
);
456 W_SetViewBackgroundColor(cPtr
->view
, scr
->white
);
457 paintColorWell(cPtr
);
459 cPtr
->flags
.active
^= 1;
461 if (cPtr
->flags
.active
) {
462 WMPostNotificationName(_ColorWellActivatedNotification
, cPtr
, NULL
);
464 cpanel
= WMGetColorPanel(scr
);
466 WMSetColorPanelAction(cpanel
, updateColorCallback
, cPtr
);
469 WMSetColorPanelColor(cpanel
, cPtr
->color
);
470 WMShowColorPanel(cpanel
);
475 destroyColorWell(ColorWell
*cPtr
)
477 WMRemoveNotificationObserver(cPtr
);
480 WMReleaseColor(cPtr
->color
);