3
#include <WINGs/WINGsP.h>
4
#include <X11/cursorfont.h>
6
#include "wtableview.h"
9
const char *WMTableViewSelectionDidChangeNotification = "WMTableViewSelectionDidChangeNotification";
12
struct W_TableColumn {
22
WMTableColumnDelegate *delegate;
29
static void handleResize(W_ViewDelegate *self, WMView *view);
31
static void rearrangeHeader(WMTableView *table);
33
static WMRange rowsInRect(WMTableView *table, WMRect rect);
37
WMCreateTableColumn(char *title)
39
WMTableColumn *col = wmalloc(sizeof(WMTableColumn));
49
col->title = wstrdup(title);
61
WMSetTableColumnId(WMTableColumn *column, void *id)
68
WMGetTableColumnId(WMTableColumn *column)
75
WMSetTableColumnWidth(WMTableColumn *column, unsigned width)
77
if (column->maxWidth == 0)
78
column->width = WMAX(column->minWidth, width);
80
column->width = WMAX(column->minWidth, WMIN(column->maxWidth, width));
83
rearrangeHeader(column->table);
89
WMSetTableColumnDelegate(WMTableColumn *column, WMTableColumnDelegate *delegate)
91
column->delegate = delegate;
96
WMSetTableColumnConstraints(WMTableColumn *column, unsigned minWidth,
99
wassertr(maxWidth == 0 || minWidth <= maxWidth);
101
column->minWidth = minWidth;
102
column->maxWidth = maxWidth;
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);
112
WMSetTableColumnEditable(WMTableColumn *column, Bool flag)
114
column->editable = ((flag==0) ? 0 : 1);
119
WMGetTableColumnTableView(WMTableColumn *column)
121
return column->table;
138
WMPixmap *viewBuffer;
143
WMArray *selectedRows;
154
Cursor splitterCursor;
158
WMTableViewDelegate *delegate;
168
unsigned headerHeight;
173
unsigned drawsGrid:1;
174
unsigned canSelectRow:1;
175
unsigned canSelectMultiRows:1;
176
unsigned canDeselectRow:1;
178
unsigned int hasVScroller:1;
179
unsigned int hasHScroller:1;
182
static W_Class tableClass = 0;
185
static W_ViewDelegate viewDelegate = {
195
static void reorganizeInterior(WMTableView *table);
198
static void handleEvents(XEvent *event, void *data);
199
static void handleTableEvents(XEvent *event, void *data);
200
static void repaintTable(WMTableView *table);
203
getTotalSize(WMTableView *table)
208
/* get width from columns */
210
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
211
WMTableColumn *column;
213
column = WMGetFromArray(table->columns, i);
215
size.width += column->width;
218
/* get height from rows */
219
size.height = table->rows * table->rowHeight;
226
getVisibleRect(WMTableView *table)
228
WMSize size = getTotalSize(table);
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);
235
rect.size.height = size.height;
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);
243
rect.size.width = size.width;
252
scrollToPoint(WMTableView *table, int x, int y)
254
WMSize size = getTotalSize(table);
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));
266
WMSetScrollerParameters(table->hscroll, value, prop);
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));
278
WMSetScrollerParameters(table->vscroll, value, prop);
282
if (table->editingRow >= 0) {
283
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
284
WMTableColumn *column;
286
column = WMGetFromArray(table->columns, i);
288
if (column->delegate && column->delegate->beginCellEdit)
289
(*column->delegate->beginCellEdit)(column->delegate, column,
299
adjustScrollers(WMTableView *table)
301
WMSize size = getTotalSize(table);
302
WMSize vsize = WMGetViewSize(table->tableView);
306
if (table->hscroll) {
307
if (size.width <= vsize.width) {
311
oprop = WMGetScrollerKnobProportion(table->hscroll);
314
ovalue = WMGetScrollerValue(table->hscroll);
316
prop = (float)vsize.width/(float)size.width;
317
value = prop*ovalue / oprop;
319
WMSetScrollerParameters(table->hscroll, value, prop);
322
if (table->vscroll) {
323
if (size.height <= vsize.height) {
327
oprop = WMGetScrollerKnobProportion(table->vscroll);
330
ovalue = WMGetScrollerValue(table->vscroll);
332
prop = (float)vsize.height/(float)size.height;
333
value = prop*ovalue / oprop;
335
WMSetScrollerParameters(table->vscroll, value, prop);
341
doScroll(WMWidget *self, void *data)
343
WMTableView *table = (WMTableView*)data;
347
WMSize ts = getTotalSize(table);
349
value = WMGetScrollerValue(self);
351
if (table->hscroll == (WMScroller *)self) {
352
vpsize = W_VIEW_WIDTH(table->tableView);
355
vpsize = W_VIEW_HEIGHT(table->tableView);
359
switch (WMGetScrollerHitPart(self)) {
360
case WSDecrementWheel:
361
case WSDecrementLine:
362
value -= (float)table->rowHeight / size;
365
WMSetScrollerParameters(self, value,
366
WMGetScrollerKnobProportion(self));
370
case WSIncrementWheel:
371
case WSIncrementLine:
372
value += (float)table->rowHeight / size;
375
WMSetScrollerParameters(self, value,
376
WMGetScrollerKnobProportion(self));
384
case WSDecrementPage:
385
value -= vpsize / size;
388
WMSetScrollerParameters(self, value,
389
WMGetScrollerKnobProportion(self));
393
case WSIncrementPage:
394
value += vpsize / size;
397
WMSetScrollerParameters(self, value,
398
WMGetScrollerKnobProportion(self));
408
if (table->editingRow >= 0) {
410
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
411
WMTableColumn *column;
413
column = WMGetFromArray(table->columns, i);
415
if (column->delegate && column->delegate->beginCellEdit)
416
(*column->delegate->beginCellEdit)(column->delegate, column,
422
if (table->hscroll == self) {
425
WMRect rect = getVisibleRect(table);
427
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
428
WMTableColumn *column;
431
column = WMGetFromArray(table->columns, i);
433
WMMoveWidget(column->titleW, x - rect.pos.x, 0);
435
x += W_VIEW_WIDTH(WMWidgetView(column->titleW)) + 1;
437
splitter = WMGetFromArray(table->splitters, i);
438
W_MoveView(splitter, x - rect.pos.x - 1, 0);
445
splitterHandler(XEvent *event, void *data)
447
WMTableColumn *column = (WMTableColumn*)data;
448
WMTableView *table = column->table;
452
WMScreen *scr = WMWidgetScreen(table);
454
Display *dpy = WMScreenDisplay(scr);
455
int h = WMWidgetHeight(table) - 22;
456
Window w = WMViewXID(table->view);
458
pos = WMGetViewPosition(WMWidgetView(column->titleW));
460
offsX = pos.x + column->width;
464
XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h);
469
WMMaskEvent(dpy, ButtonMotionMask|ButtonReleaseMask, &ev);
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;
481
cx = offsX + ev.xmotion.x;
483
XDrawLine(dpy, w, gc, ox+20, 0, ox+20, h);
484
XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h);
488
column->width = cx - pos.x;
494
XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h);
495
rearrangeHeader(table);
501
realizeTable(void *data, WMNotification *notif)
508
WMCreateTableView(WMWidget *parent)
510
WMTableView *table = wmalloc(sizeof(WMTableView));
511
WMScreen *scr = WMWidgetScreen(parent);
513
memset(table, 0, sizeof(WMTableView));
516
tableClass = W_RegisterUserWidget();
518
table->widgetClass = tableClass;
520
table->view = W_CreateView(W_VIEW(parent));
523
table->view->self = table;
525
table->view->delegate = &viewDelegate;
527
table->headerHeight = 20;
529
table->hscroll = WMCreateScroller(table);
530
WMSetScrollerAction(table->hscroll, doScroll, table);
531
WMMoveWidget(table->hscroll, 1, 2+table->headerHeight);
532
WMMapWidget(table->hscroll);
534
table->hasHScroller = 1;
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);
542
table->hasVScroller = 1;
544
table->header = WMCreateFrame(table);
545
WMMoveWidget(table->header, 22, 2);
546
WMMapWidget(table->header);
547
WMSetFrameRelief(table->header, WRFlat);
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);
557
table->tableView = W_CreateView(table->view);
558
if (!table->tableView)
560
table->tableView->self = table;
561
W_MapView(table->tableView);
563
WMAddNotificationObserver(realizeTable, table, WMViewRealizedNotification,
566
table->tableView->flags.dontCompressExpose = 1;
568
table->gridColor = WMCreateNamedColor(scr, "#cccccc", False);
569
/* table->gridColor = WMGrayColor(scr);*/
574
table->backColor = WMWhiteColor(scr);
576
gcv.foreground = WMColorPixel(table->gridColor);
578
gcv.line_style = LineOnOffDash;
579
table->gridGC = XCreateGC(WMScreenDisplay(scr), W_DRAWABLE(scr),
583
table->editingRow = -1;
584
table->clickedRow = -1;
586
table->drawsGrid = 1;
587
table->rowHeight = 16;
589
table->tableWidth = 1;
591
table->columns = WMCreateArray(4);
592
table->splitters = WMCreateArray(4);
594
table->selectedRows = WMCreateArray(16);
596
table->splitterCursor = XCreateFontCursor(WMScreenDisplay(scr),
597
XC_sb_h_double_arrow);
599
table->canSelectRow = 1;
601
WMCreateEventHandler(table->view, ExposureMask|StructureNotifyMask,
602
handleEvents, table);
604
WMCreateEventHandler(table->tableView, ExposureMask|ButtonPressMask|
605
ButtonReleaseMask|ButtonMotionMask,
606
handleTableEvents, table);
608
WMResizeWidget(table, 50, 50);
613
if (table->tableView)
614
W_DestroyView(table->tableView);
616
W_DestroyView(table->view);
623
WMAddTableViewColumn(WMTableView *table, WMTableColumn *column)
625
WMScreen *scr = WMWidgetScreen(table);
627
column->table = table;
629
WMAddToArray(table->columns, column);
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);
646
WMView *splitter = W_CreateView(WMWidgetView(table->header));
648
W_SetViewBackgroundColor(splitter, WMWhiteColor(scr));
650
if (W_VIEW_REALIZED(table->view))
651
W_RealizeView(splitter);
653
W_ResizeView(splitter, 2, table->headerHeight);
656
W_SetViewCursor(splitter, table->splitterCursor);
657
WMCreateEventHandler(splitter, ButtonPressMask|ButtonReleaseMask,
658
splitterHandler, column);
660
WMAddToArray(table->splitters, splitter);
663
rearrangeHeader(table);
668
WMSetTableViewHeaderHeight(WMTableView *table, unsigned height)
670
table->headerHeight = height;
672
handleResize(NULL, table->view);
677
WMSetTableViewDelegate(WMTableView *table, WMTableViewDelegate *delegate)
679
table->delegate = delegate;
684
WMSetTableViewAction(WMTableView *table, WMAction *action, void *clientData)
686
table->action = action;
688
table->clientData = clientData;
693
WMGetTableViewClickedColumn(WMTableView *table)
695
return table->clickedColumn;
700
WMGetTableViewClickedRow(WMTableView *table)
702
return table->clickedRow;
707
WMGetTableViewSelectedRows(WMTableView *table)
709
return table->selectedRows;
714
WMGetTableViewDocumentView(WMTableView *table)
716
return table->tableView;
721
WMTableViewDataForCell(WMTableView *table, WMTableColumn *column, int row)
723
return (*table->delegate->valueForCell)(table->delegate, column, row);
728
WMSetTableViewDataForCell(WMTableView *table, WMTableColumn *column, int row,
731
(*table->delegate->setValueForCell)(table->delegate, column, row, data);
736
WMTableViewRectForCell(WMTableView *table, WMTableColumn *column, int row)
742
rect.pos.y = row * table->rowHeight;
743
rect.size.height = table->rowHeight;
745
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
747
col = WMGetFromArray(table->columns, i);
750
rect.size.width = col->width;
754
rect.pos.x += col->width;
758
WMRect r = getVisibleRect(table);
760
rect.pos.y -= r.pos.y;
761
rect.pos.x -= r.pos.x;
769
WMSetTableViewDataSource(WMTableView *table, void *source)
771
table->dataSource = source;
776
WMGetTableViewDataSource(WMTableView *table)
778
return table->dataSource;
784
WMSetTableViewHasHorizontalScroller(WMTableView *tPtr, Bool flag)
787
if (tPtr->hasHScroller)
789
tPtr->hasHScroller = 1;
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);
797
if (W_VIEW_REALIZED(tPtr->view)) {
798
WMRealizeWidget(tPtr->hscroll);
801
reorganizeInterior(tPtr);
803
WMMapWidget(tPtr->hscroll);
805
if (!tPtr->hasHScroller)
807
tPtr->hasHScroller = 0;
809
WMUnmapWidget(tPtr->hscroll);
810
WMDestroyWidget(tPtr->hscroll);
811
tPtr->hscroll = NULL;
813
reorganizeInterior(tPtr);
818
/* not supported by now */
820
WMSetTableViewHasVerticalScroller(WMTableView *tPtr, Bool flag)
823
if (tPtr->hasVScroller)
825
tPtr->hasVScroller = 1;
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);
833
if (W_VIEW_REALIZED(tPtr->view)) {
834
WMRealizeWidget(tPtr->vscroll);
837
reorganizeInterior(tPtr);
839
WMMapWidget(tPtr->vscroll);
841
if (!tPtr->hasVScroller)
843
tPtr->hasVScroller = 0;
845
WMUnmapWidget(tPtr->vscroll);
846
WMDestroyWidget(tPtr->vscroll);
847
tPtr->vscroll = NULL;
849
reorganizeInterior(tPtr);
855
WMSetTableViewBackgroundColor(WMTableView *table, WMColor *color)
857
W_SetViewBackgroundColor(table->tableView, color);
859
if (table->backColor)
860
WMReleaseColor(table->backColor);
862
table->backColor = WMRetainColor(color);
869
WMSetTableViewGridColor(WMTableView *table, WMColor *color)
871
WMReleaseColor(table->gridColor);
872
table->gridColor = WMRetainColor(color);
873
XSetForeground(WMScreenDisplay(WMWidgetScreen(table)), table->gridGC,
874
WMColorPixel(color));
881
WMSetTableViewRowHeight(WMTableView *table, int height)
883
table->rowHeight = height;
890
WMScrollTableViewRowToVisible(WMTableView *table, int row)
892
WMScroller *scroller;
897
rect = getVisibleRect(table);
898
range = rowsInRect(table, rect);
900
scroller = table->vscroll;
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;
909
tmp = table->rows*table->rowHeight - rect.size.height;
910
newY = WMAX(0, WMIN(newY, tmp));
912
scrollToPoint(table, rect.pos.x, newY);
918
drawGrid(WMTableView *table, WMRect rect)
920
WMScreen *scr = WMWidgetScreen(table);
921
Display *dpy = WMScreenDisplay(scr);
926
Drawable d = WMGetPixmapXID(table->viewBuffer);
927
GC gc = table->gridGC;
932
XSetDashes(dpy, gc, 0, dashl, 1);
934
y1 = (rect.pos.y/table->rowHeight - 1)*table->rowHeight;
935
y2 = y1 + (rect.size.height/table->rowHeight+2)*table->rowHeight;
938
y2 = W_VIEW_HEIGHT(table->tableView);
941
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
942
WMTableColumn *column;
944
XDrawLine(dpy, d, gc, xx, y1, xx, y2);
946
column = WMGetFromArray(table->columns, i);
949
XDrawLine(dpy, d, gc, xx, y1, xx, y2);
952
x2 = rect.size.width;
957
XSetDashes(dpy, gc, (rect.pos.x&1), dashl, 1);
960
y1 = -rect.pos.y%table->rowHeight;
961
y2 = y1 + rect.size.height + table->rowHeight;
963
for (i = y1; i <= y2; i += table->rowHeight) {
964
XDrawLine(dpy, d, gc, x1, i, x2, i);
970
columnsInRect(WMTableView *table, WMRect rect)
972
WMTableColumn *column;
975
int totalColumns = WMGetArrayItemCount(table->columns);
980
for (i = 0; i < totalColumns; i++) {
981
column = WMGetFromArray(table->columns, i);
983
if (rect.pos.x >= pos && rect.pos.x < pos + column->width) {
989
if (pos > rect.pos.x + rect.size.width) {
994
pos += column->width;
996
range.count = WMAX(1, WMIN(range.count, totalColumns - range.position));
1002
rowsInRect(WMTableView *table, WMRect rect)
1005
int rh = table->rowHeight;
1008
dif = rect.pos.y % rh;
1010
range.position = WMAX(0, (rect.pos.y - dif) / rh);
1011
range.count = WMAX(1, WMIN((rect.size.height + dif) / rh, table->rows));
1018
drawRow(WMTableView *table, int row, WMRect clipRect)
1021
WMRange cols = columnsInRect(table, clipRect);
1022
WMTableColumn *column;
1023
Drawable d = WMGetPixmapXID(table->viewBuffer);
1025
for (i = cols.position; i < cols.position+cols.count; i++) {
1026
column = WMGetFromArray(table->columns, i);
1028
if (!column->delegate || !column->delegate->drawCell)
1031
if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound)
1032
(*column->delegate->drawSelectedCell)(column->delegate, column, row, d);
1034
(*column->delegate->drawCell)(column->delegate, column, row, d);
1041
drawFullRow(WMTableView *table, int row)
1044
WMTableColumn *column;
1045
Drawable d = WMGetPixmapXID(table->viewBuffer);
1047
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
1048
column = WMGetFromArray(table->columns, i);
1050
if (!column->delegate || !column->delegate->drawCell)
1053
if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound)
1054
(*column->delegate->drawSelectedCell)(column->delegate, column, row, d);
1056
(*column->delegate->drawCell)(column->delegate, column, row, d);
1063
setRowSelected(WMTableView *table, unsigned row, Bool flag)
1067
if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound) {
1069
WMRemoveFromArray(table->selectedRows, (void*)row);
1074
WMAddToArray(table->selectedRows, (void*)row);
1078
if (repaint && row < table->rows) {
1079
/*drawFullRow(table, row);*/
1080
repaintTable(table);
1086
repaintTable(WMTableView *table)
1090
WMScreen *scr = WMWidgetScreen(table);
1093
if (!table->delegate || !W_VIEW_REALIZED(table->view))
1096
wassertr(table->delegate->numberOfRows);
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);
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));
1111
rect = getVisibleRect(table);
1113
if (table->drawsGrid) {
1114
drawGrid(table, rect);
1117
rows = rowsInRect(table, rect);
1118
for (i = rows.position;
1119
i < WMIN(rows.position+rows.count + 1, table->rows);
1121
drawRow(table, i, rect);
1124
XSetWindowBackgroundPixmap(scr->display, table->tableView->window,
1125
WMGetPixmapXID(table->viewBuffer));
1126
XClearWindow(scr->display, table->tableView->window);
1131
stopRowEdit(WMTableView *table, int row)
1134
WMTableColumn *column;
1136
table->editingRow = -1;
1137
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
1138
column = WMGetFromArray(table->columns, i);
1140
if (column->delegate && column->delegate->endCellEdit)
1141
(*column->delegate->endCellEdit)(column->delegate, column, row);
1148
WMEditTableViewRow(WMTableView *table, int row)
1151
WMTableColumn *column;
1153
if (table->editingRow >= 0) {
1154
stopRowEdit(table, table->editingRow);
1157
table->editingRow = row;
1162
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
1163
column = WMGetFromArray(table->columns, i);
1165
if (column->delegate && column->delegate->beginCellEdit)
1166
(*column->delegate->beginCellEdit)(column->delegate, column, row);
1172
WMSelectTableViewRow(WMTableView *table, int row)
1174
if (table->clickedRow >= 0)
1175
setRowSelected(table, table->clickedRow, False);
1177
if (row >= table->rows) {
1181
setRowSelected(table, row, True);
1182
table->clickedRow = row;
1185
(*table->action)(table, table->clientData);
1186
WMPostNotificationName(WMTableViewSelectionDidChangeNotification,
1192
WMReloadTableView(WMTableView *table)
1194
if (table->editingRow >= 0)
1195
stopRowEdit(table, table->editingRow);
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) */
1200
WMEmptyArray(table->selectedRows);
1202
if (table->clickedRow >= 0) {
1204
(*table->action)(table, table->clientData);
1205
WMPostNotificationName(WMTableViewSelectionDidChangeNotification,
1207
table->clickedRow = -1;
1210
if (table->delegate && table->delegate->numberOfRows) {
1213
rows = (*table->delegate->numberOfRows)(table->delegate, table);
1215
if (rows != table->rows) {
1217
handleResize(table->view->delegate, table->view);
1219
repaintTable(table);
1226
WMNoteTableViewNumberOfRowsChanged(WMTableView *table)
1228
WMReloadTableView(table);
1233
handleTableEvents(XEvent *event, void *data)
1235
WMTableView *table = (WMTableView*)data;
1238
switch (event->type) {
1240
if (event->xbutton.button == Button1) {
1241
WMRect rect = getVisibleRect(table);
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;
1250
table->dragging = 1;
1256
if (table->dragging && event->xmotion.y >= 0) {
1257
WMRect rect = getVisibleRect(table);
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;
1269
if (event->xbutton.button == Button1) {
1271
(*table->action)(table, table->clientData);
1272
WMPostNotificationName(WMTableViewSelectionDidChangeNotification,
1274
table->dragging = 0;
1282
handleEvents(XEvent *event, void *data)
1284
WMTableView *table = (WMTableView*)data;
1285
WMScreen *scr = WMWidgetScreen(table);
1287
switch (event->type) {
1289
W_DrawRelief(scr, W_VIEW_DRAWABLE(table->view), 0, 0,
1290
W_VIEW_WIDTH(table->view), W_VIEW_HEIGHT(table->view),
1298
handleResize(W_ViewDelegate *self, WMView *view)
1300
reorganizeInterior(view->self);
1305
reorganizeInterior(WMTableView *table)
1309
WMSize size = getTotalSize(table);
1310
WMView *view = table->view;
1312
int hsThickness, vsThickness;
1315
vsThickness = WMWidgetWidth(table->vscroll);
1317
hsThickness = WMWidgetHeight(table->hscroll);
1319
width = W_VIEW_WIDTH(view) - 2;
1320
height = W_VIEW_HEIGHT(view) - 3;
1322
height -= table->headerHeight; /* table header */
1325
WMResizeWidget(table->corner, 20, table->headerHeight);
1327
WMMoveWidget(table->vscroll, 1, table->headerHeight + 1);
1328
WMResizeWidget(table->vscroll, 20, height + 1);
1330
if (table->hscroll) {
1331
WMMoveWidget(table->hscroll, vsThickness, W_VIEW_HEIGHT(view) - hsThickness - 1);
1332
WMResizeWidget(table->hscroll, width-(vsThickness+1), hsThickness);
1336
WMResizeWidget(table->header, width-(vsThickness+1), table->headerHeight);
1338
if (table->viewBuffer) {
1339
WMReleasePixmap(table->viewBuffer);
1340
table->viewBuffer = NULL;
1343
width -= vsThickness;
1344
height -= hsThickness;
1347
vw = WMIN(size.width, width);
1348
vh = WMIN(size.height, height);
1350
W_MoveView(table->tableView, vsThickness+1, 1+table->headerHeight+1);
1351
W_ResizeView(table->tableView, WMAX(vw, 1), WMAX(vh, 1)+1);
1353
adjustScrollers(table);
1355
repaintTable(table);
1360
rearrangeHeader(WMTableView *table)
1365
/*WMRect rect = WMGetScrollViewVisibleRect(table->scrollView);*/
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);
1374
WMMoveWidget(column->titleW, width, 0);
1375
WMResizeWidget(column->titleW, column->width-1, table->headerHeight);
1377
width += column->width;
1378
W_MoveView(splitter, width-1, 0);
1381
wassertr(table->delegate && table->delegate->numberOfRows);
1383
table->rows = table->delegate->numberOfRows(table->delegate, table);
1385
table->tableWidth = width + 1;
1387
handleResize(table->view->delegate, table->view);