~profzoom/ubuntu/quantal/wmaker/bug-1079925

« back to all changes in this revision

Viewing changes to WINGs/wcolorwell.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2004-11-10 14:05:30 UTC
  • Revision ID: james.westby@ubuntu.com-20041110140530-qpd66b5lm38x7apk
Tags: upstream-0.91.0
ImportĀ upstreamĀ versionĀ 0.91.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
 
 
3
 
 
4
 
 
5
#include "WINGsP.h"
 
6
 
 
7
#define XDND_COLOR_DATA_TYPE "application/X-color"
 
8
 
 
9
char *WMColorWellDidChangeNotification = "WMColorWellDidChangeNotification";
 
10
 
 
11
 
 
12
typedef struct W_ColorWell {
 
13
    W_Class widgetClass;
 
14
    WMView *view;
 
15
 
 
16
    WMView *colorView;
 
17
 
 
18
    WMColor *color;
 
19
 
 
20
    WMAction *action;
 
21
    void *clientData;
 
22
 
 
23
    WMPoint ipoint;
 
24
 
 
25
    struct {
 
26
        unsigned int active:1;
 
27
        unsigned int bordered:1;
 
28
    } flags;
 
29
 
 
30
    WMArray *xdndTypes;
 
31
} ColorWell;
 
32
 
 
33
static char *_ColorWellActivatedNotification = "_ColorWellActivatedNotification";
 
34
 
 
35
 
 
36
 
 
37
static void destroyColorWell(ColorWell *cPtr);
 
38
static void paintColorWell(ColorWell *cPtr);
 
39
 
 
40
static void handleEvents(XEvent *event, void *data);
 
41
 
 
42
static void handleDragEvents(XEvent *event, void *data);
 
43
 
 
44
static void handleActionEvents(XEvent *event, void *data);
 
45
 
 
46
static void willResizeColorWell();
 
47
 
 
48
 
 
49
 
 
50
W_ViewDelegate _ColorWellViewDelegate = {
 
51
    NULL,
 
52
    NULL,
 
53
    NULL,
 
54
    NULL,
 
55
    willResizeColorWell
 
56
};
 
57
 
 
58
 
 
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);
 
63
 
 
64
static WMDragSourceProcs _DragSourceProcs = {
 
65
    dropDataTypes,
 
66
    wantedDropOperation,
 
67
    NULL,
 
68
    acceptDropOperation,
 
69
    NULL,
 
70
    NULL,
 
71
    fetchDragData
 
72
};
 
73
 
 
74
 
 
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);
 
81
 
 
82
static WMDragDestinationProcs _DragDestinationProcs = {
 
83
    NULL,
 
84
    requiredDataTypes,
 
85
    allowedOperation,
 
86
    NULL,
 
87
    performDragOperation ,
 
88
    NULL
 
89
};
 
90
 
 
91
 
 
92
#define DEFAULT_WIDTH           60
 
93
#define DEFAULT_HEIGHT          30
 
94
#define DEFAULT_BORDER_WIDTH    6
 
95
 
 
96
#define MIN_WIDTH       16
 
97
#define MIN_HEIGHT      8
 
98
 
 
99
 
 
100
 
 
101
static void
 
102
colorChangedObserver(void *data, WMNotification *notification)
 
103
{
 
104
    WMColorPanel *panel = (WMColorPanel*)WMGetNotificationObject(notification);
 
105
    WMColorWell *cPtr = (WMColorWell*)data;
 
106
    WMColor *color;
 
107
 
 
108
    if (!cPtr->flags.active)
 
109
        return;
 
110
 
 
111
    color = WMGetColorPanelColor(panel);
 
112
 
 
113
    WMSetColorWellColor(cPtr, color);
 
114
    WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
 
115
}
 
116
 
 
117
 
 
118
static void
 
119
updateColorCallback(void *self, void *data)
 
120
{
 
121
    WMColorPanel *panel = (WMColorPanel*)self;
 
122
    WMColorWell *cPtr = (ColorWell*)data;
 
123
    WMColor *color;
 
124
 
 
125
    color = WMGetColorPanelColor(panel);
 
126
    WMSetColorWellColor(cPtr, color);
 
127
    WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
 
128
}
 
129
 
 
130
 
 
131
 
 
132
static void
 
133
activatedObserver(void *data, WMNotification *notification)
 
134
{
 
135
    /*
 
136
     WMColorWell *cPtr = (WMColorWell*)data;
 
137
 
 
138
     if (!cPtr->flags.active || WMGetNotificationObject(notification) == cPtr)
 
139
     return;
 
140
 
 
141
     W_SetViewBackgroundColor(cPtr->view, WMWidgetScreen(cPtr)->gray);
 
142
     paintColorWell(cPtr);
 
143
 
 
144
     cPtr->flags.active = 0;
 
145
     */
 
146
}
 
147
 
 
148
 
 
149
 
 
150
static WMArray*
 
151
getXdndTypeArray()
 
152
{
 
153
    WMArray *types = WMCreateArray(1);
 
154
    WMAddToArray(types, XDND_COLOR_DATA_TYPE);
 
155
    return types;
 
156
}
 
157
 
 
158
 
 
159
WMColorWell*
 
160
WMCreateColorWell(WMWidget *parent)
 
161
{
 
162
    ColorWell *cPtr;
 
163
 
 
164
    cPtr = wmalloc(sizeof(ColorWell));
 
165
    memset(cPtr, 0, sizeof(ColorWell));
 
166
 
 
167
    cPtr->widgetClass = WC_ColorWell;
 
168
 
 
169
    cPtr->view = W_CreateView(W_VIEW(parent));
 
170
    if (!cPtr->view) {
 
171
        wfree(cPtr);
 
172
        return NULL;
 
173
    }
 
174
    cPtr->view->self = cPtr;
 
175
 
 
176
    cPtr->view->delegate = &_ColorWellViewDelegate;
 
177
 
 
178
    cPtr->colorView = W_CreateView(cPtr->view);
 
179
    if (!cPtr->colorView) {
 
180
        W_DestroyView(cPtr->view);
 
181
        wfree(cPtr);
 
182
        return NULL;
 
183
    }
 
184
    cPtr->colorView->self = cPtr;
 
185
 
 
186
    WMCreateEventHandler(cPtr->view, ExposureMask|StructureNotifyMask
 
187
                         |ClientMessageMask, handleEvents, cPtr);
 
188
 
 
189
    WMCreateEventHandler(cPtr->colorView, ExposureMask, handleEvents, cPtr);
 
190
 
 
191
    WMCreateDragHandler(cPtr->colorView, handleDragEvents, cPtr);
 
192
 
 
193
    WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents,
 
194
                         cPtr);
 
195
 
 
196
    cPtr->colorView->flags.mapWhenRealized = 1;
 
197
 
 
198
    cPtr->flags.bordered = 1;
 
199
 
 
200
    W_ResizeView(cPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
 
201
 
 
202
    WMAddNotificationObserver(activatedObserver, cPtr,
 
203
                              _ColorWellActivatedNotification, NULL);
 
204
 
 
205
    cPtr->color = WMBlackColor(WMWidgetScreen(cPtr));
 
206
 
 
207
    WMAddNotificationObserver(colorChangedObserver, cPtr,
 
208
                              WMColorPanelColorChangedNotification, NULL);
 
209
 
 
210
    WMSetViewDragSourceProcs(cPtr->colorView, &_DragSourceProcs);
 
211
    WMSetViewDragDestinationProcs(cPtr->colorView, &_DragDestinationProcs);
 
212
 
 
213
    cPtr->xdndTypes = getXdndTypeArray();
 
214
    WMRegisterViewForDraggedTypes(cPtr->colorView, cPtr->xdndTypes);
 
215
 
 
216
    return cPtr;
 
217
}
 
218
 
 
219
 
 
220
void
 
221
WMSetColorWellColor(WMColorWell *cPtr, WMColor *color)
 
222
{
 
223
    if (cPtr->color)
 
224
        WMReleaseColor(cPtr->color);
 
225
 
 
226
    cPtr->color = WMRetainColor(color);
 
227
 
 
228
    if (cPtr->colorView->flags.realized && cPtr->colorView->flags.mapped)
 
229
        paintColorWell(cPtr);
 
230
}
 
231
 
 
232
 
 
233
WMColor*
 
234
WMGetColorWellColor(WMColorWell *cPtr)
 
235
{
 
236
    return cPtr->color;
 
237
}
 
238
 
 
239
 
 
240
void
 
241
WSetColorWellBordered(WMColorWell *cPtr, Bool flag)
 
242
{
 
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);
 
247
    }
 
248
}
 
249
 
 
250
 
 
251
static void
 
252
willResizeColorWell(W_ViewDelegate *self, WMView *view,
 
253
                    unsigned int *width, unsigned int *height)
 
254
{
 
255
    WMColorWell *cPtr = (WMColorWell*)view->self;
 
256
    int bw;
 
257
 
 
258
    if (cPtr->flags.bordered) {
 
259
 
 
260
        if (*width < MIN_WIDTH)
 
261
            *width = MIN_WIDTH;
 
262
        if (*height < MIN_HEIGHT)
 
263
            *height = MIN_HEIGHT;
 
264
 
 
265
        bw = (int)((float)WMIN(*width, *height)*0.24);
 
266
 
 
267
        W_ResizeView(cPtr->colorView, *width-2*bw, *height-2*bw);
 
268
 
 
269
        if (cPtr->colorView->pos.x!=bw || cPtr->colorView->pos.y!=bw)
 
270
            W_MoveView(cPtr->colorView, bw, bw);
 
271
    } else {
 
272
        W_ResizeView(cPtr->colorView, *width, *height);
 
273
 
 
274
        W_MoveView(cPtr->colorView, 0, 0);
 
275
    }
 
276
}
 
277
 
 
278
 
 
279
static void
 
280
paintColorWell(ColorWell *cPtr)
 
281
{
 
282
    W_Screen *scr = cPtr->view->screen;
 
283
 
 
284
    W_DrawRelief(scr, cPtr->view->window, 0, 0, cPtr->view->size.width,
 
285
                 cPtr->view->size.height, WRRaised);
 
286
 
 
287
    W_DrawRelief(scr, cPtr->colorView->window, 0, 0,
 
288
                 cPtr->colorView->size.width, cPtr->colorView->size.height,
 
289
                 WRSunken);
 
290
 
 
291
    if (cPtr->color)
 
292
        WMPaintColorSwatch(cPtr->color, cPtr->colorView->window,
 
293
                           2, 2, cPtr->colorView->size.width-4,
 
294
                           cPtr->colorView->size.height-4);
 
295
}
 
296
 
 
297
 
 
298
 
 
299
static void
 
300
handleEvents(XEvent *event, void *data)
 
301
{
 
302
    ColorWell *cPtr = (ColorWell*)data;
 
303
 
 
304
    CHECK_CLASS(data, WC_ColorWell);
 
305
 
 
306
 
 
307
    switch (event->type) {
 
308
    case Expose:
 
309
        if (event->xexpose.count!=0)
 
310
            break;
 
311
        paintColorWell(cPtr);
 
312
        break;
 
313
 
 
314
    case DestroyNotify:
 
315
        destroyColorWell(cPtr);
 
316
        break;
 
317
 
 
318
    }
 
319
}
 
320
 
 
321
 
 
322
static WMArray*
 
323
dropDataTypes(WMView *self)
 
324
{
 
325
    return ((ColorWell*)self->self)->xdndTypes;
 
326
}
 
327
 
 
328
 
 
329
static WMDragOperationType
 
330
wantedDropOperation(WMView *self)
 
331
{
 
332
    return WDOperationCopy;
 
333
}
 
334
 
 
335
 
 
336
static Bool
 
337
acceptDropOperation(WMView *self, WMDragOperationType operation)
 
338
{
 
339
    return (operation == WDOperationCopy);
 
340
}
 
341
 
 
342
 
 
343
static WMData*
 
344
fetchDragData(WMView *self, char *type)
 
345
{
 
346
    char *color = WMGetColorRGBDescription(((WMColorWell*)self->self)->color);
 
347
    WMData *data;
 
348
 
 
349
    data = WMCreateDataWithBytes(color, strlen(color)+1);
 
350
    wfree(color);
 
351
 
 
352
    return data;
 
353
}
 
354
 
 
355
 
 
356
static WMPixmap*
 
357
makeDragPixmap(WMColorWell *cPtr)
 
358
{
 
359
    WMScreen *scr = cPtr->view->screen;
 
360
    Pixmap pix;
 
361
 
 
362
    pix = XCreatePixmap(scr->display, W_DRAWABLE(scr), 16, 16, scr->depth);
 
363
 
 
364
    XFillRectangle(scr->display, pix, WMColorGC(cPtr->color), 0, 0, 15, 15);
 
365
 
 
366
    XDrawRectangle(scr->display, pix, WMColorGC(scr->black), 0, 0, 15, 15);
 
367
 
 
368
    return WMCreatePixmapFromXPixmaps(scr, pix, None, 16, 16, scr->depth);
 
369
}
 
370
 
 
371
 
 
372
static void
 
373
handleDragEvents(XEvent *event, void *data)
 
374
{
 
375
    WMColorWell *cPtr = (ColorWell*)data;
 
376
 
 
377
    if (event->type == ButtonPress && event->xbutton.button == Button1) {
 
378
        /* initialise drag icon */
 
379
        WMSetViewDragImage(cPtr->colorView, makeDragPixmap(cPtr));
 
380
    }
 
381
 
 
382
    WMDragImageFromView(cPtr->colorView, event);
 
383
}
 
384
 
 
385
 
 
386
static void
 
387
handleActionEvents(XEvent *event, void *data)
 
388
{
 
389
    WMColorWell *cPtr = (ColorWell*)data;
 
390
    WMScreen *scr = WMWidgetScreen(cPtr);
 
391
    WMColorPanel *cpanel;
 
392
 
 
393
    if (cPtr->flags.active)
 
394
        W_SetViewBackgroundColor(cPtr->view, scr->gray);
 
395
    else
 
396
        W_SetViewBackgroundColor(cPtr->view, scr->white);
 
397
    paintColorWell(cPtr);
 
398
 
 
399
    cPtr->flags.active ^= 1;
 
400
 
 
401
    if (cPtr->flags.active) {
 
402
        WMPostNotificationName(_ColorWellActivatedNotification, cPtr, NULL);
 
403
    }
 
404
    cpanel = WMGetColorPanel(scr);
 
405
 
 
406
    WMSetColorPanelAction(cpanel, updateColorCallback, cPtr);
 
407
 
 
408
    if (cPtr->color)
 
409
        WMSetColorPanelColor(cpanel, cPtr->color);
 
410
    WMShowColorPanel(cpanel);
 
411
}
 
412
 
 
413
 
 
414
static void
 
415
destroyColorWell(ColorWell *cPtr)
 
416
{
 
417
    WMRemoveNotificationObserver(cPtr);
 
418
 
 
419
    if (cPtr->color)
 
420
        WMReleaseColor(cPtr->color);
 
421
 
 
422
    WMFreeArray(cPtr->xdndTypes);
 
423
 
 
424
    wfree(cPtr);
 
425
}
 
426
 
 
427
 
 
428
static Bool
 
429
dropIsOk(WMDragOperationType request, WMArray *sourceDataTypes)
 
430
{
 
431
    WMArrayIterator iter;
 
432
    char *type;
 
433
 
 
434
    if (request == WDOperationCopy) {
 
435
        WM_ITERATE_ARRAY(sourceDataTypes, type, iter) {
 
436
            if (type != NULL && strcmp(type, XDND_COLOR_DATA_TYPE)==0) {
 
437
                return True;
 
438
            }
 
439
        }
 
440
    }
 
441
 
 
442
    return False;
 
443
}
 
444
 
 
445
 
 
446
static WMArray*
 
447
requiredDataTypes(WMView *self, WMDragOperationType request, WMArray *sourceDataTypes)
 
448
{
 
449
    if (dropIsOk(request, sourceDataTypes))
 
450
        return ((ColorWell*)self->self)->xdndTypes;
 
451
    else
 
452
        return NULL;
 
453
}
 
454
 
 
455
 
 
456
static WMDragOperationType
 
457
allowedOperation(WMView *self, WMDragOperationType request, WMArray *sourceDataTypes)
 
458
{
 
459
    if (dropIsOk(request, sourceDataTypes))
 
460
        return WDOperationCopy;
 
461
    else
 
462
        return WDOperationNone;
 
463
}
 
464
 
 
465
 
 
466
static void
 
467
performDragOperation(WMView *self, WMArray *dropData, WMArray *operations,
 
468
                     WMPoint* dropLocation)
 
469
{
 
470
    char *colorName;
 
471
    WMColor *color;
 
472
    WMData* data;
 
473
 
 
474
    /* only one operation requested (WDOperationCopy) implies only one data */
 
475
    data = (WMData*)WMGetFromArray(dropData, 0);
 
476
 
 
477
    if (data != NULL) {
 
478
        colorName = (char*)WMDataBytes(data);
 
479
        color = WMCreateNamedColor(W_VIEW_SCREEN(self), colorName, True);
 
480
        WMSetColorWellColor(self->self, color);
 
481
        WMReleaseColor(color);
 
482
    }
 
483
}
 
484
 
 
485