From 22ae4f5a3cae5d3bbf1af8ba4eb987a7e2345d8c Mon Sep 17 00:00:00 2001 From: kojima Date: Thu, 17 May 2001 22:30:38 +0000 Subject: [PATCH] fixed tableview overflow bug --- WINGs/Extras/test.c | 11 +- WINGs/Extras/wtabledelegates.c | 154 +++++++------ WINGs/Extras/wtableview.c | 475 +++++++++++++++++++++++++++++++---------- WINGs/Extras/wtableview.h | 7 +- 4 files changed, 449 insertions(+), 198 deletions(-) diff --git a/WINGs/Extras/test.c b/WINGs/Extras/test.c index d3ebae0b..f3e6a877 100644 --- a/WINGs/Extras/test.c +++ b/WINGs/Extras/test.c @@ -30,7 +30,11 @@ void *valueForCell(WMTableViewDelegate *self, WMTableColumn *column, int row) int i; if (col1[0] == 0) { for (i = 0; i < 20; i++) { - col1[i] = "teste"; + char buf[128]; + + sprintf(buf, "Test row %i", i); + + col1[i] = wstrdup(buf); col2[i] = 0; } } @@ -82,13 +86,14 @@ main(int argc, char **argv) scr = WMOpenScreen(NULL); + XSynchronize(WMScreenDisplay(scr), 1); win = WMCreateWindow(scr, "eweq"); WMResizeWidget(win, 400, 200); WMMapWidget(win); table = WMCreateTableView(win); - WMResizeWidget(table, 400, 200); + WMSetViewExpandsToParent(WMWidgetView(table), 10, 10, 10, 10); WMSetTableViewBackgroundColor(table, WMWhiteColor(scr)); /*WMSetTableViewGridColor(table, WMGrayColor(scr));*/ WMSetTableViewHeaderHeight(table, 20); @@ -119,10 +124,8 @@ main(int argc, char **argv) WMAddTableViewColumn(table, col); WMSetTableColumnDelegate(col, colDeleg); WMSetTableColumnId(col, (void*)2); - WMMapWidget(table); WMRealizeWidget(win); WMScreenMainLoop(scr); - } diff --git a/WINGs/Extras/wtabledelegates.c b/WINGs/Extras/wtabledelegates.c index 89f9c0f7..67e0a31d 100644 --- a/WINGs/Extras/wtabledelegates.c +++ b/WINGs/Extras/wtabledelegates.c @@ -10,8 +10,8 @@ typedef struct { WMTableView *table; WMFont *font; GC gc; - GC selGc; - GC selTextGc; + GC selGC; + GC textGC; } StringData; @@ -27,8 +27,8 @@ typedef struct { WMTableView *table; WMFont *font; GC gc; - GC selGc; - GC selTextGc; + GC selGC; + GC textGC; } StringEditorData; @@ -39,8 +39,8 @@ typedef struct { char **options; int count; GC gc; - GC selGc; - GC selTextGc; + GC selGC; + GC textGC; } EnumSelectorData; @@ -49,6 +49,7 @@ typedef struct { WMTableView *table; Bool state; GC gc; + GC selGC; } BooleanSwitchData; @@ -74,11 +75,9 @@ static void stringDraw(WMScreen *scr, Drawable d, GC gc, XSetClipRectangles(dpy, gc, 0, 0, rects, 1, YXSorted); if (!selected) { - XClearArea(dpy, d, rects[0].x, rects[0].y, - rects[0].width, rects[0].height, - False); - - WMDrawString(scr, d, gc, font, x, y, + XFillRectangles(dpy, d, gc, rects, 1); + + WMDrawString(scr, d, stgc, font, x, y, data, strlen(data)); } else { XFillRectangles(dpy, d, sgc, rects, 1); @@ -92,7 +91,7 @@ static void stringDraw(WMScreen *scr, Drawable d, GC gc, -static void pixmapDraw(WMScreen *scr, Drawable d, GC gc, +static void pixmapDraw(WMScreen *scr, Drawable d, GC gc, GC sgc, WMPixmap *pixmap, WMRect rect, Bool selected) { int x, y; @@ -107,10 +106,8 @@ static void pixmapDraw(WMScreen *scr, Drawable d, GC gc, XSetClipRectangles(dpy, gc, 0, 0, rects, 1, YXSorted); if (!selected) { - XClearArea(dpy, d, rects[0].x, rects[0].y, - rects[0].width, rects[0].height, - False); - + XFillRectangles(dpy, d, gc, rects, 1); + if (pixmap) { size = WMGetPixmapSize(pixmap); x = rect.pos.x + (rect.size.width - size.width) / 2; @@ -119,7 +116,7 @@ static void pixmapDraw(WMScreen *scr, Drawable d, GC gc, WMDrawPixmap(pixmap, d, x, y); } } else { - XFillRectangles(dpy, d, gc, rects, 1); + XFillRectangles(dpy, d, sgc, rects, 1); if (pixmap) { size = WMGetPixmapSize(pixmap); @@ -139,14 +136,13 @@ static void pixmapDraw(WMScreen *scr, Drawable d, GC gc, static void SECellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { StringEditorData *strdata = (StringEditorData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); - stringDraw(WMWidgetScreen(table), - WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, strdata->selGc, strdata->selTextGc, strdata->font, + stringDraw(WMWidgetScreen(table), d, + strdata->gc, strdata->selGC, strdata->textGC, strdata->font, WMTableViewDataForCell(table, column, row), WMTableViewRectForCell(table, column, row), False); @@ -154,14 +150,13 @@ static void SECellPainter(WMTableColumnDelegate *self, static void selectedSECellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { StringEditorData *strdata = (StringEditorData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); - stringDraw(WMWidgetScreen(table), - WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, strdata->selGc, strdata->selTextGc, strdata->font, + stringDraw(WMWidgetScreen(table), d, + strdata->gc, strdata->selGC, strdata->textGC, strdata->font, WMTableViewDataForCell(table, column, row), WMTableViewRectForCell(table, column, row), True); @@ -208,9 +203,9 @@ WMTableColumnDelegate *WTCreateStringEditorDelegate(WMTableView *parent) 0, 0); data->table = parent; data->font = WMSystemFontOfSize(scr, 12); - data->selGc = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); - data->selTextGc = WMColorGC(WMBlackColor(scr)); - data->gc = WMColorGC(WMBlackColor(scr)); + data->selGC = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); + data->textGC = WMColorGC(WMBlackColor(scr)); + data->gc = WMColorGC(WMWhiteColor(scr)); delegate->data = data; delegate->drawCell = SECellPainter; @@ -227,15 +222,14 @@ WMTableColumnDelegate *WTCreateStringEditorDelegate(WMTableView *parent) static void ESCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { EnumSelectorData *strdata = (EnumSelectorData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); int i = (int)WMTableViewDataForCell(table, column, row); - stringDraw(WMWidgetScreen(table), - WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, strdata->selGc, strdata->selTextGc, strdata->font, + stringDraw(WMWidgetScreen(table), d, + strdata->gc, strdata->selGC, strdata->textGC, strdata->font, strdata->options[i], WMTableViewRectForCell(table, column, row), False); @@ -243,15 +237,14 @@ static void ESCellPainter(WMTableColumnDelegate *self, static void selectedESCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { EnumSelectorData *strdata = (EnumSelectorData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); int i = (int)WMTableViewDataForCell(table, column, row); - stringDraw(WMWidgetScreen(table), - WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, strdata->selGc, strdata->selTextGc, strdata->font, + stringDraw(WMWidgetScreen(table), d, + strdata->gc, strdata->selGC, strdata->textGC, strdata->font, strdata->options[i], WMTableViewRectForCell(table, column, row), True); @@ -301,9 +294,9 @@ WMTableColumnDelegate *WTCreateEnumSelectorDelegate(WMTableView *parent) 0, 0); data->table = parent; data->font = WMSystemFontOfSize(scr, 12); - data->selGc = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); - data->selTextGc = WMColorGC(WMBlackColor(scr)); - data->gc = WMColorGC(WMBlackColor(scr)); + data->selGC = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); + data->textGC = WMColorGC(WMBlackColor(scr)); + data->gc = WMColorGC(WMWhiteColor(scr)); data->count = 0; data->options = NULL; @@ -342,7 +335,7 @@ void WTSetEnumSelectorOptions(WMTableColumnDelegate *delegate, /* ---------------------------------------------------------------------- */ static void BSCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { BooleanSwitchData *strdata = (BooleanSwitchData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); @@ -350,19 +343,19 @@ static void BSCellPainter(WMTableColumnDelegate *self, WMScreen *scr = WMWidgetScreen(table); if (i) { - pixmapDraw(scr, WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, WMGetSystemPixmap(scr, WSICheckMark), + pixmapDraw(scr, d, + strdata->gc, strdata->selGC, WMGetSystemPixmap(scr, WSICheckMark), WMTableViewRectForCell(table, column, row), False); } else { - pixmapDraw(scr, WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, NULL, + pixmapDraw(scr, d, + strdata->gc, strdata->selGC, NULL, WMTableViewRectForCell(table, column, row), False); } } static void selectedBSCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { BooleanSwitchData *strdata = (BooleanSwitchData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); @@ -370,12 +363,12 @@ static void selectedBSCellPainter(WMTableColumnDelegate *self, WMScreen *scr = WMWidgetScreen(table); if (i) { - pixmapDraw(scr, WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, WMGetSystemPixmap(scr, WSICheckMark), + pixmapDraw(scr, d, + strdata->gc, strdata->selGC, WMGetSystemPixmap(scr, WSICheckMark), WMTableViewRectForCell(table, column, row), True); } else { - pixmapDraw(scr, WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, NULL, + pixmapDraw(scr, d, + strdata->gc, strdata->selGC, NULL, WMTableViewRectForCell(table, column, row), True); } } @@ -428,7 +421,8 @@ WMTableColumnDelegate *WTCreateBooleanSwitchDelegate(WMTableView *parent) data->table = parent; color = WMCreateNamedColor(scr, SelectionColor, False); WMSetWidgetBackgroundColor(data->widget, color); - data->gc = WMColorGC(color); + data->gc = WMColorGC(WMWhiteColor(scr)); + data->selGC = WMColorGC(color); delegate->data = data; delegate->drawCell = BSCellPainter; @@ -444,14 +438,13 @@ WMTableColumnDelegate *WTCreateBooleanSwitchDelegate(WMTableView *parent) static void SCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { StringData *strdata = (StringData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); - stringDraw(WMWidgetScreen(table), - WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, strdata->selGc, strdata->selTextGc, strdata->font, + stringDraw(WMWidgetScreen(table), d, + strdata->gc, strdata->selGC, strdata->textGC, strdata->font, WMTableViewDataForCell(table, column, row), WMTableViewRectForCell(table, column, row), False); @@ -459,14 +452,13 @@ static void SCellPainter(WMTableColumnDelegate *self, static void selectedSCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { StringData *strdata = (StringData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); - stringDraw(WMWidgetScreen(table), - WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, strdata->selGc, strdata->selTextGc, strdata->font, + stringDraw(WMWidgetScreen(table), d, + strdata->gc, strdata->selGC, strdata->textGC, strdata->font, WMTableViewDataForCell(table, column, row), WMTableViewRectForCell(table, column, row), True); @@ -481,9 +473,9 @@ WMTableColumnDelegate *WTCreateStringDelegate(WMTableView *parent) data->table = parent; data->font = WMSystemFontOfSize(scr, 12); - data->selGc = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); - data->selTextGc = WMColorGC(WMBlackColor(scr)); - data->gc = WMColorGC(WMBlackColor(scr)); + data->selGC = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); + data->textGC = WMColorGC(WMBlackColor(scr)); + data->gc = WMColorGC(WMWhiteColor(scr)); delegate->data = data; delegate->drawCell = SCellPainter; @@ -499,14 +491,13 @@ WMTableColumnDelegate *WTCreateStringDelegate(WMTableView *parent) static void PCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { StringData *strdata = (StringData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); - pixmapDraw(WMWidgetScreen(table), - WMViewXID(WMGetTableViewDocumentView(table)), - strdata->selGc, + pixmapDraw(WMWidgetScreen(table), d, + strdata->gc, strdata->selGC, (WMPixmap*)WMTableViewDataForCell(table, column, row), WMTableViewRectForCell(table, column, row), False); @@ -514,14 +505,13 @@ static void PCellPainter(WMTableColumnDelegate *self, static void selectedPCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { StringData *strdata = (StringData*)self->data; WMTableView *table = WMGetTableColumnTableView(column); - pixmapDraw(WMWidgetScreen(table), - WMViewXID(WMGetTableViewDocumentView(table)), - strdata->selGc, + pixmapDraw(WMWidgetScreen(table), d, + strdata->gc, strdata->selGC, (WMPixmap*)WMTableViewDataForCell(table, column, row), WMTableViewRectForCell(table, column, row), True); @@ -535,7 +525,8 @@ WMTableColumnDelegate *WTCreatePixmapDelegate(WMTableView *table) StringData *data = wmalloc(sizeof(StringData)); data->table = table; - data->selGc = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); + data->selGC = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); + data->gc = WMColorGC(WMWhiteColor(scr)); delegate->data = data; delegate->drawCell = PCellPainter; @@ -550,7 +541,7 @@ WMTableColumnDelegate *WTCreatePixmapDelegate(WMTableView *table) /* ---------------------------------------------------------------------- */ -static void drawPSCell(WMTableColumnDelegate *self, +static void drawPSCell(WMTableColumnDelegate *self, Drawable d, WMTableColumn *column, int row, Bool selected) { StringData *strdata = (StringData*)self->data; @@ -576,31 +567,30 @@ static void drawPSCell(WMTableColumnDelegate *self, pixmapDraw(WMWidgetScreen(table), WMViewXID(WMGetTableViewDocumentView(table)), - strdata->selGc, pix, rect, + strdata->gc, strdata->selGC, pix, rect, selected); rect.pos.x += size.width-1; rect.size.width = owidth-size.width+1; } - stringDraw(WMWidgetScreen(table), - WMViewXID(WMGetTableViewDocumentView(table)), - strdata->gc, strdata->selGc, strdata->selTextGc, strdata->font, + stringDraw(WMWidgetScreen(table), d, + strdata->gc, strdata->selGC, strdata->textGC, strdata->font, str, rect, selected); } static void PSCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { - drawPSCell(self, column, row, False); + drawPSCell(self, d, column, row, False); } static void selectedPSCellPainter(WMTableColumnDelegate *self, - WMTableColumn *column, int row) + WMTableColumn *column, int row, Drawable d) { - drawPSCell(self, column, row, True); + drawPSCell(self, d, column, row, True); } @@ -612,9 +602,9 @@ WMTableColumnDelegate *WTCreatePixmapStringDelegate(WMTableView *parent) data->table = parent; data->font = WMSystemFontOfSize(scr, 12); - data->selGc = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); - data->selTextGc = WMColorGC(WMBlackColor(scr)); - data->gc = WMColorGC(WMBlackColor(scr)); + data->selGC = WMColorGC(WMCreateNamedColor(scr, SelectionColor, False)); + data->textGC = WMColorGC(WMBlackColor(scr)); + data->gc = WMColorGC(WMWhiteColor(scr)); delegate->data = data; delegate->drawCell = PSCellPainter; diff --git a/WINGs/Extras/wtableview.c b/WINGs/Extras/wtableview.c index 9792ad48..69a7fcbb 100644 --- a/WINGs/Extras/wtableview.c +++ b/WINGs/Extras/wtableview.c @@ -124,9 +124,12 @@ struct W_TableView { WMFrame *header; WMLabel *corner; - - WMScrollView *scrollView; + + WMScroller *hscroll; + WMScroller *vscroll; WMView *tableView; + + WMPixmap *viewBuffer; WMArray *columns; WMArray *splitters; @@ -136,6 +139,8 @@ struct W_TableView { int tableWidth; int rows; + + WMColor *backColor; GC gridGC; WMColor *gridColor; @@ -182,29 +187,225 @@ static W_ViewDelegate viewDelegate = { static void handleEvents(XEvent *event, void *data); static void handleTableEvents(XEvent *event, void *data); +static void repaintTable(WMTableView *table); - -static void scrollObserver(void *self, WMNotification *notif) +static WMSize getTotalSize(WMTableView *table) { - WMTableView *table = (WMTableView*)self; - WMRect rect; - int i, x; - - rect = WMGetScrollViewVisibleRect(table->scrollView); + WMSize size; + int i; - x = 0; + /* get width from columns */ + size.width = 0; for (i = 0; i < WMGetArrayItemCount(table->columns); i++) { WMTableColumn *column; - WMView *splitter; column = WMGetFromArray(table->columns, i); - WMMoveWidget(column->titleW, x - rect.pos.x, 0); - - x += W_VIEW_WIDTH(WMWidgetView(column->titleW)) + 1; - - splitter = WMGetFromArray(table->splitters, i); - W_MoveView(splitter, x - rect.pos.x - 1, 0); + size.width += column->width; + } + + /* get height from rows */ + size.height = table->rows * table->rowHeight; + + return size; +} + + +static WMRect getVisibleRect(WMTableView *table) +{ + WMSize size = getTotalSize(table); + WMRect rect; + + rect.size.height = size.height * WMGetScrollerKnobProportion(table->vscroll); + rect.size.width = size.width * WMGetScrollerKnobProportion(table->hscroll); + + rect.pos.x = (size.width - rect.size.width) * WMGetScrollerValue(table->hscroll); + rect.pos.y = (size.height - rect.size.height) * WMGetScrollerValue(table->vscroll); + + return rect; +} + + +static void scrollToPoint(WMTableView *table, int x, int y) +{ + WMSize size = getTotalSize(table); + int i; + float value, prop; + + if (size.width < W_VIEW_WIDTH(table->tableView)) { + prop = (float)size.width / (float)W_VIEW_WIDTH(table->tableView); + value = x * (float)(size.width - W_VIEW_WIDTH(table->tableView)); + } else { + prop = 1.0; + value = 0.0; + } + WMSetScrollerParameters(table->hscroll, value, prop); + + + if (size.height < W_VIEW_HEIGHT(table->tableView)) { + prop = (float)size.height / (float)W_VIEW_HEIGHT(table->tableView); + value = y * (float)(size.height - W_VIEW_HEIGHT(table->tableView)); + } else { + prop = 1.0; + value = 0.0; + } + WMSetScrollerParameters(table->vscroll, value, prop); + + + + if (table->editingRow >= 0) { + for (i = 0; i < WMGetArrayItemCount(table->columns); i++) { + WMTableColumn *column; + + column = WMGetFromArray(table->columns, i); + + if (column->delegate && column->delegate->beginCellEdit) + (*column->delegate->beginCellEdit)(column->delegate, column, + table->editingRow); + } + } + + repaintTable(table); +} + + +static void adjustScrollers(WMTableView *table) +{ + WMSize size = getTotalSize(table); + WMSize vsize = WMGetViewSize(table->tableView); + float prop, value; + float oprop, ovalue; + + if (size.width <= vsize.width) { + value = 0.0; + prop = 1.0; + } else { + oprop = WMGetScrollerKnobProportion(table->hscroll); + if (oprop == 0.0) + oprop = 1.0; + ovalue = WMGetScrollerValue(table->hscroll); + + prop = (float)vsize.width/(float)size.width; + value = prop*ovalue / oprop; + } + WMSetScrollerParameters(table->hscroll, value, prop); + + if (size.height <= vsize.height) { + value = 0.0; + prop = 1.0; + } else { + oprop = WMGetScrollerKnobProportion(table->vscroll); + oprop = WMGetScrollerKnobProportion(table->hscroll); + if (oprop == 0.0) + oprop = 1.0; + ovalue = WMGetScrollerValue(table->vscroll); + + prop = (float)vsize.height/(float)size.height; + value = prop*ovalue / oprop; + } + WMSetScrollerParameters(table->vscroll, value, prop); +} + + +static void doScroll(WMWidget *self, void *data) +{ + WMTableView *table = (WMTableView*)data; + float value; + float vpsize; + float size; + WMSize ts = getTotalSize(table); + + value = WMGetScrollerValue(self); + + if (table->hscroll == (WMScroller *)self) { + vpsize = W_VIEW_WIDTH(table->tableView); + size = ts.width; + } else { + vpsize = W_VIEW_HEIGHT(table->tableView); + size = ts.height; + } + + switch (WMGetScrollerHitPart(self)) { + case WSDecrementWheel: + case WSDecrementLine: + value -= (float)table->rowHeight / size; + if (value < 0) + value = 0.0; + WMSetScrollerParameters(self, value, + WMGetScrollerKnobProportion(self)); + repaintTable(table); + break; + + case WSIncrementWheel: + case WSIncrementLine: + value += (float)table->rowHeight / size; + if (value > 1.0) + value = 1.0; + WMSetScrollerParameters(self, value, + WMGetScrollerKnobProportion(self)); + repaintTable(table); + break; + + case WSKnob: + repaintTable(table); + break; + + case WSDecrementPage: + value -= vpsize / size; + if (value < 0.0) + value = 0.0; + WMSetScrollerParameters(self, value, + WMGetScrollerKnobProportion(self)); + repaintTable(table); + break; + + case WSIncrementPage: + value += vpsize / size; + if (value > 1.0) + value = 1.0; + WMSetScrollerParameters(self, value, + WMGetScrollerKnobProportion(self)); + repaintTable(table); + break; + + + case WSNoPart: + case WSKnobSlot: + break; + } + + if (table->editingRow >= 0) { + int i; + for (i = 0; i < WMGetArrayItemCount(table->columns); i++) { + WMTableColumn *column; + + column = WMGetFromArray(table->columns, i); + + if (column->delegate && column->delegate->beginCellEdit) + (*column->delegate->beginCellEdit)(column->delegate, column, + table->editingRow); + } + } + + + if (table->hscroll == self) { + int x = 0; + int i; + WMRect rect = getVisibleRect(table); + + for (i = 0; i < WMGetArrayItemCount(table->columns); i++) { + WMTableColumn *column; + WMView *splitter; + + column = WMGetFromArray(table->columns, i); + + WMMoveWidget(column->titleW, x - rect.pos.x, 0); + + x += W_VIEW_WIDTH(WMWidgetView(column->titleW)) + 1; + + splitter = WMGetFromArray(table->splitters, i); + W_MoveView(splitter, x - rect.pos.x - 1, 0); + } } } @@ -259,10 +460,16 @@ static void splitterHandler(XEvent *event, void *data) } XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h); - rearrangeHeader(table); + rearrangeHeader(table); + repaintTable(table); } +static void realizeTable(void *data, WMNotification *notif) +{ + repaintTable(data); +} + WMTableView *WMCreateTableView(WMWidget *parent) { @@ -285,22 +492,18 @@ WMTableView *WMCreateTableView(WMWidget *parent) table->headerHeight = 20; - table->scrollView = WMCreateScrollView(table); - if (!table->scrollView) - goto error; - WMResizeWidget(table->scrollView, 10, 10); - WMSetScrollViewHasVerticalScroller(table->scrollView, True); - WMSetScrollViewHasHorizontalScroller(table->scrollView, True); - { - WMScroller *scroller; - scroller = WMGetScrollViewHorizontalScroller(table->scrollView); - WMAddNotificationObserver(scrollObserver, table, - WMScrollerDidScrollNotification, - scroller); - } - WMMoveWidget(table->scrollView, 1, 2+table->headerHeight); - WMMapWidget(table->scrollView); + table->hscroll = WMCreateScroller(table); + WMSetScrollerAction(table->hscroll, doScroll, table); + WMMoveWidget(table->hscroll, 1, 2+table->headerHeight); + WMMapWidget(table->hscroll); + table->vscroll = WMCreateScroller(table); + WMSetScrollerArrowsPosition(table->vscroll, WSAMaxEnd); + WMSetScrollerAction(table->vscroll, doScroll, table); + WMMoveWidget(table->vscroll, 1, 2+table->headerHeight); + WMMapWidget(table->vscroll); + + table->header = WMCreateFrame(table); WMMoveWidget(table->header, 22, 2); WMMapWidget(table->header); @@ -314,13 +517,15 @@ WMTableView *WMCreateTableView(WMWidget *parent) WMSetWidgetBackgroundColor(table->corner, scr->darkGray); - table->tableView = W_CreateView(W_VIEW(parent)); + table->tableView = W_CreateView(table->view); if (!table->tableView) goto error; table->tableView->self = table; - W_ResizeView(table->tableView, 100, 1000); W_MapView(table->tableView); + WMAddNotificationObserver(realizeTable, table, WMViewRealizedNotification, + table->tableView); + table->tableView->flags.dontCompressExpose = 1; table->gridColor = WMCreateNamedColor(scr, "#cccccc", False); @@ -329,6 +534,8 @@ WMTableView *WMCreateTableView(WMWidget *parent) { XGCValues gcv; + table->backColor = WMWhiteColor(scr); + gcv.foreground = WMColorPixel(table->gridColor); gcv.dashes = 1; gcv.line_style = LineOnOffDash; @@ -341,8 +548,6 @@ WMTableView *WMCreateTableView(WMWidget *parent) table->drawsGrid = 1; table->rowHeight = 16; - - WMSetScrollViewLineScroll(table->scrollView, table->rowHeight); table->tableWidth = 1; @@ -363,13 +568,11 @@ WMTableView *WMCreateTableView(WMWidget *parent) ButtonReleaseMask|ButtonMotionMask, handleTableEvents, table); - WMSetScrollViewContentView(table->scrollView, table->tableView); + WMResizeWidget(table, 50, 50); return table; error: - if (table->scrollView) - WMDestroyWidget(table->scrollView); if (table->tableView) W_DestroyView(table->tableView); if (table->view) @@ -409,7 +612,7 @@ void WMAddTableViewColumn(WMTableView *table, WMTableColumn *column) if (W_VIEW_REALIZED(table->view)) W_RealizeView(splitter); - W_ResizeView(splitter, 2, table->headerHeight-1); + W_ResizeView(splitter, 2, table->headerHeight); W_MapView(splitter); W_SetViewCursor(splitter, table->splitterCursor); @@ -504,6 +707,14 @@ WMRect WMTableViewRectForCell(WMTableView *table, WMTableColumn *column, rect.pos.x += col->width; } + + { + WMRect r = getVisibleRect(table); + + rect.pos.y -= r.pos.y; + rect.pos.x -= r.pos.x; + } + return rect; } @@ -523,6 +734,13 @@ void *WMGetTableViewDataSource(WMTableView *table) void WMSetTableViewBackgroundColor(WMTableView *table, WMColor *color) { W_SetViewBackgroundColor(table->tableView, color); + + if (table->backColor) + WMReleaseColor(table->backColor); + + table->backColor = WMRetainColor(color); + + repaintTable(table); } @@ -532,6 +750,7 @@ void WMSetTableViewGridColor(WMTableView *table, WMColor *color) table->gridColor = WMRetainColor(color); XSetForeground(WMScreenDisplay(WMWidgetScreen(table)), table->gridGC, WMColorPixel(color)); + repaintTable(table); } @@ -540,7 +759,7 @@ void WMSetTableViewRowHeight(WMTableView *table, int height) { table->rowHeight = height; - WMRedisplayWidget(table); + repaintTable(table); } @@ -551,10 +770,10 @@ void WMScrollTableViewRowToVisible(WMTableView *table, int row) WMRect rect; int newY, tmp; - rect = WMGetScrollViewVisibleRect(table->scrollView); + rect = getVisibleRect(table); range = rowsInRect(table, rect); - scroller = WMGetScrollViewVerticalScroller(table->scrollView); + scroller = table->vscroll; if (row < range.position) { newY = row * table->rowHeight - rect.size.height / 2; @@ -565,9 +784,10 @@ void WMScrollTableViewRowToVisible(WMTableView *table, int row) } tmp = table->rows*table->rowHeight - rect.size.height; newY = WMAX(0, WMIN(newY, tmp)); - WMScrollViewScrollPoint(table->scrollView, rect.pos.x, newY); + + scrollToPoint(table, rect.pos.x, newY); } - + static void drawGrid(WMTableView *table, WMRect rect) @@ -578,7 +798,7 @@ static void drawGrid(WMTableView *table, WMRect rect) int y1, y2; int x1, x2; int xx; - Drawable d = W_VIEW_DRAWABLE(table->tableView); + Drawable d = WMGetPixmapXID(table->viewBuffer); GC gc = table->gridGC; #if 0 @@ -592,21 +812,19 @@ static void drawGrid(WMTableView *table, WMRect rect) y1 = 0; y2 = W_VIEW_HEIGHT(table->tableView); - xx = 0; + xx = -rect.pos.x; for (i = 0; i < WMGetArrayItemCount(table->columns); i++) { WMTableColumn *column; - - if (xx >= rect.pos.x && xx <= rect.pos.x+rect.size.width) { - XDrawLine(dpy, d, gc, xx, y1, xx, y2); - } + + XDrawLine(dpy, d, gc, xx, y1, xx, y2); + column = WMGetFromArray(table->columns, i); xx += column->width; } XDrawLine(dpy, d, gc, xx, y1, xx, y2); - - x1 = rect.pos.x; - x2 = WMIN(x1 + rect.size.width, xx); + x1 = 0; + x2 = rect.size.width; if (x2 <= x1) return; @@ -614,7 +832,7 @@ static void drawGrid(WMTableView *table, WMRect rect) XSetDashes(dpy, gc, (rect.pos.x&1), dashl, 1); #endif - y1 = rect.pos.y - rect.pos.y%table->rowHeight; + y1 = -rect.pos.y%table->rowHeight; y2 = y1 + rect.size.height + table->rowHeight; for (i = y1; i <= y2; i += table->rowHeight) { @@ -673,16 +891,18 @@ static void drawRow(WMTableView *table, int row, WMRect clipRect) int i; WMRange cols = columnsInRect(table, clipRect); WMTableColumn *column; + Drawable d = WMGetPixmapXID(table->viewBuffer); for (i = cols.position; i < cols.position+cols.count; i++) { column = WMGetFromArray(table->columns, i); - wassertr(column->delegate && column->delegate->drawCell); - + if (!column->delegate || !column->delegate->drawCell) + continue; + if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound) - (*column->delegate->drawSelectedCell)(column->delegate, column, row); + (*column->delegate->drawSelectedCell)(column->delegate, column, row, d); else - (*column->delegate->drawCell)(column->delegate, column, row); + (*column->delegate->drawCell)(column->delegate, column, row, d); } } @@ -691,16 +911,18 @@ static void drawFullRow(WMTableView *table, int row) { int i; WMTableColumn *column; - + Drawable d = WMGetPixmapXID(table->viewBuffer); + for (i = 0; i < WMGetArrayItemCount(table->columns); i++) { column = WMGetFromArray(table->columns, i); - wassertr(column->delegate && column->delegate->drawCell); - + if (!column->delegate || !column->delegate->drawCell) + continue; + if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound) - (*column->delegate->drawSelectedCell)(column->delegate, column, row); + (*column->delegate->drawSelectedCell)(column->delegate, column, row, d); else - (*column->delegate->drawCell)(column->delegate, column, row); + (*column->delegate->drawCell)(column->delegate, column, row, d); } } @@ -721,34 +943,39 @@ static void setRowSelected(WMTableView *table, unsigned row, Bool flag) } } if (repaint && row < table->rows) { - drawFullRow(table, row); + //drawFullRow(table, row); + repaintTable(table); } } -static void repaintTable(WMTableView *table, int x, int y, - int width, int height) +static void repaintTable(WMTableView *table) { WMRect rect; WMRange rows; + WMScreen *scr = WMWidgetScreen(table); int i; - wassertr(table->delegate && table->delegate->numberOfRows); - i = (*table->delegate->numberOfRows)(table->delegate, table); - - if (i != table->rows) { - table->rows = i; - W_ResizeView(table->tableView, table->tableWidth, - table->rows * table->rowHeight + 1); - } - - - if (x >= table->tableWidth-1) + if (!table->delegate || !W_VIEW_REALIZED(table->view)) return; - rect.pos = wmkpoint(x,y); - rect.size = wmksize(width, height); + wassertr(table->delegate->numberOfRows); + if (!table->viewBuffer) { + table->viewBuffer = WMCreatePixmap(scr, + W_VIEW_WIDTH(table->tableView), + W_VIEW_HEIGHT(table->tableView), + WMScreenDepth(scr), 0); + } + + XFillRectangle(scr->display, + WMGetPixmapXID(table->viewBuffer), + WMColorGC(table->backColor), 0, 0, + W_VIEW_WIDTH(table->tableView), + W_VIEW_HEIGHT(table->tableView)); + + rect = getVisibleRect(table); + if (table->drawsGrid) { drawGrid(table, rect); } @@ -759,6 +986,10 @@ static void repaintTable(WMTableView *table, int x, int y, i++) { drawRow(table, i, rect); } + + XSetWindowBackgroundPixmap(scr->display, table->tableView->window, + WMGetPixmapXID(table->viewBuffer)); + XClearWindow(scr->display, table->tableView->window); } @@ -822,11 +1053,11 @@ void WMSelectTableViewRow(WMTableView *table, int row) void WMReloadTableView(WMTableView *table) { - WMRect rect = WMGetScrollViewVisibleRect(table->scrollView); + WMRect rect = getVisibleRect(table); if (table->editingRow >= 0) stopRowEdit(table, table->editingRow); - + /* when this is called, nothing in the table can be assumed to be * like the last time we accessed it (ie, rows might have disappeared) */ @@ -841,8 +1072,18 @@ void WMReloadTableView(WMTableView *table) table, NULL); } - repaintTable(table, 0, 0, - W_VIEW_WIDTH(table->tableView), rect.size.height); + if (table->delegate && table->delegate->numberOfRows) { + int rows; + + rows = (*table->delegate->numberOfRows)(table->delegate, table); + + if (rows != table->rows) { + table->rows = rows; + handleResize(table->delegate, table->view); + } else { + repaintTable(table); + } + } } @@ -860,19 +1101,25 @@ static void handleTableEvents(XEvent *event, void *data) switch (event->type) { case ButtonPress: if (event->xbutton.button == Button1) { - row = event->xbutton.y/table->rowHeight; + WMRect rect = getVisibleRect(table); + + row = (event->xbutton.y + rect.pos.y)/table->rowHeight; if (row != table->clickedRow) { setRowSelected(table, table->clickedRow, False); setRowSelected(table, row, True); table->clickedRow = row; table->dragging = 1; + } else { + table->dragging = 1; } } break; case MotionNotify: if (table->dragging && event->xmotion.y >= 0) { - row = event->xmotion.y/table->rowHeight; + WMRect rect = getVisibleRect(table); + + row = (event->xmotion.y + rect.pos.y)/table->rowHeight; if (table->clickedRow != row && row >= 0 && row < table->rows) { setRowSelected(table, table->clickedRow, False); setRowSelected(table, row, True); @@ -890,11 +1137,6 @@ static void handleTableEvents(XEvent *event, void *data) table->dragging = 0; } break; - - case Expose: - repaintTable(table, event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); - break; } } @@ -909,13 +1151,6 @@ static void handleEvents(XEvent *event, void *data) W_DrawRelief(scr, W_VIEW_DRAWABLE(table->view), 0, 0, W_VIEW_WIDTH(table->view), W_VIEW_HEIGHT(table->view), WRSunken); - - if (event->xexpose.serial == 0) { - WMRect rect = WMGetScrollViewVisibleRect(table->scrollView); - - repaintTable(table, rect.pos.x, rect.pos.y, - rect.size.width, rect.size.height); - } break; } } @@ -926,21 +1161,44 @@ static void handleResize(W_ViewDelegate *self, WMView *view) int width; int height; WMTableView *table = view->self; + WMSize size = getTotalSize(table); + WMScreen *scr = WMWidgetScreen(table); + int vw, vh; width = W_VIEW_WIDTH(view) - 2; height = W_VIEW_HEIGHT(view) - 3; - - height -= table->headerHeight; /* table header */ + height -= table->headerHeight; /* table header */ + if (table->corner) WMResizeWidget(table->corner, 20, table->headerHeight); + + WMMoveWidget(table->vscroll, 1, table->headerHeight + 1); + WMResizeWidget(table->vscroll, 20, height + 1); + + WMMoveWidget(table->hscroll, 20, W_VIEW_HEIGHT(view) - 20 - 1); + WMResizeWidget(table->hscroll, width-20+1, 20); - if (table->scrollView) { - WMMoveWidget(table->scrollView, 1, table->headerHeight + 2); - WMResizeWidget(table->scrollView, width, height); - } if (table->header) WMResizeWidget(table->header, width - 21, table->headerHeight); + + if (table->viewBuffer) { + WMReleasePixmap(table->viewBuffer); + table->viewBuffer = NULL; + } + + width -= 20; + height -= 20; + + vw = WMIN(size.width, width); + vh = WMIN(size.height, height); + + W_MoveView(table->tableView, 21, 1+table->headerHeight+1); + W_ResizeView(table->tableView, WMAX(vw, 1), WMAX(vh, 1)); + + adjustScrollers(table); + + repaintTable(table); } @@ -969,8 +1227,7 @@ static void rearrangeHeader(WMTableView *table) table->rows = table->delegate->numberOfRows(table->delegate, table); - W_ResizeView(table->tableView, width+1, - table->rows * table->rowHeight + 1); - - table->tableWidth = width + 1; + table->tableWidth = width + 1; + + handleResize(table->delegate, table->view); } diff --git a/WINGs/Extras/wtableview.h b/WINGs/Extras/wtableview.h index 0c0a1033..1ee852f9 100644 --- a/WINGs/Extras/wtableview.h +++ b/WINGs/Extras/wtableview.h @@ -17,10 +17,11 @@ extern const char *WMTableViewSelectionDidChangeNotification; typedef struct WMTableColumnDelegate { void *data; - void (*drawCell)(struct WMTableColumnDelegate *self, WMTableColumn *column, - int row); + void (*drawCell)(struct WMTableColumnDelegate *self, + WMTableColumn *column, int row, Drawable d); void (*drawSelectedCell)(struct WMTableColumnDelegate *self, - WMTableColumn *column, int row); + WMTableColumn *column, int row, Drawable d); + void (*beginCellEdit)(struct WMTableColumnDelegate *self, WMTableColumn *column, int row); void (*endCellEdit)(struct WMTableColumnDelegate *self, WMTableColumn *column, -- 2.11.4.GIT