Files
wmaker/WINGs/Extras/wtableview.c
T

1390 lines
32 KiB
C
Raw Normal View History

2000-11-12 03:29:53 +00:00
#include <WINGs/WINGsP.h>
2000-11-12 03:29:53 +00:00
#include <X11/cursorfont.h>
#include "wtableview.h"
2000-12-21 04:46:20 +00:00
2001-01-02 14:17:26 +00:00
const char *WMTableViewSelectionDidChangeNotification = "WMTableViewSelectionDidChangeNotification";
2000-12-21 04:46:20 +00:00
2000-11-12 03:29:53 +00:00
struct W_TableColumn {
WMTableView *table;
WMWidget *titleW;
char *title;
int width;
int minWidth;
int maxWidth;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
void *id;
WMTableColumnDelegate *delegate;
unsigned resizable:1;
unsigned editable:1;
};
static void handleResize(W_ViewDelegate *self, WMView *view);
2001-01-02 14:17:26 +00:00
static void rearrangeHeader(WMTableView *table);
static WMRange rowsInRect(WMTableView *table, WMRect rect);
2000-11-12 03:29:53 +00:00
2004-10-12 21:28:27 +00:00
WMTableColumn*
WMCreateTableColumn(char *title)
2000-11-12 03:29:53 +00:00
{
WMTableColumn *col = wmalloc(sizeof(WMTableColumn));
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
col->table = NULL;
col->titleW = NULL;
col->width = 50;
col->minWidth = 5;
col->maxWidth = 0;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
col->id = NULL;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
col->title = wstrdup(title);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
col->delegate = NULL;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
col->resizable = 1;
col->editable = 0;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
return col;
}
2004-10-12 21:28:27 +00:00
void
WMSetTableColumnId(WMTableColumn *column, void *id)
2000-11-12 03:29:53 +00:00
{
column->id = id;
}
2004-10-12 21:28:27 +00:00
void*
WMGetTableColumnId(WMTableColumn *column)
2000-11-12 03:29:53 +00:00
{
return column->id;
}
2004-10-12 21:28:27 +00:00
void
WMSetTableColumnWidth(WMTableColumn *column, unsigned width)
2000-11-12 03:29:53 +00:00
{
if (column->maxWidth == 0)
2004-10-12 21:28:27 +00:00
column->width = WMAX(column->minWidth, width);
2000-11-12 03:29:53 +00:00
else
2004-10-12 21:28:27 +00:00
column->width = WMAX(column->minWidth, WMIN(column->maxWidth, width));
2001-01-02 14:17:26 +00:00
2000-11-12 03:29:53 +00:00
if (column->table) {
2004-10-12 21:28:27 +00:00
rearrangeHeader(column->table);
2000-11-12 03:29:53 +00:00
}
}
2004-10-12 21:28:27 +00:00
void
WMSetTableColumnDelegate(WMTableColumn *column, WMTableColumnDelegate *delegate)
2000-11-12 03:29:53 +00:00
{
column->delegate = delegate;
}
2004-10-12 21:28:27 +00:00
void
WMSetTableColumnConstraints(WMTableColumn *column, unsigned minWidth,
unsigned maxWidth)
2000-11-12 03:29:53 +00:00
{
wassertr(maxWidth == 0 || minWidth <= maxWidth);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
column->minWidth = minWidth;
column->maxWidth = maxWidth;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
if (column->width < column->minWidth)
2004-10-12 21:28:27 +00:00
WMSetTableColumnWidth(column, column->minWidth);
else if (column->width > column->maxWidth && column->maxWidth != 0)
2004-10-12 21:28:27 +00:00
WMSetTableColumnWidth(column, column->maxWidth);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
void
WMSetTableColumnEditable(WMTableColumn *column, Bool flag)
2000-11-12 03:29:53 +00:00
{
column->editable = ((flag==0) ? 0 : 1);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
WMTableView*
WMGetTableColumnTableView(WMTableColumn *column)
2000-11-12 03:29:53 +00:00
{
return column->table;
}
struct W_TableView {
W_Class widgetClass;
WMView *view;
WMFrame *header;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
WMLabel *corner;
2001-05-17 22:30:38 +00:00
WMScroller *hscroll;
WMScroller *vscroll;
2000-11-12 03:29:53 +00:00
WMView *tableView;
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
WMPixmap *viewBuffer;
2000-11-12 03:29:53 +00:00
WMArray *columns;
WMArray *splitters;
2000-12-21 04:46:20 +00:00
WMArray *selectedRows;
2000-11-12 03:29:53 +00:00
int tableWidth;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
int rows;
2001-05-17 22:30:38 +00:00
WMColor *backColor;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
GC gridGC;
WMColor *gridColor;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
Cursor splitterCursor;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
void *dataSource;
WMTableViewDelegate *delegate;
2001-01-02 14:17:26 +00:00
WMAction *action;
void *clientData;
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
void *clickedColumn;
int clickedRow;
2004-10-12 21:28:27 +00:00
int editingRow;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
unsigned headerHeight;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
unsigned rowHeight;
2001-01-02 14:17:26 +00:00
unsigned dragging:1;
2000-11-12 03:29:53 +00:00
unsigned drawsGrid:1;
2000-12-21 04:46:20 +00:00
unsigned canSelectRow:1;
unsigned canSelectMultiRows:1;
unsigned canDeselectRow:1;
unsigned int hasVScroller:1;
unsigned int hasHScroller:1;
2000-11-12 03:29:53 +00:00
};
static W_Class tableClass = 0;
static W_ViewDelegate viewDelegate = {
NULL,
2004-10-12 21:28:27 +00:00
NULL,
handleResize,
NULL,
NULL
2000-11-12 03:29:53 +00:00
};
static void reorganizeInterior(WMTableView *table);
2000-11-12 03:29:53 +00:00
static void handleEvents(XEvent *event, void *data);
static void handleTableEvents(XEvent *event, void *data);
2001-05-17 22:30:38 +00:00
static void repaintTable(WMTableView *table);
2000-11-12 03:29:53 +00:00
2004-10-12 21:28:27 +00:00
static WMSize
getTotalSize(WMTableView *table)
2000-11-12 03:29:53 +00:00
{
2001-05-17 22:30:38 +00:00
WMSize size;
int i;
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
/* get width from columns */
size.width = 0;
2000-11-12 03:29:53 +00:00
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
2004-10-12 21:28:27 +00:00
WMTableColumn *column;
column = WMGetFromArray(table->columns, i);
size.width += column->width;
2001-05-17 22:30:38 +00:00
}
/* get height from rows */
size.height = table->rows * table->rowHeight;
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
return size;
}
2004-10-12 21:28:27 +00:00
static WMRect
getVisibleRect(WMTableView *table)
2001-05-17 22:30:38 +00:00
{
WMSize size = getTotalSize(table);
WMRect rect;
2004-10-12 21:28:27 +00:00
if (table->vscroll) {
rect.size.height = size.height * WMGetScrollerKnobProportion(table->vscroll);
rect.pos.y = (size.height - rect.size.height) * WMGetScrollerValue(table->vscroll);
} else {
rect.size.height = size.height;
rect.pos.y = 0;
}
2004-10-12 21:28:27 +00:00
if (table->hscroll) {
rect.size.width = size.width * WMGetScrollerKnobProportion(table->hscroll);
rect.pos.x = (size.width - rect.size.width) * WMGetScrollerValue(table->hscroll);
} else {
rect.size.width = size.width;
rect.pos.x = 0;
}
2001-05-17 22:30:38 +00:00
return rect;
}
2004-10-12 21:28:27 +00:00
static void
scrollToPoint(WMTableView *table, int x, int y)
2001-05-17 22:30:38 +00:00
{
WMSize size = getTotalSize(table);
int i;
float value, prop;
2004-10-12 21:28:27 +00:00
if (table->hscroll) {
if (size.width > W_VIEW_WIDTH(table->tableView)) {
prop = (float)W_VIEW_WIDTH(table->tableView) / (float)size.width;
value = (float)x / (float)(size.width - W_VIEW_WIDTH(table->tableView));
} else {
prop = 1.0;
value = 0.0;
}
WMSetScrollerParameters(table->hscroll, value, prop);
2001-05-17 22:30:38 +00:00
}
if (table->vscroll) {
if (size.height > W_VIEW_HEIGHT(table->tableView)) {
prop = (float)W_VIEW_HEIGHT(table->tableView) / (float)size.height;
value = (float)y / (float)(size.height - W_VIEW_HEIGHT(table->tableView));
} else {
prop = 1.0;
value = 0.0;
}
WMSetScrollerParameters(table->vscroll, value, prop);
2001-05-17 22:30:38 +00:00
}
2001-05-18 17:07:18 +00:00
2001-05-17 22:30:38 +00:00
if (table->editingRow >= 0) {
2004-10-12 21:28:27 +00:00
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);
}
2001-05-17 22:30:38 +00:00
}
repaintTable(table);
}
2004-10-12 21:28:27 +00:00
static void
adjustScrollers(WMTableView *table)
2001-05-17 22:30:38 +00:00
{
WMSize size = getTotalSize(table);
WMSize vsize = WMGetViewSize(table->tableView);
float prop, value;
float oprop, ovalue;
if (table->hscroll) {
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);
2004-10-12 21:28:27 +00:00
prop = (float)vsize.width/(float)size.width;
value = prop*ovalue / oprop;
}
WMSetScrollerParameters(table->hscroll, value, prop);
2001-05-17 22:30:38 +00:00
}
if (table->vscroll) {
if (size.height <= vsize.height) {
value = 0.0;
prop = 1.0;
} else {
oprop = WMGetScrollerKnobProportion(table->vscroll);
if (oprop == 0.0)
2004-10-12 21:28:27 +00:00
oprop = 1.0;
ovalue = WMGetScrollerValue(table->vscroll);
2004-10-12 21:28:27 +00:00
prop = (float)vsize.height/(float)size.height;
value = prop*ovalue / oprop;
}
WMSetScrollerParameters(table->vscroll, value, prop);
2001-05-17 22:30:38 +00:00
}
}
2004-10-12 21:28:27 +00:00
static void
doScroll(WMWidget *self, void *data)
2001-05-17 22:30:38 +00:00
{
WMTableView *table = (WMTableView*)data;
float value;
float vpsize;
float size;
WMSize ts = getTotalSize(table);
value = WMGetScrollerValue(self);
if (table->hscroll == (WMScroller *)self) {
2004-10-12 21:28:27 +00:00
vpsize = W_VIEW_WIDTH(table->tableView);
size = ts.width;
2001-05-17 22:30:38 +00:00
} else {
2004-10-12 21:28:27 +00:00
vpsize = W_VIEW_HEIGHT(table->tableView);
size = ts.height;
2001-05-17 22:30:38 +00:00
}
switch (WMGetScrollerHitPart(self)) {
2004-10-12 21:28:27 +00:00
case WSDecrementWheel:
case WSDecrementLine:
value -= (float)table->rowHeight / size;
if (value < 0)
value = 0.0;
WMSetScrollerParameters(self, value,
WMGetScrollerKnobProportion(self));
repaintTable(table);
2001-05-17 22:30:38 +00:00
break;
2004-10-12 21:28:27 +00:00
case WSIncrementWheel:
case WSIncrementLine:
value += (float)table->rowHeight / size;
if (value > 1.0)
value = 1.0;
WMSetScrollerParameters(self, value,
WMGetScrollerKnobProportion(self));
repaintTable(table);
break;
2001-05-17 22:30:38 +00:00
2004-10-12 21:28:27 +00:00
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;
2001-05-17 22:30:38 +00:00
2004-10-12 21:28:27 +00:00
case WSNoPart:
case WSKnobSlot:
break;
2001-05-17 22:30:38 +00:00
}
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
if (table->editingRow >= 0) {
2004-10-12 21:28:27 +00:00
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);
}
2001-05-17 22:30:38 +00:00
}
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
if (table->hscroll == self) {
2004-10-12 21:28:27 +00:00
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);
}
2000-11-12 03:29:53 +00:00
}
}
2002-01-10 06:03:06 +00:00
static void
splitterHandler(XEvent *event, void *data)
2000-11-12 03:29:53 +00:00
{
WMTableColumn *column = (WMTableColumn*)data;
WMTableView *table = column->table;
2000-12-21 04:46:20 +00:00
int done = 0;
int cx, ox, offsX;
WMPoint pos;
WMScreen *scr = WMWidgetScreen(table);
GC gc = scr->ixorGC;
Display *dpy = WMScreenDisplay(scr);
int h = WMWidgetHeight(table) - 22;
Window w = WMViewXID(table->view);
2004-10-12 21:28:27 +00:00
pos = WMGetViewPosition(WMWidgetView(column->titleW));
offsX = pos.x + column->width;
2004-10-12 21:28:27 +00:00
ox = cx = offsX;
2004-10-12 21:28:27 +00:00
XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h);
2000-12-21 04:46:20 +00:00
while (!done) {
2004-10-12 21:28:27 +00:00
XEvent ev;
WMMaskEvent(dpy, ButtonMotionMask|ButtonReleaseMask, &ev);
switch (ev.type) {
case MotionNotify:
ox = cx;
if (column->width + ev.xmotion.x < column->minWidth)
cx = pos.x + column->minWidth;
else if (column->maxWidth > 0
&& column->width + ev.xmotion.x > column->maxWidth)
cx = pos.x + column->maxWidth;
else
cx = offsX + ev.xmotion.x;
XDrawLine(dpy, w, gc, ox+20, 0, ox+20, h);
XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h);
break;
case ButtonRelease:
column->width = cx - pos.x;
done = 1;
break;
}
2000-12-21 04:46:20 +00:00
}
2004-10-12 21:28:27 +00:00
XDrawLine(dpy, w, gc, cx+20, 0, cx+20, h);
2001-05-17 22:30:38 +00:00
rearrangeHeader(table);
repaintTable(table);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
static void
realizeTable(void *data, WMNotification *notif)
2001-05-17 22:30:38 +00:00
{
repaintTable(data);
}
2000-11-12 03:29:53 +00:00
2004-10-12 21:28:27 +00:00
WMTableView*
WMCreateTableView(WMWidget *parent)
2000-11-12 03:29:53 +00:00
{
WMTableView *table = wmalloc(sizeof(WMTableView));
WMScreen *scr = WMWidgetScreen(parent);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
memset(table, 0, sizeof(WMTableView));
if (!tableClass) {
2004-10-12 21:28:27 +00:00
tableClass = W_RegisterUserWidget();
2000-11-12 03:29:53 +00:00
}
table->widgetClass = tableClass;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
table->view = W_CreateView(W_VIEW(parent));
2004-10-12 21:28:27 +00:00
if (!table->view)
goto error;
2000-11-12 03:29:53 +00:00
table->view->self = table;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
table->view->delegate = &viewDelegate;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
table->headerHeight = 20;
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
table->hscroll = WMCreateScroller(table);
WMSetScrollerAction(table->hscroll, doScroll, table);
WMMoveWidget(table->hscroll, 1, 2+table->headerHeight);
WMMapWidget(table->hscroll);
2000-11-12 03:29:53 +00:00
table->hasHScroller = 1;
2001-05-17 22:30:38 +00:00
table->vscroll = WMCreateScroller(table);
WMSetScrollerArrowsPosition(table->vscroll, WSAMaxEnd);
WMSetScrollerAction(table->vscroll, doScroll, table);
WMMoveWidget(table->vscroll, 1, 2+table->headerHeight);
WMMapWidget(table->vscroll);
table->hasVScroller = 1;
2000-11-12 03:29:53 +00:00
table->header = WMCreateFrame(table);
WMMoveWidget(table->header, 22, 2);
WMMapWidget(table->header);
WMSetFrameRelief(table->header, WRFlat);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
table->corner = WMCreateLabel(table);
WMResizeWidget(table->corner, 20, table->headerHeight);
WMMoveWidget(table->corner, 2, 2);
WMMapWidget(table->corner);
WMSetLabelRelief(table->corner, WRRaised);
WMSetWidgetBackgroundColor(table->corner, scr->darkGray);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
2001-05-17 22:30:38 +00:00
table->tableView = W_CreateView(table->view);
2000-12-21 04:46:20 +00:00
if (!table->tableView)
2004-10-12 21:28:27 +00:00
goto error;
2000-12-21 04:46:20 +00:00
table->tableView->self = table;
W_MapView(table->tableView);
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
WMAddNotificationObserver(realizeTable, table, WMViewRealizedNotification,
2004-10-12 21:28:27 +00:00
table->tableView);
2000-11-12 03:29:53 +00:00
table->tableView->flags.dontCompressExpose = 1;
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
table->gridColor = WMCreateNamedColor(scr, "#cccccc", False);
2004-10-12 21:28:27 +00:00
/* table->gridColor = WMGrayColor(scr);*/
2000-11-12 03:29:53 +00:00
{
2004-10-12 21:28:27 +00:00
XGCValues gcv;
table->backColor = WMWhiteColor(scr);
gcv.foreground = WMColorPixel(table->gridColor);
gcv.dashes = 1;
gcv.line_style = LineOnOffDash;
table->gridGC = XCreateGC(WMScreenDisplay(scr), W_DRAWABLE(scr),
GCForeground, &gcv);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
table->editingRow = -1;
2001-01-02 14:17:26 +00:00
table->clickedRow = -1;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
table->drawsGrid = 1;
table->rowHeight = 16;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
table->tableWidth = 1;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
table->columns = WMCreateArray(4);
table->splitters = WMCreateArray(4);
2000-12-21 04:46:20 +00:00
table->selectedRows = WMCreateArray(16);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
table->splitterCursor = XCreateFontCursor(WMScreenDisplay(scr),
2004-10-12 21:28:27 +00:00
XC_sb_h_double_arrow);
2000-12-21 04:46:20 +00:00
table->canSelectRow = 1;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
WMCreateEventHandler(table->view, ExposureMask|StructureNotifyMask,
handleEvents, table);
2001-01-02 14:17:26 +00:00
WMCreateEventHandler(table->tableView, ExposureMask|ButtonPressMask|
2004-10-12 21:28:27 +00:00
ButtonReleaseMask|ButtonMotionMask,
2000-11-12 03:29:53 +00:00
handleTableEvents, table);
2001-05-17 22:30:38 +00:00
WMResizeWidget(table, 50, 50);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
return table;
2004-10-12 21:28:27 +00:00
error:
if (table->tableView)
W_DestroyView(table->tableView);
if (table->view)
W_DestroyView(table->view);
wfree(table);
return NULL;
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
void
WMAddTableViewColumn(WMTableView *table, WMTableColumn *column)
2000-11-12 03:29:53 +00:00
{
WMScreen *scr = WMWidgetScreen(table);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
column->table = table;
WMAddToArray(table->columns, column);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
if (!column->titleW) {
2004-10-12 21:28:27 +00:00
column->titleW = WMCreateLabel(table);
WMSetLabelRelief(column->titleW, WRRaised);
WMSetLabelFont(column->titleW, scr->boldFont);
WMSetLabelTextColor(column->titleW, scr->white);
WMSetWidgetBackgroundColor(column->titleW, scr->darkGray);
WMSetLabelText(column->titleW, column->title);
W_ReparentView(WMWidgetView(column->titleW),
WMWidgetView(table->header), 0, 0);
if (W_VIEW_REALIZED(table->view))
WMRealizeWidget(column->titleW);
WMMapWidget(column->titleW);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
{
2004-10-12 21:28:27 +00:00
WMView *splitter = W_CreateView(WMWidgetView(table->header));
W_SetViewBackgroundColor(splitter, WMWhiteColor(scr));
2000-11-12 03:29:53 +00:00
2004-10-12 21:28:27 +00:00
if (W_VIEW_REALIZED(table->view))
W_RealizeView(splitter);
2000-11-12 03:29:53 +00:00
2004-10-12 21:28:27 +00:00
W_ResizeView(splitter, 2, table->headerHeight);
W_MapView(splitter);
2004-10-12 21:28:27 +00:00
W_SetViewCursor(splitter, table->splitterCursor);
WMCreateEventHandler(splitter, ButtonPressMask|ButtonReleaseMask,
splitterHandler, column);
2000-11-12 03:29:53 +00:00
2004-10-12 21:28:27 +00:00
WMAddToArray(table->splitters, splitter);
2000-11-12 03:29:53 +00:00
}
2001-01-02 14:17:26 +00:00
rearrangeHeader(table);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
void
WMSetTableViewHeaderHeight(WMTableView *table, unsigned height)
2000-11-12 03:29:53 +00:00
{
table->headerHeight = height;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
handleResize(NULL, table->view);
}
2004-10-12 21:28:27 +00:00
void
WMSetTableViewDelegate(WMTableView *table, WMTableViewDelegate *delegate)
2000-11-12 03:29:53 +00:00
{
table->delegate = delegate;
}
2004-10-12 21:28:27 +00:00
void
WMSetTableViewAction(WMTableView *table, WMAction *action, void *clientData)
2001-01-02 14:17:26 +00:00
{
table->action = action;
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
table->clientData = clientData;
}
2004-10-12 21:28:27 +00:00
void*
WMGetTableViewClickedColumn(WMTableView *table)
2001-01-02 14:17:26 +00:00
{
return table->clickedColumn;
}
2004-10-12 21:28:27 +00:00
int
WMGetTableViewClickedRow(WMTableView *table)
2001-01-02 14:17:26 +00:00
{
return table->clickedRow;
}
2004-10-12 21:28:27 +00:00
WMArray*
WMGetTableViewSelectedRows(WMTableView *table)
{
return table->selectedRows;
}
2004-10-12 21:28:27 +00:00
WMView*
WMGetTableViewDocumentView(WMTableView *table)
2000-11-12 03:29:53 +00:00
{
return table->tableView;
}
2004-10-12 21:28:27 +00:00
void*
WMTableViewDataForCell(WMTableView *table, WMTableColumn *column, int row)
2000-11-12 03:29:53 +00:00
{
return (*table->delegate->valueForCell)(table->delegate, column, row);
}
2004-10-12 21:28:27 +00:00
void
WMSetTableViewDataForCell(WMTableView *table, WMTableColumn *column, int row,
void *data)
{
(*table->delegate->setValueForCell)(table->delegate, column, row, data);
}
2004-10-12 21:28:27 +00:00
WMRect
WMTableViewRectForCell(WMTableView *table, WMTableColumn *column, int row)
2000-11-12 03:29:53 +00:00
{
WMRect rect;
int i;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
rect.pos.x = 0;
rect.pos.y = row * table->rowHeight;
rect.size.height = table->rowHeight;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
2004-10-12 21:28:27 +00:00
WMTableColumn *col;
col = WMGetFromArray(table->columns, i);
if (col == column) {
rect.size.width = col->width;
break;
}
rect.pos.x += col->width;
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
{
2004-10-12 21:28:27 +00:00
WMRect r = getVisibleRect(table);
rect.pos.y -= r.pos.y;
rect.pos.x -= r.pos.x;
2001-05-17 22:30:38 +00:00
}
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
return rect;
}
2004-10-12 21:28:27 +00:00
void
WMSetTableViewDataSource(WMTableView *table, void *source)
2000-11-12 03:29:53 +00:00
{
table->dataSource = source;
}
2004-10-12 21:28:27 +00:00
void*
WMGetTableViewDataSource(WMTableView *table)
2000-11-12 03:29:53 +00:00
{
return table->dataSource;
}
2004-10-12 21:28:27 +00:00
void
WMSetTableViewHasHorizontalScroller(WMTableView *tPtr, Bool flag)
{
if (flag) {
2004-10-12 21:28:27 +00:00
if (tPtr->hasHScroller)
return;
tPtr->hasHScroller = 1;
tPtr->hscroll = WMCreateScroller(tPtr);
WMSetScrollerAction(tPtr->hscroll, doScroll, tPtr);
WMSetScrollerArrowsPosition(tPtr->hscroll, WSAMaxEnd);
/* make it a horiz. scroller */
WMResizeWidget(tPtr->hscroll, 1, 2);
if (W_VIEW_REALIZED(tPtr->view)) {
WMRealizeWidget(tPtr->hscroll);
}
reorganizeInterior(tPtr);
WMMapWidget(tPtr->hscroll);
} else {
2004-10-12 21:28:27 +00:00
if (!tPtr->hasHScroller)
return;
tPtr->hasHScroller = 0;
WMUnmapWidget(tPtr->hscroll);
WMDestroyWidget(tPtr->hscroll);
tPtr->hscroll = NULL;
reorganizeInterior(tPtr);
}
}
#if 0
/* not supported by now */
2004-10-12 21:28:27 +00:00
void
WMSetTableViewHasVerticalScroller(WMTableView *tPtr, Bool flag)
{
if (flag) {
2004-10-12 21:28:27 +00:00
if (tPtr->hasVScroller)
return;
tPtr->hasVScroller = 1;
tPtr->vscroll = WMCreateScroller(tPtr);
WMSetScrollerAction(tPtr->vscroll, doScroll, tPtr);
WMSetScrollerArrowsPosition(tPtr->vscroll, WSAMaxEnd);
/* make it a vert. scroller */
WMResizeWidget(tPtr->vscroll, 1, 2);
if (W_VIEW_REALIZED(tPtr->view)) {
WMRealizeWidget(tPtr->vscroll);
}
reorganizeInterior(tPtr);
WMMapWidget(tPtr->vscroll);
} else {
2004-10-12 21:28:27 +00:00
if (!tPtr->hasVScroller)
return;
tPtr->hasVScroller = 0;
WMUnmapWidget(tPtr->vscroll);
WMDestroyWidget(tPtr->vscroll);
tPtr->vscroll = NULL;
reorganizeInterior(tPtr);
}
}
#endif
2004-10-12 21:28:27 +00:00
void
WMSetTableViewBackgroundColor(WMTableView *table, WMColor *color)
2000-11-12 03:29:53 +00:00
{
W_SetViewBackgroundColor(table->tableView, color);
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
if (table->backColor)
2004-10-12 21:28:27 +00:00
WMReleaseColor(table->backColor);
2001-05-17 22:30:38 +00:00
table->backColor = WMRetainColor(color);
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
repaintTable(table);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
void
WMSetTableViewGridColor(WMTableView *table, WMColor *color)
2000-11-12 03:29:53 +00:00
{
WMReleaseColor(table->gridColor);
table->gridColor = WMRetainColor(color);
2004-10-12 21:28:27 +00:00
XSetForeground(WMScreenDisplay(WMWidgetScreen(table)), table->gridGC,
WMColorPixel(color));
2001-05-17 22:30:38 +00:00
repaintTable(table);
2000-11-12 03:29:53 +00:00
}
2000-12-21 04:46:20 +00:00
2004-10-12 21:28:27 +00:00
void
WMSetTableViewRowHeight(WMTableView *table, int height)
2001-01-02 14:17:26 +00:00
{
table->rowHeight = height;
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
repaintTable(table);
2001-01-02 14:17:26 +00:00
}
2004-10-12 21:28:27 +00:00
void
WMScrollTableViewRowToVisible(WMTableView *table, int row)
2001-01-02 14:17:26 +00:00
{
WMScroller *scroller;
WMRange range;
WMRect rect;
int newY, tmp;
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
rect = getVisibleRect(table);
2001-01-02 14:17:26 +00:00
range = rowsInRect(table, rect);
2001-05-17 22:30:38 +00:00
scroller = table->vscroll;
2001-01-02 14:17:26 +00:00
if (row < range.position) {
2004-10-12 21:28:27 +00:00
newY = row * table->rowHeight - rect.size.height / 2;
2001-01-02 14:17:26 +00:00
} else if (row >= range.position + range.count) {
2004-10-12 21:28:27 +00:00
newY = row * table->rowHeight - rect.size.height / 2;
2001-01-02 14:17:26 +00:00
} else {
2004-10-12 21:28:27 +00:00
return;
2001-01-02 14:17:26 +00:00
}
tmp = table->rows*table->rowHeight - rect.size.height;
newY = WMAX(0, WMIN(newY, tmp));
2001-05-17 22:30:38 +00:00
scrollToPoint(table, rect.pos.x, newY);
2001-01-02 14:17:26 +00:00
}
2001-05-17 22:30:38 +00:00
2001-01-02 14:17:26 +00:00
2004-10-12 21:28:27 +00:00
static void
drawGrid(WMTableView *table, WMRect rect)
2000-11-12 03:29:53 +00:00
{
WMScreen *scr = WMWidgetScreen(table);
Display *dpy = WMScreenDisplay(scr);
int i;
int y1, y2;
int x1, x2;
int xx;
2001-05-17 22:30:38 +00:00
Drawable d = WMGetPixmapXID(table->viewBuffer);
2000-11-12 03:29:53 +00:00
GC gc = table->gridGC;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
#if 0
char dashl[1] = {1};
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
XSetDashes(dpy, gc, 0, dashl, 1);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
y1 = (rect.pos.y/table->rowHeight - 1)*table->rowHeight;
y2 = y1 + (rect.size.height/table->rowHeight+2)*table->rowHeight;
#endif
y1 = 0;
y2 = W_VIEW_HEIGHT(table->tableView);
2001-05-17 22:30:38 +00:00
xx = -rect.pos.x;
2000-11-12 03:29:53 +00:00
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
2004-10-12 21:28:27 +00:00
WMTableColumn *column;
2001-05-17 22:30:38 +00:00
2004-10-12 21:28:27 +00:00
XDrawLine(dpy, d, gc, xx, y1, xx, y2);
2001-05-17 22:30:38 +00:00
2004-10-12 21:28:27 +00:00
column = WMGetFromArray(table->columns, i);
xx += column->width;
2000-11-12 03:29:53 +00:00
}
XDrawLine(dpy, d, gc, xx, y1, xx, y2);
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
x1 = 0;
x2 = rect.size.width;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
if (x2 <= x1)
2004-10-12 21:28:27 +00:00
return;
2000-11-12 03:29:53 +00:00
#if 0
XSetDashes(dpy, gc, (rect.pos.x&1), dashl, 1);
#endif
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
y1 = -rect.pos.y%table->rowHeight;
2000-11-12 03:29:53 +00:00
y2 = y1 + rect.size.height + table->rowHeight;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
for (i = y1; i <= y2; i += table->rowHeight) {
2004-10-12 21:28:27 +00:00
XDrawLine(dpy, d, gc, x1, i, x2, i);
}
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
static WMRange
columnsInRect(WMTableView *table, WMRect rect)
2000-11-12 03:29:53 +00:00
{
WMTableColumn *column;
int pos;
int i, found;
2000-11-12 03:29:53 +00:00
int totalColumns = WMGetArrayItemCount(table->columns);
WMRange range;
2004-10-12 21:28:27 +00:00
pos = 0;
found = 0;
2000-11-12 03:29:53 +00:00
for (i = 0; i < totalColumns; i++) {
2004-10-12 21:28:27 +00:00
column = WMGetFromArray(table->columns, i);
if (!found) {
if (rect.pos.x >= pos && rect.pos.x < pos + column->width) {
range.position = i;
range.count = 1;
found = 1;
2004-10-12 21:28:27 +00:00
}
} else {
if (pos > rect.pos.x + rect.size.width) {
break;
}
2004-10-12 21:28:27 +00:00
range.count++;
}
pos += column->width;
2000-11-12 03:29:53 +00:00
}
range.count = WMAX(1, WMIN(range.count, totalColumns - range.position));
return range;
}
2004-10-12 21:28:27 +00:00
static WMRange
rowsInRect(WMTableView *table, WMRect rect)
2000-11-12 03:29:53 +00:00
{
WMRange range;
int rh = table->rowHeight;
2001-01-02 14:17:26 +00:00
int dif;
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
dif = rect.pos.y % rh;
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
range.position = WMAX(0, (rect.pos.y - dif) / rh);
range.count = WMAX(1, WMIN((rect.size.height + dif) / rh, table->rows));
2000-11-12 03:29:53 +00:00
return range;
}
2004-10-12 21:28:27 +00:00
static void
drawRow(WMTableView *table, int row, WMRect clipRect)
2000-11-12 03:29:53 +00:00
{
int i;
WMRange cols = columnsInRect(table, clipRect);
WMTableColumn *column;
2001-05-17 22:30:38 +00:00
Drawable d = WMGetPixmapXID(table->viewBuffer);
2001-01-21 00:19:02 +00:00
2000-11-12 03:29:53 +00:00
for (i = cols.position; i < cols.position+cols.count; i++) {
2004-10-12 21:28:27 +00:00
column = WMGetFromArray(table->columns, i);
2000-11-12 03:29:53 +00:00
2004-10-12 21:28:27 +00:00
if (!column->delegate || !column->delegate->drawCell)
continue;
2001-05-17 22:30:38 +00:00
2004-10-12 21:28:27 +00:00
if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound)
(*column->delegate->drawSelectedCell)(column->delegate, column, row, d);
else
(*column->delegate->drawCell)(column->delegate, column, row, d);
2000-12-21 04:46:20 +00:00
}
}
#if 0
2004-10-12 21:28:27 +00:00
static void
drawFullRow(WMTableView *table, int row)
2000-12-21 04:46:20 +00:00
{
int i;
WMTableColumn *column;
2001-05-17 22:30:38 +00:00
Drawable d = WMGetPixmapXID(table->viewBuffer);
2000-12-21 04:46:20 +00:00
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
2004-10-12 21:28:27 +00:00
column = WMGetFromArray(table->columns, i);
2000-12-21 04:46:20 +00:00
2004-10-12 21:28:27 +00:00
if (!column->delegate || !column->delegate->drawCell)
continue;
2001-05-17 22:30:38 +00:00
2004-10-12 21:28:27 +00:00
if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound)
(*column->delegate->drawSelectedCell)(column->delegate, column, row, d);
else
(*column->delegate->drawCell)(column->delegate, column, row, d);
2000-12-21 04:46:20 +00:00
}
}
#endif
2000-12-21 04:46:20 +00:00
2004-10-12 21:28:27 +00:00
static void
setRowSelected(WMTableView *table, unsigned row, Bool flag)
2000-12-21 04:46:20 +00:00
{
int repaint = 0;
if (WMFindInArray(table->selectedRows, NULL, (void*)row) != WANotFound) {
2004-10-12 21:28:27 +00:00
if (!flag) {
WMRemoveFromArray(table->selectedRows, (void*)row);
repaint = 1;
}
2000-12-21 04:46:20 +00:00
} else {
2004-10-12 21:28:27 +00:00
if (flag) {
WMAddToArray(table->selectedRows, (void*)row);
repaint = 1;
}
2000-12-21 04:46:20 +00:00
}
2001-01-10 21:10:39 +00:00
if (repaint && row < table->rows) {
2004-10-12 21:28:27 +00:00
/*drawFullRow(table, row);*/
repaintTable(table);
2000-11-12 03:29:53 +00:00
}
}
2004-10-12 21:28:27 +00:00
static void
repaintTable(WMTableView *table)
2000-11-12 03:29:53 +00:00
{
WMRect rect;
WMRange rows;
2001-05-17 22:30:38 +00:00
WMScreen *scr = WMWidgetScreen(table);
2000-11-12 03:29:53 +00:00
int i;
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
if (!table->delegate || !W_VIEW_REALIZED(table->view))
2004-10-12 21:28:27 +00:00
return;
2001-05-17 22:30:38 +00:00
wassertr(table->delegate->numberOfRows);
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
if (!table->viewBuffer) {
2004-10-12 21:28:27 +00:00
table->viewBuffer = WMCreatePixmap(scr,
W_VIEW_WIDTH(table->tableView),
W_VIEW_HEIGHT(table->tableView),
WMScreenDepth(scr), 0);
2001-05-17 22:30:38 +00:00
}
XFillRectangle(scr->display,
2004-10-12 21:28:27 +00:00
WMGetPixmapXID(table->viewBuffer),
WMColorGC(table->backColor), 0, 0,
W_VIEW_WIDTH(table->tableView),
W_VIEW_HEIGHT(table->tableView));
2001-05-17 22:30:38 +00:00
rect = getVisibleRect(table);
2000-11-12 03:29:53 +00:00
if (table->drawsGrid) {
2004-10-12 21:28:27 +00:00
drawGrid(table, rect);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
rows = rowsInRect(table, rect);
2001-01-10 21:10:39 +00:00
for (i = rows.position;
2004-10-12 21:28:27 +00:00
i < WMIN(rows.position+rows.count + 1, table->rows);
i++) {
drawRow(table, i, rect);
2000-11-12 03:29:53 +00:00
}
2001-05-17 22:30:38 +00:00
XSetWindowBackgroundPixmap(scr->display, table->tableView->window,
2004-10-12 21:28:27 +00:00
WMGetPixmapXID(table->viewBuffer));
2001-05-17 22:30:38 +00:00
XClearWindow(scr->display, table->tableView->window);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
static void
stopRowEdit(WMTableView *table, int row)
2000-12-21 04:46:20 +00:00
{
int i;
WMTableColumn *column;
table->editingRow = -1;
2000-12-21 04:46:20 +00:00
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
2004-10-12 21:28:27 +00:00
column = WMGetFromArray(table->columns, i);
2000-12-21 04:46:20 +00:00
2004-10-12 21:28:27 +00:00
if (column->delegate && column->delegate->endCellEdit)
(*column->delegate->endCellEdit)(column->delegate, column, row);
}
}
2004-10-12 21:28:27 +00:00
void
WMEditTableViewRow(WMTableView *table, int row)
{
int i;
WMTableColumn *column;
if (table->editingRow >= 0) {
2004-10-12 21:28:27 +00:00
stopRowEdit(table, table->editingRow);
}
2001-01-26 19:30:53 +00:00
table->editingRow = row;
2004-10-12 21:28:27 +00:00
2001-01-26 19:30:53 +00:00
if (row < 0)
2004-10-12 21:28:27 +00:00
return;
for (i = 0; i < WMGetArrayItemCount(table->columns); i++) {
2004-10-12 21:28:27 +00:00
column = WMGetFromArray(table->columns, i);
2004-10-12 21:28:27 +00:00
if (column->delegate && column->delegate->beginCellEdit)
(*column->delegate->beginCellEdit)(column->delegate, column, row);
2000-12-21 04:46:20 +00:00
}
}
2004-10-12 21:28:27 +00:00
void
WMSelectTableViewRow(WMTableView *table, int row)
2001-01-02 14:17:26 +00:00
{
if (table->clickedRow >= 0)
2004-10-12 21:28:27 +00:00
setRowSelected(table, table->clickedRow, False);
2001-01-10 21:10:39 +00:00
if (row >= table->rows) {
2004-10-12 21:28:27 +00:00
return;
2001-01-10 21:10:39 +00:00
}
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
setRowSelected(table, row, True);
table->clickedRow = row;
2001-01-10 21:10:39 +00:00
2001-01-02 14:17:26 +00:00
if (table->action)
2004-10-12 21:28:27 +00:00
(*table->action)(table, table->clientData);
2001-01-02 14:17:26 +00:00
WMPostNotificationName(WMTableViewSelectionDidChangeNotification,
2004-10-12 21:28:27 +00:00
table, NULL);
2001-01-02 14:17:26 +00:00
}
2004-10-12 21:28:27 +00:00
void
WMReloadTableView(WMTableView *table)
2001-01-02 14:17:26 +00:00
{
2001-01-21 00:19:02 +00:00
if (table->editingRow >= 0)
2004-10-12 21:28:27 +00:00
stopRowEdit(table, table->editingRow);
2001-05-17 22:30:38 +00:00
2001-01-10 21:10:39 +00:00
/* 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) */
WMEmptyArray(table->selectedRows);
2004-10-12 21:28:27 +00:00
2001-01-10 21:10:39 +00:00
if (table->clickedRow >= 0) {
2004-10-12 21:28:27 +00:00
if (table->action)
(*table->action)(table, table->clientData);
WMPostNotificationName(WMTableViewSelectionDidChangeNotification,
table, NULL);
table->clickedRow = -1;
2001-01-10 21:10:39 +00:00
}
2001-05-17 22:30:38 +00:00
if (table->delegate && table->delegate->numberOfRows) {
2004-10-12 21:28:27 +00:00
int rows;
rows = (*table->delegate->numberOfRows)(table->delegate, table);
if (rows != table->rows) {
table->rows = rows;
handleResize(table->view->delegate, table->view);
} else {
repaintTable(table);
}
2001-05-17 22:30:38 +00:00
}
2001-01-02 14:17:26 +00:00
}
2004-10-12 21:28:27 +00:00
void
WMNoteTableViewNumberOfRowsChanged(WMTableView *table)
2001-01-02 14:17:26 +00:00
{
WMReloadTableView(table);
}
2004-10-12 21:28:27 +00:00
static void
handleTableEvents(XEvent *event, void *data)
2000-11-12 03:29:53 +00:00
{
WMTableView *table = (WMTableView*)data;
2001-01-02 14:17:26 +00:00
int row;
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
switch (event->type) {
2004-10-12 21:28:27 +00:00
case ButtonPress:
if (event->xbutton.button == Button1) {
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) {
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);
table->clickedRow = row;
}
}
break;
case ButtonRelease:
if (event->xbutton.button == Button1) {
if (table->action)
(*table->action)(table, table->clientData);
WMPostNotificationName(WMTableViewSelectionDidChangeNotification,
table, NULL);
table->dragging = 0;
}
break;
2001-01-02 14:17:26 +00:00
}
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
static void
handleEvents(XEvent *event, void *data)
2000-11-12 03:29:53 +00:00
{
WMTableView *table = (WMTableView*)data;
WMScreen *scr = WMWidgetScreen(table);
2004-10-12 21:28:27 +00:00
2000-11-12 03:29:53 +00:00
switch (event->type) {
2004-10-12 21:28:27 +00:00
case Expose:
W_DrawRelief(scr, W_VIEW_DRAWABLE(table->view), 0, 0,
W_VIEW_WIDTH(table->view), W_VIEW_HEIGHT(table->view),
WRSunken);
break;
2000-11-12 03:29:53 +00:00
}
}
2004-10-12 21:28:27 +00:00
static void
handleResize(W_ViewDelegate *self, WMView *view)
{
reorganizeInterior(view->self);
}
2004-10-12 21:28:27 +00:00
static void
reorganizeInterior(WMTableView *table)
2000-11-12 03:29:53 +00:00
{
int width;
int height;
2001-05-17 22:30:38 +00:00
WMSize size = getTotalSize(table);
WMView *view = table->view;
2001-05-17 22:30:38 +00:00
int vw, vh;
int hsThickness, vsThickness;
if (table->vscroll)
vsThickness = WMWidgetWidth(table->vscroll);
if (table->hscroll)
hsThickness = WMWidgetHeight(table->hscroll);
2000-11-12 03:29:53 +00:00
width = W_VIEW_WIDTH(view) - 2;
height = W_VIEW_HEIGHT(view) - 3;
2004-10-12 21:28:27 +00:00
height -= table->headerHeight; /* table header */
2000-11-12 03:29:53 +00:00
if (table->corner)
2004-10-12 21:28:27 +00:00
WMResizeWidget(table->corner, 20, table->headerHeight);
2001-05-17 22:30:38 +00:00
WMMoveWidget(table->vscroll, 1, table->headerHeight + 1);
WMResizeWidget(table->vscroll, 20, height + 1);
if (table->hscroll) {
WMMoveWidget(table->hscroll, vsThickness, W_VIEW_HEIGHT(view) - hsThickness - 1);
WMResizeWidget(table->hscroll, width-(vsThickness+1), hsThickness);
}
2000-11-12 03:29:53 +00:00
if (table->header)
2004-10-12 21:28:27 +00:00
WMResizeWidget(table->header, width-(vsThickness+1), table->headerHeight);
2001-05-17 22:30:38 +00:00
if (table->viewBuffer) {
2004-10-12 21:28:27 +00:00
WMReleasePixmap(table->viewBuffer);
table->viewBuffer = NULL;
2001-05-17 22:30:38 +00:00
}
width -= vsThickness;
height -= hsThickness;
2001-05-17 22:30:38 +00:00
vw = WMIN(size.width, width);
vh = WMIN(size.height, height);
W_MoveView(table->tableView, vsThickness+1, 1+table->headerHeight+1);
2001-07-23 20:31:32 +00:00
W_ResizeView(table->tableView, WMAX(vw, 1), WMAX(vh, 1)+1);
2004-10-12 21:28:27 +00:00
2001-05-17 22:30:38 +00:00
adjustScrollers(table);
2004-10-12 21:28:27 +00:00
repaintTable(table);
2000-11-12 03:29:53 +00:00
}
2004-10-12 21:28:27 +00:00
static void
rearrangeHeader(WMTableView *table)
2001-01-02 14:17:26 +00:00
{
int width;
int count;
2004-10-12 21:28:27 +00:00
int i;
/*WMRect rect = WMGetScrollViewVisibleRect(table->scrollView);*/
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
width = 0;
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
count = WMGetArrayItemCount(table->columns);
for (i = 0; i < count; i++) {
2004-10-12 21:28:27 +00:00
WMTableColumn *column = WMGetFromArray(table->columns, i);
WMView *splitter = WMGetFromArray(table->splitters, i);
2001-01-02 14:17:26 +00:00
2004-10-12 21:28:27 +00:00
WMMoveWidget(column->titleW, width, 0);
WMResizeWidget(column->titleW, column->width-1, table->headerHeight);
2001-01-02 14:17:26 +00:00
2004-10-12 21:28:27 +00:00
width += column->width;
W_MoveView(splitter, width-1, 0);
2001-01-02 14:17:26 +00:00
}
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
wassertr(table->delegate && table->delegate->numberOfRows);
2004-10-12 21:28:27 +00:00
2001-01-02 14:17:26 +00:00
table->rows = table->delegate->numberOfRows(table->delegate, table);
2001-05-17 22:30:38 +00:00
table->tableWidth = width + 1;
2004-10-12 21:28:27 +00:00
handleResize(table->view->delegate, table->view);
2001-01-02 14:17:26 +00:00
}
2004-10-12 21:28:27 +00:00