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

« back to all changes in this revision

Viewing changes to WINGs/Extras/wtableview.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
#include <WINGs/WINGsP.h>
 
4
#include <X11/cursorfont.h>
 
5
 
 
6
#include "wtableview.h"
 
7
 
 
8
 
 
9
const char *WMTableViewSelectionDidChangeNotification = "WMTableViewSelectionDidChangeNotification";
 
10
 
 
11
 
 
12
struct W_TableColumn {
 
13
    WMTableView *table;
 
14
    WMWidget *titleW;
 
15
    char *title;
 
16
    int width;
 
17
    int minWidth;
 
18
    int maxWidth;
 
19
 
 
20
    void *id;
 
21
 
 
22
    WMTableColumnDelegate *delegate;
 
23
 
 
24
    unsigned resizable:1;
 
25
    unsigned editable:1;
 
26
};
 
27
 
 
28
 
 
29
static void handleResize(W_ViewDelegate *self, WMView *view);
 
30
 
 
31
static void rearrangeHeader(WMTableView *table);
 
32
 
 
33
static WMRange rowsInRect(WMTableView *table, WMRect rect);
 
34
 
 
35
 
 
36
WMTableColumn*
 
37
WMCreateTableColumn(char *title)
 
38
{
 
39
    WMTableColumn *col = wmalloc(sizeof(WMTableColumn));
 
40
 
 
41
    col->table = NULL;
 
42
    col->titleW = NULL;
 
43
    col->width = 50;
 
44
    col->minWidth = 5;
 
45
    col->maxWidth = 0;
 
46
 
 
47
    col->id = NULL;
 
48
 
 
49
    col->title = wstrdup(title);
 
50
 
 
51
    col->delegate = NULL;
 
52
 
 
53
    col->resizable = 1;
 
54
    col->editable = 0;
 
55
 
 
56
    return col;
 
57
}
 
58
 
 
59
 
 
60
void
 
61
WMSetTableColumnId(WMTableColumn *column, void *id)
 
62
{
 
63
    column->id = id;
 
64
}
 
65
 
 
66
 
 
67
void*
 
68
WMGetTableColumnId(WMTableColumn *column)
 
69
{
 
70
    return column->id;
 
71
}
 
72
 
 
73
 
 
74
void
 
75
WMSetTableColumnWidth(WMTableColumn *column, unsigned width)
 
76
{
 
77
    if (column->maxWidth == 0)
 
78
        column->width = WMAX(column->minWidth, width);
 
79
    else
 
80
        column->width = WMAX(column->minWidth, WMIN(column->maxWidth, width));
 
81
 
 
82
    if (column->table) {
 
83
        rearrangeHeader(column->table);
 
84
    }
 
85
}
 
86
 
 
87
 
 
88
void
 
89
WMSetTableColumnDelegate(WMTableColumn *column, WMTableColumnDelegate *delegate)
 
90
{
 
91
    column->delegate = delegate;
 
92
}
 
93
 
 
94
 
 
95
void
 
96
WMSetTableColumnConstraints(WMTableColumn *column, unsigned minWidth,
 
97
                            unsigned maxWidth)
 
98
{
 
99
    wassertr(maxWidth == 0 || minWidth <= maxWidth);
 
100
 
 
101
    column->minWidth = minWidth;
 
102
    column->maxWidth = maxWidth;
 
103
 
 
104
    if (column->width < column->minWidth)
 
105
        WMSetTableColumnWidth(column, column->minWidth);
 
106
    else if (column->width > column->maxWidth && column->maxWidth != 0)
 
107
        WMSetTableColumnWidth(column, column->maxWidth);
 
108
}
 
109
 
 
110
 
 
111
void
 
112
WMSetTableColumnEditable(WMTableColumn *column, Bool flag)
 
113
{
 
114
    column->editable = ((flag==0) ? 0 : 1);
 
115
}
 
116
 
 
117
 
 
118
WMTableView*
 
119
WMGetTableColumnTableView(WMTableColumn *column)
 
120
{
 
121
    return column->table;
 
122
}
 
123
 
 
124
 
 
125
 
 
126
struct W_TableView {
 
127
    W_Class widgetClass;
 
128
    WMView *view;
 
129
 
 
130
    WMFrame *header;
 
131
 
 
132
    WMLabel *corner;
 
133
 
 
134
    WMScroller *hscroll;
 
135
    WMScroller *vscroll;
 
136
    WMView *tableView;
 
137
 
 
138
    WMPixmap *viewBuffer;
 
139
 
 
140
    WMArray *columns;
 
141
    WMArray *splitters;
 
142
 
 
143
    WMArray *selectedRows;
 
144
 
 
145
    int tableWidth;
 
146
 
 
147
    int rows;
 
148
 
 
149
    WMColor *backColor;
 
150
 
 
151
    GC gridGC;
 
152
    WMColor *gridColor;
 
153
 
 
154
    Cursor splitterCursor;
 
155
 
 
156
    void *dataSource;
 
157
 
 
158
    WMTableViewDelegate *delegate;
 
159
 
 
160
    WMAction *action;
 
161
    void *clientData;
 
162
 
 
163
    void *clickedColumn;
 
164
    int clickedRow;
 
165
 
 
166
    int editingRow;
 
167
 
 
168
    unsigned headerHeight;
 
169
 
 
170
    unsigned rowHeight;
 
171
 
 
172
    unsigned dragging:1;
 
173
    unsigned drawsGrid:1;
 
174
    unsigned canSelectRow:1;
 
175
    unsigned canSelectMultiRows:1;
 
176
    unsigned canDeselectRow:1;
 
177
 
 
178
    unsigned int hasVScroller:1;
 
179
    unsigned int hasHScroller:1;
 
180
};
 
181
 
 
182
static W_Class tableClass = 0;
 
183
 
 
184
 
 
185
static W_ViewDelegate viewDelegate = {
 
186
    NULL,
 
187
    NULL,
 
188
    handleResize,
 
189
    NULL,
 
190
    NULL
 
191
};
 
192
 
 
193
 
 
194
 
 
195
static void reorganizeInterior(WMTableView *table);
 
196
 
 
197
 
 
198
static void handleEvents(XEvent *event, void *data);
 
199
static void handleTableEvents(XEvent *event, void *data);
 
200
static void repaintTable(WMTableView *table);
 
201
 
 
202
static WMSize
 
203
getTotalSize(WMTableView *table)
 
204
{
 
205
    WMSize size;
 
206
    int i;
 
207
 
 
208
    /* get width from columns */
 
209
    size.width = 0;
 
210
    for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
 
211
        WMTableColumn *column;
 
212
 
 
213
        column = WMGetFromArray(table->columns, i);
 
214
 
 
215
        size.width += column->width;
 
216
    }
 
217
 
 
218
    /* get height from rows */
 
219
    size.height = table->rows * table->rowHeight;
 
220
 
 
221
    return size;
 
222
}
 
223
 
 
224
 
 
225
static WMRect
 
226
getVisibleRect(WMTableView *table)
 
227
{
 
228
    WMSize size = getTotalSize(table);
 
229
    WMRect rect;
 
230
 
 
231
    if (table->vscroll) {
 
232
        rect.size.height = size.height * WMGetScrollerKnobProportion(table->vscroll);
 
233
        rect.pos.y = (size.height - rect.size.height) * WMGetScrollerValue(table->vscroll);
 
234
    } else {
 
235
        rect.size.height = size.height;
 
236
        rect.pos.y = 0;
 
237
    }
 
238
 
 
239
    if (table->hscroll) {
 
240
        rect.size.width = size.width * WMGetScrollerKnobProportion(table->hscroll);
 
241
        rect.pos.x = (size.width - rect.size.width) * WMGetScrollerValue(table->hscroll);
 
242
    } else {
 
243
        rect.size.width = size.width;
 
244
        rect.pos.x = 0;
 
245
    }
 
246
 
 
247
    return rect;
 
248
}
 
249
 
 
250
 
 
251
static void
 
252
scrollToPoint(WMTableView *table, int x, int y)
 
253
{
 
254
    WMSize size = getTotalSize(table);
 
255
    int i;
 
256
    float value, prop;
 
257
 
 
258
    if (table->hscroll) {
 
259
        if (size.width > W_VIEW_WIDTH(table->tableView)) {
 
260
            prop = (float)W_VIEW_WIDTH(table->tableView) / (float)size.width;
 
261
            value = (float)x / (float)(size.width - W_VIEW_WIDTH(table->tableView));
 
262
        } else {
 
263
            prop = 1.0;
 
264
            value = 0.0;
 
265
        }
 
266
        WMSetScrollerParameters(table->hscroll, value, prop);
 
267
    }
 
268
 
 
269
    if (table->vscroll) {
 
270
        if (size.height > W_VIEW_HEIGHT(table->tableView)) {
 
271
            prop = (float)W_VIEW_HEIGHT(table->tableView) / (float)size.height;
 
272
            value = (float)y / (float)(size.height - W_VIEW_HEIGHT(table->tableView));
 
273
        } else {
 
274
            prop = 1.0;
 
275
            value = 0.0;
 
276
        }
 
277
 
 
278
        WMSetScrollerParameters(table->vscroll, value, prop);
 
279
    }
 
280
 
 
281
 
 
282
    if (table->editingRow >= 0) {
 
283
        for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
 
284
            WMTableColumn *column;
 
285
 
 
286
            column = WMGetFromArray(table->columns, i);
 
287
 
 
288
            if (column->delegate && column->delegate->beginCellEdit)
 
289
                (*column->delegate->beginCellEdit)(column->delegate, column,
 
290
                                                   table->editingRow);
 
291
        }
 
292
    }
 
293
 
 
294
    repaintTable(table);
 
295
}
 
296
 
 
297
 
 
298
static void
 
299
adjustScrollers(WMTableView *table)
 
300
{
 
301
    WMSize size = getTotalSize(table);
 
302
    WMSize vsize = WMGetViewSize(table->tableView);
 
303
    float prop, value;
 
304
    float oprop, ovalue;
 
305
 
 
306
    if (table->hscroll) {
 
307
        if (size.width <= vsize.width) {
 
308
            value = 0.0;
 
309
            prop = 1.0;
 
310
        } else {
 
311
            oprop = WMGetScrollerKnobProportion(table->hscroll);
 
312
            if (oprop == 0.0)
 
313
                oprop = 1.0;
 
314
            ovalue = WMGetScrollerValue(table->hscroll);
 
315
 
 
316
            prop = (float)vsize.width/(float)size.width;
 
317
            value = prop*ovalue / oprop;
 
318
        }
 
319
        WMSetScrollerParameters(table->hscroll, value, prop);
 
320
    }
 
321
 
 
322
    if (table->vscroll) {
 
323
        if (size.height <= vsize.height) {
 
324
            value = 0.0;
 
325
            prop = 1.0;
 
326
        } else {
 
327
            oprop = WMGetScrollerKnobProportion(table->vscroll);
 
328
            if (oprop == 0.0)
 
329
                oprop = 1.0;
 
330
            ovalue = WMGetScrollerValue(table->vscroll);
 
331
 
 
332
            prop = (float)vsize.height/(float)size.height;
 
333
            value = prop*ovalue / oprop;
 
334
        }
 
335
        WMSetScrollerParameters(table->vscroll, value, prop);
 
336
    }
 
337
}
 
338
 
 
339
 
 
340
static void
 
341
doScroll(WMWidget *self, void *data)
 
342
{
 
343
    WMTableView *table = (WMTableView*)data;
 
344
    float value;
 
345
    float vpsize;
 
346
    float size;
 
347
    WMSize ts = getTotalSize(table);
 
348
 
 
349
    value = WMGetScrollerValue(self);
 
350
 
 
351
    if (table->hscroll == (WMScroller *)self) {
 
352
        vpsize = W_VIEW_WIDTH(table->tableView);
 
353
        size = ts.width;
 
354
    } else {
 
355
        vpsize = W_VIEW_HEIGHT(table->tableView);
 
356
        size = ts.height;
 
357
    }
 
358
 
 
359
    switch (WMGetScrollerHitPart(self)) {
 
360
    case WSDecrementWheel:
 
361
    case WSDecrementLine:
 
362
        value -= (float)table->rowHeight / size;
 
363
        if (value < 0)
 
364
            value = 0.0;
 
365
        WMSetScrollerParameters(self, value,
 
366
                                WMGetScrollerKnobProportion(self));
 
367
        repaintTable(table);
 
368
        break;
 
369
 
 
370
    case WSIncrementWheel:
 
371
    case WSIncrementLine:
 
372
        value += (float)table->rowHeight / size;
 
373
        if (value > 1.0)
 
374
            value = 1.0;
 
375
        WMSetScrollerParameters(self, value,
 
376
                                WMGetScrollerKnobProportion(self));
 
377
        repaintTable(table);
 
378
        break;
 
379
 
 
380
    case WSKnob:
 
381
        repaintTable(table);
 
382
        break;
 
383
 
 
384
    case WSDecrementPage:
 
385
        value -= vpsize / size;
 
386
        if (value < 0.0)
 
387
            value = 0.0;
 
388
        WMSetScrollerParameters(self, value,
 
389
                                WMGetScrollerKnobProportion(self));
 
390
        repaintTable(table);
 
391
        break;
 
392
 
 
393
    case WSIncrementPage:
 
394
        value += vpsize / size;
 
395
        if (value > 1.0)
 
396
            value = 1.0;
 
397
        WMSetScrollerParameters(self, value,
 
398
                                WMGetScrollerKnobProportion(self));
 
399
        repaintTable(table);
 
400
        break;
 
401
 
 
402
 
 
403
    case WSNoPart:
 
404
    case WSKnobSlot:
 
405
        break;
 
406
    }
 
407
 
 
408
    if (table->editingRow >= 0) {
 
409
        int i;
 
410
        for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
 
411
            WMTableColumn *column;
 
412
 
 
413
            column = WMGetFromArray(table->columns, i);
 
414
 
 
415
            if (column->delegate && column->delegate->beginCellEdit)
 
416
                (*column->delegate->beginCellEdit)(column->delegate, column,
 
417
                                                   table->editingRow);
 
418
        }
 
419
    }
 
420
 
 
421
 
 
422
    if (table->hscroll == self) {
 
423
        int x = 0;
 
424
        int i;
 
425
        WMRect rect = getVisibleRect(table);
 
426
 
 
427
        for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
 
428
            WMTableColumn *column;
 
429
            WMView *splitter;
 
430
 
 
431
            column = WMGetFromArray(table->columns, i);
 
432
 
 
433
            WMMoveWidget(column->titleW, x - rect.pos.x, 0);
 
434
 
 
435
            x += W_VIEW_WIDTH(WMWidgetView(column->titleW)) + 1;
 
436
 
 
437
            splitter = WMGetFromArray(table->splitters, i);
 
438
            W_MoveView(splitter, x - rect.pos.x - 1, 0);
 
439
        }
 
440
    }
 
441
}
 
442
 
 
443
 
 
444
static void
 
445
splitterHandler(XEvent *event, void *data)
 
446
{
 
447
    WMTableColumn *column = (WMTableColumn*)data;
 
448
    WMTableView *table = column->table;
 
449
    int done = 0;
 
450
    int cx, ox, offsX;
 
451
    WMPoint pos;
 
452
    WMScreen *scr = WMWidgetScreen(table);
 
453
    GC gc = scr->ixorGC;
 
454
    Display *dpy = WMScreenDisplay(scr);
 
455
    int h = WMWidgetHeight(table) - 22;
 
456
    Window w = WMViewXID(table->view);
 
457
 
 
458
    pos = WMGetViewPosition(WMWidgetView(column->titleW));
 
459
 
 
460
    offsX = pos.x + column->width;
 
461
 
 
462
    ox = cx = offsX;
 
463
 
 
464
    XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h);
 
465
 
 
466
    while (!done) {
 
467
        XEvent ev;
 
468
 
 
469
        WMMaskEvent(dpy, ButtonMotionMask|ButtonReleaseMask, &ev);
 
470
 
 
471
        switch (ev.type) {
 
472
        case MotionNotify:
 
473
            ox = cx;
 
474
 
 
475
            if (column->width + ev.xmotion.x < column->minWidth)
 
476
                cx = pos.x + column->minWidth;
 
477
            else if (column->maxWidth > 0
 
478
                     && column->width + ev.xmotion.x > column->maxWidth)
 
479
                cx = pos.x + column->maxWidth;
 
480
            else
 
481
                cx = offsX + ev.xmotion.x;
 
482
 
 
483
            XDrawLine(dpy, w, gc, ox+20, 0, ox+20, h);
 
484
            XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h);
 
485
            break;
 
486
 
 
487
        case ButtonRelease:
 
488
            column->width = cx - pos.x;
 
489
            done = 1;
 
490
            break;
 
491
        }
 
492
    }
 
493
 
 
494
    XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h);
 
495
    rearrangeHeader(table);
 
496
    repaintTable(table);
 
497
}
 
498
 
 
499
 
 
500
static void
 
501
realizeTable(void *data, WMNotification *notif)
 
502
{
 
503
    repaintTable(data);
 
504
}
 
505
 
 
506
 
 
507
WMTableView*
 
508
WMCreateTableView(WMWidget *parent)
 
509
{
 
510
    WMTableView *table = wmalloc(sizeof(WMTableView));
 
511
    WMScreen *scr = WMWidgetScreen(parent);
 
512
 
 
513
    memset(table, 0, sizeof(WMTableView));
 
514
 
 
515
    if (!tableClass) {
 
516
        tableClass = W_RegisterUserWidget();
 
517
    }
 
518
    table->widgetClass = tableClass;
 
519
 
 
520
    table->view = W_CreateView(W_VIEW(parent));
 
521
    if (!table->view)
 
522
        goto error;
 
523
    table->view->self = table;
 
524
 
 
525
    table->view->delegate = &viewDelegate;
 
526
 
 
527
    table->headerHeight = 20;
 
528
 
 
529
    table->hscroll = WMCreateScroller(table);
 
530
    WMSetScrollerAction(table->hscroll, doScroll, table);
 
531
    WMMoveWidget(table->hscroll, 1, 2+table->headerHeight);
 
532
    WMMapWidget(table->hscroll);
 
533
 
 
534
    table->hasHScroller = 1;
 
535
 
 
536
    table->vscroll = WMCreateScroller(table);
 
537
    WMSetScrollerArrowsPosition(table->vscroll, WSAMaxEnd);
 
538
    WMSetScrollerAction(table->vscroll, doScroll, table);
 
539
    WMMoveWidget(table->vscroll, 1, 2+table->headerHeight);
 
540
    WMMapWidget(table->vscroll);
 
541
 
 
542
    table->hasVScroller = 1;
 
543
 
 
544
    table->header = WMCreateFrame(table);
 
545
    WMMoveWidget(table->header, 22, 2);
 
546
    WMMapWidget(table->header);
 
547
    WMSetFrameRelief(table->header, WRFlat);
 
548
 
 
549
    table->corner = WMCreateLabel(table);
 
550
    WMResizeWidget(table->corner, 20, table->headerHeight);
 
551
    WMMoveWidget(table->corner, 2, 2);
 
552
    WMMapWidget(table->corner);
 
553
    WMSetLabelRelief(table->corner, WRRaised);
 
554
    WMSetWidgetBackgroundColor(table->corner, scr->darkGray);
 
555
 
 
556
 
 
557
    table->tableView = W_CreateView(table->view);
 
558
    if (!table->tableView)
 
559
        goto error;
 
560
    table->tableView->self = table;
 
561
    W_MapView(table->tableView);
 
562
 
 
563
    WMAddNotificationObserver(realizeTable, table, WMViewRealizedNotification,
 
564
                              table->tableView);
 
565
 
 
566
    table->tableView->flags.dontCompressExpose = 1;
 
567
 
 
568
    table->gridColor = WMCreateNamedColor(scr, "#cccccc", False);
 
569
    /*   table->gridColor = WMGrayColor(scr);*/
 
570
 
 
571
    {
 
572
        XGCValues gcv;
 
573
 
 
574
        table->backColor = WMWhiteColor(scr);
 
575
 
 
576
        gcv.foreground = WMColorPixel(table->gridColor);
 
577
        gcv.dashes = 1;
 
578
        gcv.line_style = LineOnOffDash;
 
579
        table->gridGC = XCreateGC(WMScreenDisplay(scr), W_DRAWABLE(scr),
 
580
                                  GCForeground, &gcv);
 
581
    }
 
582
 
 
583
    table->editingRow = -1;
 
584
    table->clickedRow = -1;
 
585
 
 
586
    table->drawsGrid = 1;
 
587
    table->rowHeight = 16;
 
588
 
 
589
    table->tableWidth = 1;
 
590
 
 
591
    table->columns = WMCreateArray(4);
 
592
    table->splitters = WMCreateArray(4);
 
593
 
 
594
    table->selectedRows = WMCreateArray(16);
 
595
 
 
596
    table->splitterCursor = XCreateFontCursor(WMScreenDisplay(scr),
 
597
                                              XC_sb_h_double_arrow);
 
598
 
 
599
    table->canSelectRow = 1;
 
600
 
 
601
    WMCreateEventHandler(table->view, ExposureMask|StructureNotifyMask,
 
602
                         handleEvents, table);
 
603
 
 
604
    WMCreateEventHandler(table->tableView, ExposureMask|ButtonPressMask|
 
605
                         ButtonReleaseMask|ButtonMotionMask,
 
606
                         handleTableEvents, table);
 
607
 
 
608
    WMResizeWidget(table, 50, 50);
 
609
 
 
610
    return table;
 
611
 
 
612
    error:
 
613
        if (table->tableView)
 
614
            W_DestroyView(table->tableView);
 
615
        if (table->view)
 
616
            W_DestroyView(table->view);
 
617
        wfree(table);
 
618
        return NULL;
 
619
}
 
620
 
 
621
 
 
622
void
 
623
WMAddTableViewColumn(WMTableView *table, WMTableColumn *column)
 
624
{
 
625
    WMScreen *scr = WMWidgetScreen(table);
 
626
 
 
627
    column->table = table;
 
628
 
 
629
    WMAddToArray(table->columns, column);
 
630
 
 
631
    if (!column->titleW) {
 
632
        column->titleW = WMCreateLabel(table);
 
633
        WMSetLabelRelief(column->titleW, WRRaised);
 
634
        WMSetLabelFont(column->titleW, scr->boldFont);
 
635
        WMSetLabelTextColor(column->titleW, scr->white);
 
636
        WMSetWidgetBackgroundColor(column->titleW, scr->darkGray);
 
637
        WMSetLabelText(column->titleW, column->title);
 
638
        W_ReparentView(WMWidgetView(column->titleW),
 
639
                       WMWidgetView(table->header), 0, 0);
 
640
        if (W_VIEW_REALIZED(table->view))
 
641
            WMRealizeWidget(column->titleW);
 
642
        WMMapWidget(column->titleW);
 
643
    }
 
644
 
 
645
    {
 
646
        WMView *splitter = W_CreateView(WMWidgetView(table->header));
 
647
 
 
648
        W_SetViewBackgroundColor(splitter, WMWhiteColor(scr));
 
649
 
 
650
        if (W_VIEW_REALIZED(table->view))
 
651
            W_RealizeView(splitter);
 
652
 
 
653
        W_ResizeView(splitter, 2, table->headerHeight);
 
654
        W_MapView(splitter);
 
655
 
 
656
        W_SetViewCursor(splitter, table->splitterCursor);
 
657
        WMCreateEventHandler(splitter, ButtonPressMask|ButtonReleaseMask,
 
658
                             splitterHandler, column);
 
659
 
 
660
        WMAddToArray(table->splitters, splitter);
 
661
    }
 
662
 
 
663
    rearrangeHeader(table);
 
664
}
 
665
 
 
666
 
 
667
void
 
668
WMSetTableViewHeaderHeight(WMTableView *table, unsigned height)
 
669
{
 
670
    table->headerHeight = height;
 
671
 
 
672
    handleResize(NULL, table->view);
 
673
}
 
674
 
 
675
 
 
676
void
 
677
WMSetTableViewDelegate(WMTableView *table, WMTableViewDelegate *delegate)
 
678
{
 
679
    table->delegate = delegate;
 
680
}
 
681
 
 
682
 
 
683
void
 
684
WMSetTableViewAction(WMTableView *table, WMAction *action, void *clientData)
 
685
{
 
686
    table->action = action;
 
687
 
 
688
    table->clientData = clientData;
 
689
}
 
690
 
 
691
 
 
692
void*
 
693
WMGetTableViewClickedColumn(WMTableView *table)
 
694
{
 
695
    return table->clickedColumn;
 
696
}
 
697
 
 
698
 
 
699
int
 
700
WMGetTableViewClickedRow(WMTableView *table)
 
701
{
 
702
    return table->clickedRow;
 
703
}
 
704
 
 
705
 
 
706
WMArray*
 
707
WMGetTableViewSelectedRows(WMTableView *table)
 
708
{
 
709
    return table->selectedRows;
 
710
}
 
711
 
 
712
 
 
713
WMView*
 
714
WMGetTableViewDocumentView(WMTableView *table)
 
715
{
 
716
    return table->tableView;
 
717
}
 
718
 
 
719
 
 
720
void*
 
721
WMTableViewDataForCell(WMTableView *table, WMTableColumn *column, int row)
 
722
{
 
723
    return (*table->delegate->valueForCell)(table->delegate, column, row);
 
724
}
 
725
 
 
726
 
 
727
void
 
728
WMSetTableViewDataForCell(WMTableView *table, WMTableColumn *column, int row,
 
729
                          void *data)
 
730
{
 
731
    (*table->delegate->setValueForCell)(table->delegate, column, row, data);
 
732
}
 
733
 
 
734
 
 
735
WMRect
 
736
WMTableViewRectForCell(WMTableView *table, WMTableColumn *column, int row)
 
737
{
 
738
    WMRect rect;
 
739
    int i;
 
740
 
 
741
    rect.pos.x = 0;
 
742
    rect.pos.y = row * table->rowHeight;
 
743
    rect.size.height = table->rowHeight;
 
744
 
 
745
    for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
 
746
        WMTableColumn *col;
 
747
        col = WMGetFromArray(table->columns, i);
 
748
 
 
749
        if (col == column) {
 
750
            rect.size.width = col->width;
 
751
            break;
 
752
        }
 
753
 
 
754
        rect.pos.x += col->width;
 
755
    }
 
756
 
 
757
    {
 
758
        WMRect r = getVisibleRect(table);
 
759
 
 
760
        rect.pos.y -= r.pos.y;
 
761
        rect.pos.x -= r.pos.x;
 
762
    }
 
763
 
 
764
    return rect;
 
765
}
 
766
 
 
767
 
 
768
void
 
769
WMSetTableViewDataSource(WMTableView *table, void *source)
 
770
{
 
771
    table->dataSource = source;
 
772
}
 
773
 
 
774
 
 
775
void*
 
776
WMGetTableViewDataSource(WMTableView *table)
 
777
{
 
778
    return table->dataSource;
 
779
}
 
780
 
 
781
 
 
782
 
 
783
void
 
784
WMSetTableViewHasHorizontalScroller(WMTableView *tPtr, Bool flag)
 
785
{
 
786
    if (flag) {
 
787
        if (tPtr->hasHScroller)
 
788
            return;
 
789
        tPtr->hasHScroller = 1;
 
790
 
 
791
        tPtr->hscroll = WMCreateScroller(tPtr);
 
792
        WMSetScrollerAction(tPtr->hscroll, doScroll, tPtr);
 
793
        WMSetScrollerArrowsPosition(tPtr->hscroll, WSAMaxEnd);
 
794
        /* make it a horiz. scroller */
 
795
        WMResizeWidget(tPtr->hscroll, 1, 2);
 
796
 
 
797
        if (W_VIEW_REALIZED(tPtr->view)) {
 
798
            WMRealizeWidget(tPtr->hscroll);
 
799
        }
 
800
 
 
801
        reorganizeInterior(tPtr);
 
802
 
 
803
        WMMapWidget(tPtr->hscroll);
 
804
    } else {
 
805
        if (!tPtr->hasHScroller)
 
806
            return;
 
807
        tPtr->hasHScroller = 0;
 
808
 
 
809
        WMUnmapWidget(tPtr->hscroll);
 
810
        WMDestroyWidget(tPtr->hscroll);
 
811
        tPtr->hscroll = NULL;
 
812
 
 
813
        reorganizeInterior(tPtr);
 
814
    }
 
815
}
 
816
 
 
817
#if 0
 
818
/* not supported by now */
 
819
void
 
820
WMSetTableViewHasVerticalScroller(WMTableView *tPtr, Bool flag)
 
821
{
 
822
    if (flag) {
 
823
        if (tPtr->hasVScroller)
 
824
            return;
 
825
        tPtr->hasVScroller = 1;
 
826
 
 
827
        tPtr->vscroll = WMCreateScroller(tPtr);
 
828
        WMSetScrollerAction(tPtr->vscroll, doScroll, tPtr);
 
829
        WMSetScrollerArrowsPosition(tPtr->vscroll, WSAMaxEnd);
 
830
        /* make it a vert. scroller */
 
831
        WMResizeWidget(tPtr->vscroll, 1, 2);
 
832
 
 
833
        if (W_VIEW_REALIZED(tPtr->view)) {
 
834
            WMRealizeWidget(tPtr->vscroll);
 
835
        }
 
836
 
 
837
        reorganizeInterior(tPtr);
 
838
 
 
839
        WMMapWidget(tPtr->vscroll);
 
840
    } else {
 
841
        if (!tPtr->hasVScroller)
 
842
            return;
 
843
        tPtr->hasVScroller = 0;
 
844
 
 
845
        WMUnmapWidget(tPtr->vscroll);
 
846
        WMDestroyWidget(tPtr->vscroll);
 
847
        tPtr->vscroll = NULL;
 
848
 
 
849
        reorganizeInterior(tPtr);
 
850
    }
 
851
}
 
852
#endif
 
853
 
 
854
void
 
855
WMSetTableViewBackgroundColor(WMTableView *table, WMColor *color)
 
856
{
 
857
    W_SetViewBackgroundColor(table->tableView, color);
 
858
 
 
859
    if (table->backColor)
 
860
        WMReleaseColor(table->backColor);
 
861
 
 
862
    table->backColor = WMRetainColor(color);
 
863
 
 
864
    repaintTable(table);
 
865
}
 
866
 
 
867
 
 
868
void
 
869
WMSetTableViewGridColor(WMTableView *table, WMColor *color)
 
870
{
 
871
    WMReleaseColor(table->gridColor);
 
872
    table->gridColor = WMRetainColor(color);
 
873
    XSetForeground(WMScreenDisplay(WMWidgetScreen(table)), table->gridGC,
 
874
                   WMColorPixel(color));
 
875
    repaintTable(table);
 
876
}
 
877
 
 
878
 
 
879
 
 
880
void
 
881
WMSetTableViewRowHeight(WMTableView *table, int height)
 
882
{
 
883
    table->rowHeight = height;
 
884
 
 
885
    repaintTable(table);
 
886
}
 
887
 
 
888
 
 
889
void
 
890
WMScrollTableViewRowToVisible(WMTableView *table, int row)
 
891
{
 
892
    WMScroller *scroller;
 
893
    WMRange range;
 
894
    WMRect rect;
 
895
    int newY, tmp;
 
896
 
 
897
    rect = getVisibleRect(table);
 
898
    range = rowsInRect(table, rect);
 
899
 
 
900
    scroller = table->vscroll;
 
901
 
 
902
    if (row < range.position) {
 
903
        newY = row * table->rowHeight - rect.size.height / 2;
 
904
    } else if (row >= range.position + range.count) {
 
905
        newY = row * table->rowHeight - rect.size.height / 2;
 
906
    } else {
 
907
        return;
 
908
    }
 
909
    tmp = table->rows*table->rowHeight - rect.size.height;
 
910
    newY = WMAX(0, WMIN(newY, tmp));
 
911
 
 
912
    scrollToPoint(table, rect.pos.x, newY);
 
913
}
 
914
 
 
915
 
 
916
 
 
917
static void
 
918
drawGrid(WMTableView *table, WMRect rect)
 
919
{
 
920
    WMScreen *scr = WMWidgetScreen(table);
 
921
    Display *dpy = WMScreenDisplay(scr);
 
922
    int i;
 
923
    int y1, y2;
 
924
    int x1, x2;
 
925
    int xx;
 
926
    Drawable d = WMGetPixmapXID(table->viewBuffer);
 
927
    GC gc = table->gridGC;
 
928
 
 
929
#if 0
 
930
    char dashl[1] = {1};
 
931
 
 
932
    XSetDashes(dpy, gc, 0, dashl, 1);
 
933
 
 
934
    y1 = (rect.pos.y/table->rowHeight - 1)*table->rowHeight;
 
935
    y2 = y1 + (rect.size.height/table->rowHeight+2)*table->rowHeight;
 
936
#endif
 
937
    y1 = 0;
 
938
    y2 = W_VIEW_HEIGHT(table->tableView);
 
939
 
 
940
    xx = -rect.pos.x;
 
941
    for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
 
942
        WMTableColumn *column;
 
943
 
 
944
        XDrawLine(dpy, d, gc, xx, y1, xx, y2);
 
945
 
 
946
        column = WMGetFromArray(table->columns, i);
 
947
        xx += column->width;
 
948
    }
 
949
    XDrawLine(dpy, d, gc, xx, y1, xx, y2);
 
950
 
 
951
    x1 = 0;
 
952
    x2 = rect.size.width;
 
953
 
 
954
    if (x2 <= x1)
 
955
        return;
 
956
#if 0
 
957
    XSetDashes(dpy, gc, (rect.pos.x&1), dashl, 1);
 
958
#endif
 
959
 
 
960
    y1 = -rect.pos.y%table->rowHeight;
 
961
    y2 = y1 + rect.size.height + table->rowHeight;
 
962
 
 
963
    for (i = y1; i <= y2; i += table->rowHeight) {
 
964
        XDrawLine(dpy, d, gc, x1, i, x2, i);
 
965
    }
 
966
}
 
967
 
 
968
 
 
969
static WMRange
 
970
columnsInRect(WMTableView *table, WMRect rect)
 
971
{
 
972
    WMTableColumn *column;
 
973
    int pos;
 
974
    int i, found;
 
975
    int totalColumns = WMGetArrayItemCount(table->columns);
 
976
    WMRange range;
 
977
 
 
978
    pos = 0;
 
979
    found = 0;
 
980
    for (i = 0; i < totalColumns; i++) {
 
981
        column = WMGetFromArray(table->columns, i);
 
982
        if (!found) {
 
983
            if (rect.pos.x >= pos && rect.pos.x < pos + column->width) {
 
984
                range.position = i;
 
985
                range.count = 1;
 
986
                found = 1;
 
987
            }
 
988
        } else {
 
989
            if (pos > rect.pos.x + rect.size.width) {
 
990
                break;
 
991
            }
 
992
            range.count++;
 
993
        }
 
994
        pos += column->width;
 
995
    }
 
996
    range.count = WMAX(1, WMIN(range.count, totalColumns - range.position));
 
997
    return range;
 
998
}
 
999
 
 
1000
 
 
1001
static WMRange
 
1002
rowsInRect(WMTableView *table, WMRect rect)
 
1003
{
 
1004
    WMRange range;
 
1005
    int rh = table->rowHeight;
 
1006
    int dif;
 
1007
 
 
1008
    dif = rect.pos.y % rh;
 
1009
 
 
1010
    range.position = WMAX(0, (rect.pos.y - dif) / rh);
 
1011
    range.count = WMAX(1, WMIN((rect.size.height + dif) / rh, table->rows));
 
1012
 
 
1013
    return range;
 
1014
}
 
1015
 
 
1016
 
 
1017
static void
 
1018
drawRow(WMTableView *table, int row, WMRect clipRect)
 
1019
{
 
1020
    int i;
 
1021
    WMRange cols = columnsInRect(table, clipRect);
 
1022
    WMTableColumn *column;
 
1023
    Drawable d = WMGetPixmapXID(table->viewBuffer);
 
1024
 
 
1025
    for (i = cols.position; i < cols.position+cols.count; i++) {
 
1026
        column = WMGetFromArray(table->columns, i);
 
1027
 
 
1028
        if (!column->delegate || !column->delegate->drawCell)
 
1029
            continue;
 
1030
 
 
1031
        if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound)
 
1032
            (*column->delegate->drawSelectedCell)(column->delegate, column, row, d);
 
1033
        else
 
1034
            (*column->delegate->drawCell)(column->delegate, column, row, d);
 
1035
    }
 
1036
}
 
1037
 
 
1038
 
 
1039
#if 0
 
1040
static void
 
1041
drawFullRow(WMTableView *table, int row)
 
1042
{
 
1043
    int i;
 
1044
    WMTableColumn *column;
 
1045
    Drawable d = WMGetPixmapXID(table->viewBuffer);
 
1046
 
 
1047
    for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
 
1048
        column = WMGetFromArray(table->columns, i);
 
1049
 
 
1050
        if (!column->delegate || !column->delegate->drawCell)
 
1051
            continue;
 
1052
 
 
1053
        if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound)
 
1054
            (*column->delegate->drawSelectedCell)(column->delegate, column, row, d);
 
1055
        else
 
1056
            (*column->delegate->drawCell)(column->delegate, column, row, d);
 
1057
    }
 
1058
}
 
1059
#endif
 
1060
 
 
1061
 
 
1062
static void
 
1063
setRowSelected(WMTableView *table, unsigned row, Bool flag)
 
1064
{
 
1065
    int repaint = 0;
 
1066
 
 
1067
    if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound) {
 
1068
        if (!flag) {
 
1069
            WMRemoveFromArray(table->selectedRows, (void*)row);
 
1070
            repaint = 1;
 
1071
        }
 
1072
    } else {
 
1073
        if (flag) {
 
1074
            WMAddToArray(table->selectedRows, (void*)row);
 
1075
            repaint = 1;
 
1076
        }
 
1077
    }
 
1078
    if (repaint && row < table->rows) {
 
1079
        /*drawFullRow(table, row);*/
 
1080
        repaintTable(table);
 
1081
    }
 
1082
}
 
1083
 
 
1084
 
 
1085
static void
 
1086
repaintTable(WMTableView *table)
 
1087
{
 
1088
    WMRect rect;
 
1089
    WMRange rows;
 
1090
    WMScreen *scr = WMWidgetScreen(table);
 
1091
    int i;
 
1092
 
 
1093
    if (!table->delegate || !W_VIEW_REALIZED(table->view))
 
1094
        return;
 
1095
 
 
1096
    wassertr(table->delegate->numberOfRows);
 
1097
 
 
1098
    if (!table->viewBuffer) {
 
1099
        table->viewBuffer = WMCreatePixmap(scr,
 
1100
                                           W_VIEW_WIDTH(table->tableView),
 
1101
                                           W_VIEW_HEIGHT(table->tableView),
 
1102
                                           WMScreenDepth(scr), 0);
 
1103
    }
 
1104
 
 
1105
    XFillRectangle(scr->display,
 
1106
                   WMGetPixmapXID(table->viewBuffer),
 
1107
                   WMColorGC(table->backColor), 0, 0,
 
1108
                   W_VIEW_WIDTH(table->tableView),
 
1109
                   W_VIEW_HEIGHT(table->tableView));
 
1110
 
 
1111
    rect = getVisibleRect(table);
 
1112
 
 
1113
    if (table->drawsGrid) {
 
1114
        drawGrid(table, rect);
 
1115
    }
 
1116
 
 
1117
    rows = rowsInRect(table, rect);
 
1118
    for (i = rows.position;
 
1119
         i < WMIN(rows.position+rows.count + 1, table->rows);
 
1120
         i++) {
 
1121
        drawRow(table, i, rect);
 
1122
    }
 
1123
 
 
1124
    XSetWindowBackgroundPixmap(scr->display, table->tableView->window,
 
1125
                               WMGetPixmapXID(table->viewBuffer));
 
1126
    XClearWindow(scr->display, table->tableView->window);
 
1127
}
 
1128
 
 
1129
 
 
1130
static void
 
1131
stopRowEdit(WMTableView *table, int row)
 
1132
{
 
1133
    int i;
 
1134
    WMTableColumn *column;
 
1135
 
 
1136
    table->editingRow = -1;
 
1137
    for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
 
1138
        column = WMGetFromArray(table->columns, i);
 
1139
 
 
1140
        if (column->delegate && column->delegate->endCellEdit)
 
1141
            (*column->delegate->endCellEdit)(column->delegate, column, row);
 
1142
    }
 
1143
}
 
1144
 
 
1145
 
 
1146
 
 
1147
void
 
1148
WMEditTableViewRow(WMTableView *table, int row)
 
1149
{
 
1150
    int i;
 
1151
    WMTableColumn *column;
 
1152
 
 
1153
    if (table->editingRow >= 0) {
 
1154
        stopRowEdit(table, table->editingRow);
 
1155
    }
 
1156
 
 
1157
    table->editingRow = row;
 
1158
 
 
1159
    if (row < 0)
 
1160
        return;
 
1161
 
 
1162
    for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
 
1163
        column = WMGetFromArray(table->columns, i);
 
1164
 
 
1165
        if (column->delegate && column->delegate->beginCellEdit)
 
1166
            (*column->delegate->beginCellEdit)(column->delegate, column, row);
 
1167
    }
 
1168
}
 
1169
 
 
1170
 
 
1171
void
 
1172
WMSelectTableViewRow(WMTableView *table, int row)
 
1173
{
 
1174
    if (table->clickedRow >= 0)
 
1175
        setRowSelected(table, table->clickedRow, False);
 
1176
 
 
1177
    if (row >= table->rows) {
 
1178
        return;
 
1179
    }
 
1180
 
 
1181
    setRowSelected(table, row, True);
 
1182
    table->clickedRow = row;
 
1183
 
 
1184
    if (table->action)
 
1185
        (*table->action)(table, table->clientData);
 
1186
    WMPostNotificationName(WMTableViewSelectionDidChangeNotification,
 
1187
                           table, NULL);
 
1188
}
 
1189
 
 
1190
 
 
1191
void
 
1192
WMReloadTableView(WMTableView *table)
 
1193
{
 
1194
    if (table->editingRow >= 0)
 
1195
        stopRowEdit(table, table->editingRow);
 
1196
 
 
1197
    /* when this is called, nothing in the table can be assumed to be
 
1198
     * like the last time we accessed it (ie, rows might have disappeared) */
 
1199
 
 
1200
    WMEmptyArray(table->selectedRows);
 
1201
 
 
1202
    if (table->clickedRow >= 0) {
 
1203
        if (table->action)
 
1204
            (*table->action)(table, table->clientData);
 
1205
        WMPostNotificationName(WMTableViewSelectionDidChangeNotification,
 
1206
                               table, NULL);
 
1207
        table->clickedRow = -1;
 
1208
    }
 
1209
 
 
1210
    if (table->delegate && table->delegate->numberOfRows) {
 
1211
        int rows;
 
1212
 
 
1213
        rows = (*table->delegate->numberOfRows)(table->delegate, table);
 
1214
 
 
1215
        if (rows != table->rows) {
 
1216
            table->rows = rows;
 
1217
            handleResize(table->view->delegate, table->view);
 
1218
        } else {
 
1219
            repaintTable(table);
 
1220
        }
 
1221
    }
 
1222
}
 
1223
 
 
1224
 
 
1225
void
 
1226
WMNoteTableViewNumberOfRowsChanged(WMTableView *table)
 
1227
{
 
1228
    WMReloadTableView(table);
 
1229
}
 
1230
 
 
1231
 
 
1232
static void
 
1233
handleTableEvents(XEvent *event, void *data)
 
1234
{
 
1235
    WMTableView *table = (WMTableView*)data;
 
1236
    int row;
 
1237
 
 
1238
    switch (event->type) {
 
1239
    case ButtonPress:
 
1240
        if (event->xbutton.button == Button1) {
 
1241
            WMRect rect = getVisibleRect(table);
 
1242
 
 
1243
            row = (event->xbutton.y + rect.pos.y)/table->rowHeight;
 
1244
            if (row != table->clickedRow) {
 
1245
                setRowSelected(table, table->clickedRow, False);
 
1246
                setRowSelected(table, row, True);
 
1247
                table->clickedRow = row;
 
1248
                table->dragging = 1;
 
1249
            } else {
 
1250
                table->dragging = 1;
 
1251
            }
 
1252
        }
 
1253
        break;
 
1254
 
 
1255
    case MotionNotify:
 
1256
        if (table->dragging && event->xmotion.y >= 0) {
 
1257
            WMRect rect = getVisibleRect(table);
 
1258
 
 
1259
            row = (event->xmotion.y + rect.pos.y)/table->rowHeight;
 
1260
            if (table->clickedRow != row && row >= 0 && row < table->rows) {
 
1261
                setRowSelected(table, table->clickedRow, False);
 
1262
                setRowSelected(table, row, True);
 
1263
                table->clickedRow = row;
 
1264
            }
 
1265
        }
 
1266
        break;
 
1267
 
 
1268
    case ButtonRelease:
 
1269
        if (event->xbutton.button == Button1) {
 
1270
            if (table->action)
 
1271
                (*table->action)(table, table->clientData);
 
1272
            WMPostNotificationName(WMTableViewSelectionDidChangeNotification,
 
1273
                                   table, NULL);
 
1274
            table->dragging = 0;
 
1275
        }
 
1276
        break;
 
1277
    }
 
1278
}
 
1279
 
 
1280
 
 
1281
static void
 
1282
handleEvents(XEvent *event, void *data)
 
1283
{
 
1284
    WMTableView *table = (WMTableView*)data;
 
1285
    WMScreen *scr = WMWidgetScreen(table);
 
1286
 
 
1287
    switch (event->type) {
 
1288
    case Expose:
 
1289
        W_DrawRelief(scr, W_VIEW_DRAWABLE(table->view), 0, 0,
 
1290
                     W_VIEW_WIDTH(table->view), W_VIEW_HEIGHT(table->view),
 
1291
                     WRSunken);
 
1292
        break;
 
1293
    }
 
1294
}
 
1295
 
 
1296
 
 
1297
static void
 
1298
handleResize(W_ViewDelegate *self, WMView *view)
 
1299
{
 
1300
    reorganizeInterior(view->self);
 
1301
}
 
1302
 
 
1303
 
 
1304
static void
 
1305
reorganizeInterior(WMTableView *table)
 
1306
{
 
1307
    int width;
 
1308
    int height;
 
1309
    WMSize size = getTotalSize(table);
 
1310
    WMView *view = table->view;
 
1311
    int vw, vh;
 
1312
    int hsThickness, vsThickness;
 
1313
 
 
1314
    if (table->vscroll)
 
1315
        vsThickness = WMWidgetWidth(table->vscroll);
 
1316
    if (table->hscroll)
 
1317
        hsThickness = WMWidgetHeight(table->hscroll);
 
1318
 
 
1319
    width = W_VIEW_WIDTH(view) - 2;
 
1320
    height = W_VIEW_HEIGHT(view) - 3;
 
1321
 
 
1322
    height -= table->headerHeight; /* table header */
 
1323
 
 
1324
    if (table->corner)
 
1325
        WMResizeWidget(table->corner, 20, table->headerHeight);
 
1326
 
 
1327
    WMMoveWidget(table->vscroll, 1, table->headerHeight + 1);
 
1328
    WMResizeWidget(table->vscroll, 20, height + 1);
 
1329
 
 
1330
    if (table->hscroll) {
 
1331
        WMMoveWidget(table->hscroll, vsThickness, W_VIEW_HEIGHT(view) - hsThickness - 1);
 
1332
        WMResizeWidget(table->hscroll, width-(vsThickness+1), hsThickness);
 
1333
    }
 
1334
 
 
1335
    if (table->header)
 
1336
        WMResizeWidget(table->header, width-(vsThickness+1), table->headerHeight);
 
1337
 
 
1338
    if (table->viewBuffer) {
 
1339
        WMReleasePixmap(table->viewBuffer);
 
1340
        table->viewBuffer = NULL;
 
1341
    }
 
1342
 
 
1343
    width -= vsThickness;
 
1344
    height -= hsThickness;
 
1345
 
 
1346
 
 
1347
    vw = WMIN(size.width, width);
 
1348
    vh = WMIN(size.height, height);
 
1349
 
 
1350
    W_MoveView(table->tableView, vsThickness+1, 1+table->headerHeight+1);
 
1351
    W_ResizeView(table->tableView, WMAX(vw, 1), WMAX(vh, 1)+1);
 
1352
 
 
1353
    adjustScrollers(table);
 
1354
 
 
1355
    repaintTable(table);
 
1356
}
 
1357
 
 
1358
 
 
1359
static void
 
1360
rearrangeHeader(WMTableView *table)
 
1361
{
 
1362
    int width;
 
1363
    int count;
 
1364
    int i;
 
1365
    /*WMRect rect = WMGetScrollViewVisibleRect(table->scrollView);*/
 
1366
 
 
1367
    width = 0;
 
1368
 
 
1369
    count = WMGetArrayItemCount(table->columns);
 
1370
    for (i = 0; i < count; i++) {
 
1371
        WMTableColumn *column = WMGetFromArray(table->columns, i);
 
1372
        WMView *splitter = WMGetFromArray(table->splitters, i);
 
1373
 
 
1374
        WMMoveWidget(column->titleW, width, 0);
 
1375
        WMResizeWidget(column->titleW, column->width-1, table->headerHeight);
 
1376
 
 
1377
        width += column->width;
 
1378
        W_MoveView(splitter, width-1, 0);
 
1379
    }
 
1380
 
 
1381
    wassertr(table->delegate && table->delegate->numberOfRows);
 
1382
 
 
1383
    table->rows = table->delegate->numberOfRows(table->delegate, table);
 
1384
 
 
1385
    table->tableWidth = width + 1;
 
1386
 
 
1387
    handleResize(table->view->delegate, table->view);
 
1388
}
 
1389