Code update for Window Maker version 0.50.0
[wmaker-crm.git] / WINGs / wcolorwell.c
blob728f29ea11132346d2b4062c5b31a7911e851728
5 #include "WINGsP.h"
8 typedef struct W_ColorWell {
9 W_Class widgetClass;
10 WMView *view;
12 WMView *colorView;
14 WMColor *color;
16 WMAction *action;
17 void *clientData;
19 WMPoint ipoint;
21 struct {
22 unsigned int active:1;
23 unsigned int bordered:1;
24 } flags;
25 } ColorWell;
28 static void destroyColorWell(ColorWell *cPtr);
29 static void paintColorWell(ColorWell *cPtr);
31 static void handleEvents(XEvent *event, void *data);
33 static void handleDragEvents(XEvent *event, void *data);
35 static void handleActionEvents(XEvent *event, void *data);
37 static void resizeColorWell();
39 W_ViewProcedureTable _ColorWellViewProcedures = {
40 NULL,
41 resizeColorWell,
42 NULL
46 #if 0
47 static WMDragSourceProcs dragProcs = {
50 #endif
52 #define DEFAULT_WIDTH 60
53 #define DEFAULT_HEIGHT 30
54 #define DEFAULT_BORDER_WIDTH 6
56 #define MIN_WIDTH 16
57 #define MIN_HEIGHT 8
61 WMColorWell*
62 WMCreateColorWell(WMWidget *parent)
64 ColorWell *cPtr;
66 cPtr = wmalloc(sizeof(ColorWell));
67 memset(cPtr, 0, sizeof(ColorWell));
69 cPtr->widgetClass = WC_ColorWell;
71 cPtr->view = W_CreateView(W_VIEW(parent));
72 if (!cPtr->view) {
73 free(cPtr);
74 return NULL;
76 cPtr->view->self = cPtr;
78 cPtr->colorView = W_CreateView(cPtr->view);
79 if (!cPtr->colorView) {
80 W_DestroyView(cPtr->view);
81 free(cPtr);
82 return NULL;
84 cPtr->colorView->self = cPtr;
86 WMCreateEventHandler(cPtr->view, ExposureMask|StructureNotifyMask
87 |ClientMessageMask, handleEvents, cPtr);
89 WMCreateEventHandler(cPtr->colorView, ExposureMask, handleEvents, cPtr);
91 WMCreateEventHandler(cPtr->colorView, ButtonPressMask|ButtonMotionMask
92 |EnterWindowMask, handleDragEvents, cPtr);
94 WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents,
95 cPtr);
97 cPtr->colorView->flags.mapWhenRealized = 1;
99 cPtr->flags.bordered = 1;
101 resizeColorWell(cPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
103 return cPtr;
107 void
108 WMSetColorWellColor(WMColorWell *cPtr, WMColor *color)
110 if (cPtr->color)
111 WMReleaseColor(cPtr->color);
113 cPtr->color = WMRetainColor(color);
115 if (cPtr->colorView->flags.realized && cPtr->colorView->flags.mapped)
116 paintColorWell(cPtr);
120 WMColor*
121 WMGetColorWellColor(WMColorWell *cPtr)
123 return cPtr->color;
127 void
128 WSetColorWellBordered(WMColorWell *cPtr, Bool flag)
130 if (cPtr->flags.bordered != flag) {
131 cPtr->flags.bordered = flag;
132 resizeColorWell(cPtr, cPtr->view->size.width, cPtr->view->size.height);
137 #define MIN(a,b) ((a) > (b) ? (b) : (a))
139 static void
140 resizeColorWell(WMColorWell *cPtr, unsigned int width, unsigned int height)
142 int bw;
144 if (cPtr->flags.bordered) {
146 if (width < MIN_WIDTH)
147 width = MIN_WIDTH;
148 if (height < MIN_HEIGHT)
149 height = MIN_HEIGHT;
151 bw = (int)((float)MIN(width, height)*0.24);
153 W_ResizeView(cPtr->view, width, height);
155 W_ResizeView(cPtr->colorView, width-2*bw, height-2*bw);
157 if (cPtr->colorView->pos.x!=bw || cPtr->colorView->pos.y!=bw)
158 W_MoveView(cPtr->colorView, bw, bw);
159 } else {
160 W_ResizeView(cPtr->view, width, height);
162 W_ResizeView(cPtr->colorView, width, height);
164 W_MoveView(cPtr->colorView, 0, 0);
169 static void
170 paintColorWell(ColorWell *cPtr)
172 W_Screen *scr = cPtr->view->screen;
174 W_DrawRelief(scr, cPtr->view->window, 0, 0, cPtr->view->size.width,
175 cPtr->view->size.height, WRRaised);
177 W_DrawRelief(scr, cPtr->colorView->window, 0, 0,
178 cPtr->colorView->size.width, cPtr->colorView->size.height,
179 WRSunken);
181 if (cPtr->color)
182 WMPaintColorSwatch(cPtr->color, cPtr->colorView->window,
183 2, 2, cPtr->colorView->size.width-4,
184 cPtr->colorView->size.height-4);
189 static void
190 handleEvents(XEvent *event, void *data)
192 ColorWell *cPtr = (ColorWell*)data;
194 CHECK_CLASS(data, WC_ColorWell);
197 switch (event->type) {
198 case Expose:
199 if (event->xexpose.count!=0)
200 break;
201 paintColorWell(cPtr);
202 break;
204 case DestroyNotify:
205 destroyColorWell(cPtr);
206 break;
212 static WMPixmap*
213 makeDragPixmap(WMColorWell *cPtr)
215 WMScreen *scr = cPtr->view->screen;
216 Pixmap pix;
218 pix = XCreatePixmap(scr->display, W_DRAWABLE(scr), 16, 16, scr->depth);
220 XFillRectangle(scr->display, pix, WMColorGC(cPtr->color), 0, 0, 15, 15);
222 XDrawRectangle(scr->display, pix, WMColorGC(scr->black), 0, 0, 15, 15);
224 return WMCreatePixmapFromXPixmaps(scr, pix, None, 16, 16, scr->depth);
228 static void
229 slideView(WMView *view, int srcX, int srcY, int dstX, int dstY)
231 double x, y, dx, dy;
232 int i;
234 srcX -= 8;
235 srcY -= 8;
236 dstX -= 8;
237 dstY -= 8;
239 x = srcX;
240 y = srcY;
242 dx = (double)(dstX-srcX)/20.0;
243 dy = (double)(dstY-srcY)/20.0;
245 for (i = 0; i < 20; i++) {
246 W_MoveView(view, x, y);
247 XFlush(view->screen->display);
249 x += dx;
250 y += dy;
255 static void
256 dragColor(ColorWell *cPtr, XEvent *event, WMPixmap *image)
258 WMView *dragView;
259 WMScreen *scr = cPtr->view->screen;
260 Display *dpy = scr->display;
261 XColor black = {0, 0,0,0, DoRed|DoGreen|DoBlue};
262 XColor green = {0, 0x4500,0xb000,0x4500, DoRed|DoGreen|DoBlue};
263 XColor back = {0, 0xffff,0xffff,0xffff, DoRed|DoGreen|DoBlue};
264 Bool done = False;
265 WMColorWell *activeWell = NULL;
267 dragView = W_CreateTopView(scr);
269 W_ResizeView(dragView, 16, 16);
270 dragView->attribFlags |= CWOverrideRedirect | CWSaveUnder;
271 dragView->attribs.event_mask = StructureNotifyMask;
272 dragView->attribs.override_redirect = True;
273 dragView->attribs.save_under = True;
275 W_MoveView(dragView, event->xmotion.x_root-8, event->xmotion.y_root-8);
277 W_RealizeView(dragView);
279 W_MapView(dragView);
281 XSetWindowBackgroundPixmap(dpy, dragView->window, WMGetPixmapXID(image));
282 XClearWindow(dpy, dragView->window);
285 XGrabPointer(dpy, dragView->window, True,
286 ButtonMotionMask|ButtonReleaseMask|EnterWindowMask,
287 GrabModeSync, GrabModeAsync,
288 scr->rootWin, scr->defaultCursor, CurrentTime);
290 while (!done) {
291 XEvent ev;
292 WMView *view;
294 XAllowEvents(dpy, SyncPointer, CurrentTime);
295 WMNextEvent(dpy, &ev);
297 switch (ev.type) {
298 case ButtonRelease:
299 if (activeWell != NULL) {
300 WMSetColorWellColor(activeWell, cPtr->color);
301 } else {
302 slideView(dragView, ev.xbutton.x_root, ev.xbutton.y_root,
303 event->xmotion.x_root, event->xmotion.y_root);
306 done = True;
307 break;
309 case EnterNotify:
310 view = W_GetViewForXWindow(dpy, ev.xcrossing.window);
312 if (view && view->self && W_CLASS(view->self) == WC_ColorWell
313 && view->self != activeWell && view->self != cPtr) {
315 activeWell = view->self;
316 XRecolorCursor(dpy, scr->defaultCursor, &green, &back);
317 } else if (view->self!=NULL && view->self != activeWell) {
318 XRecolorCursor(dpy, scr->defaultCursor, &black, &back);
319 activeWell = NULL;
321 break;
323 case MotionNotify:
324 W_MoveView(dragView, ev.xmotion.x_root-8, ev.xmotion.y_root-8);
325 break;
327 default:
328 WMHandleEvent(&ev);
329 break;
332 XUngrabPointer(dpy, CurrentTime);
333 XRecolorCursor(dpy, scr->defaultCursor, &black, &back);
335 W_DestroyView(dragView);
339 static void
340 handleDragEvents(XEvent *event, void *data)
342 WMColorWell *cPtr = (ColorWell*)data;
344 switch (event->type) {
345 case ButtonPress:
346 if (event->xbutton.button == Button1) {
347 cPtr->ipoint.x = event->xbutton.x;
348 cPtr->ipoint.y = event->xbutton.y;
350 break;
352 case MotionNotify:
353 if (event->xmotion.state & Button1Mask) {
354 if (abs(cPtr->ipoint.x - event->xmotion.x) > 4
355 || abs(cPtr->ipoint.y - event->xmotion.y) > 4) {
356 WMSize offs;
357 WMPixmap *pixmap;
359 offs.width = 2;
360 offs.height = 2;
361 pixmap = makeDragPixmap(cPtr);
364 WMDragImageFromView(cPtr->view, pixmap, cPtr->view->pos,
365 offs, event, True);
366 * */
368 dragColor(cPtr, event, pixmap);
370 WMReleasePixmap(pixmap);
373 break;
379 static void
380 handleActionEvents(XEvent *event, void *data)
382 /* WMColorWell *cPtr = (ColorWell*)data;*/
387 static void
388 destroyColorWell(ColorWell *cPtr)
390 if (cPtr->color)
391 WMReleaseColor(cPtr->color);
393 free(cPtr);