And finished rewriting table.cpp. That wasn't too bad for just text columns. Let's hope it works.

This commit is contained in:
Pietro Gagliardi 2018-06-08 21:44:55 -04:00
parent 516eb312fc
commit 41d63bd0cf
1 changed files with 110 additions and 43 deletions

View File

@ -5,9 +5,24 @@ struct uiTableModel {
std::vector<uiTable *> *tables; std::vector<uiTable *> *tables;
}; };
static uiTableTextColumnOptionalParams defaultTextColumnOptionalParams = {
.ColorModelColumn = -1,
};
struct columnParams { struct columnParams {
int textModelColumn; int textModelColumn;
int textEditableColumn; int textEditableColumn;
uiTableTextColumnOptionalParams textParams;
int imageModelColumn;
int checkboxModelColumn;
int checkboxEditableModelColumn;
int progressBarModelColumn;
int buttonModelColumn;
int buttonClickableModelColumn;
}; };
struct uiTable { struct uiTable {
@ -15,6 +30,7 @@ struct uiTable {
uiTableModel *model; uiTableModel *model;
HWND hwnd; HWND hwnd;
std::vector<struct columnParam *> *columns; std::vector<struct columnParam *> *columns;
WPARAM nColumns;
// MSDN says we have to keep LVN_GETDISPINFO strings we allocate around at least until "two additional LVN_GETDISPINFO messages have been sent". // MSDN says we have to keep LVN_GETDISPINFO strings we allocate around at least until "two additional LVN_GETDISPINFO messages have been sent".
// we'll use this queue to do so; the "two additional" part is encoded in the initial state of the queue // we'll use this queue to do so; the "two additional" part is encoded in the initial state of the queue
std::queue<WCHAR *> *dispinfoStrings; std::queue<WCHAR *> *dispinfoStrings;
@ -98,8 +114,9 @@ static LRESULT onLVN_GETDISPINFO(uiTable *t, NMLVDISPINFOW *nm)
WCHAR *wstr; WCHAR *wstr;
wstr = t->dipsinfoString->front(); wstr = t->dipsinfoString->front();
t->dispinfoString->pop(); if (wstr != NULL)
uiprivFree(wstr); uiprivFree(wstr);
t->dispinfoString->pop();
p = (*(t->columns))[nm->item.iSubItem]; p = (*(t->columns))[nm->item.iSubItem];
// TODO is this condition ever not going to be true for libui? // TODO is this condition ever not going to be true for libui?
@ -128,28 +145,33 @@ static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nmhdr, LRESULT *lResult)
return FALSE; return FALSE;
} }
$ TODO ===================
static void uiTableDestroy(uiControl *c) static void uiTableDestroy(uiControl *c)
{ {
uiTable *t = uiTable(c); uiTable *t = uiTable(c);
uiTableModel *model = t->model; uiTableModel *model = t->model;
std::vector<uiTable *>::iterator it; std::vector<uiTable *>::iterator it;
WCHAR *wstr;
uiWindowsUnregisterWM_NOTIFYHandler(t->hwnd); uiWindowsUnregisterWM_NOTIFYHandler(t->hwnd);
uiWindowsEnsureDestroyWindow(t->hwnd); uiWindowsEnsureDestroyWindow(t->hwnd);
// detach table from model // detach table from model
for (it = model->tables.begin(); it != model->tables.end(); it++) { for (it = model->tables.begin(); it != model->tables.end(); it++) {
if (*it == t) { if (*it == t) {
model->tables.erase(it); model->tables->erase(it);
break; break;
} }
} }
// free the columns // empty the string queue
for (auto col : *(t->columns)) { while (t->dispinfoStrings->size() != 0) {
uiprivFree(col->name); wstr = t->dispinfoStrings->front();
uiprivFree(col); if (wstr != NULL)
uiprivFree(wstr);
t->dispinfoStrings->pop();
} }
delete t->dispinfoStrings;
// free the columns
for (auto col : *(t->columns))
uiprivFree(col);
delete t->columns; delete t->columns;
uiFreeControl(uiControl(t)); uiFreeControl(uiControl(t));
} }
@ -176,51 +198,97 @@ static void uiTableMinimumSize(uiWindowsControl *c, int *width, int *height)
uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y);
*width = x; *width = x;
*height = y; *height = y;
} }'
void uiTableColumnAppendTextPart(uiTableColumn *c, int modelColumn, int expand) $ TODO ===================
static struct columnParams *appendColumn(uiTable *t, const char *name, int colfmt)
{ {
uiTable *t = c->t; WCHAR *wstr;
int lvIndex = 0;
LVCOLUMNW lvc; LVCOLUMNW lvc;
struct columnParams *p;
if (c->modelColumn >= 0)
return; // multiple parts not implemented
c->modelColumn = modelColumn;
// work out appropriate listview index for the column
for (auto candidate : *(t->columns)) {
if (candidate == c)
break;
if (candidate->modelColumn >= 0)
lvIndex++;
}
ZeroMemory(&lvc, sizeof (LVCOLUMNW)); ZeroMemory(&lvc, sizeof (LVCOLUMNW));
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT; /* | LVCF_SUBITEM; */ lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
lvc.fmt = LVCFMT_LEFT; lvc.fmt = colfmt;
lvc.cx = 120; // TODO lvc.cx = 120; // TODO
lvc.pszText = c->name; wstr = toUTF16(name);
if (SendMessageW(c->t->hwnd, LVM_INSERTCOLUMN, (WPARAM) lvIndex, (LPARAM) (&lvc)) == (LRESULT) (-1)) lvc.pszText = wstr;
logLastError(L"error calling LVM_INSERTCOLUMN in uiTableColumnPartSetTextPart()"); if (SendMessageW(t->hwnd, LVM_INSERTCOLUMNW, t->nColumns, (LPARAM) (&lvc)) == (LRESULT) (-1))
logLastError(L"error calling LVM_INSERTCOLUMNW in appendColumn()");
uiprivFree(wstr);
t->nColumns++;
p = uiprivNew(struct columnParams);
p->textModelColumn = -1;
p->imageModelColumn = -1;
p->checkboxModelColumn = -1;
p->progressBarModelColumn = -1;
p->buttonModelColumn = -1;
t->columns->push_back(p);
return p;
} }
void uiTableColumnPartSetEditable(uiTableColumn *c, int part, int editable) void uiTableAppendTextColumn(uiTable *t, const char *name, int textModelColumn, int textEditableModelColumn, uiTableTextColumnOptionalParams *params)
{
struct columnParams *p;
p = appendColumn(t, name, LVCFMT_LEFT);
p->textModelColumn = textModelColumn;
p->textEditableColumn = textEditableModelColumn;
if (params != NULL)
p->textParams = *params;
else
p->textParams = defaultTextColumnOptionalParams;
}
void uiTableAppendImageColumn(uiTable *t, const char *name, int imageModelColumn)
{ {
// TODO // TODO
} }
uiTableColumn *uiTableAppendColumn(uiTable *t, const char *name) void uiTableAppendImageTextColumn(uiTable *t, const char *name, int imageModelColumn, int textModelColumn, int textEditableModelColumn, uiTableTextColumnOptionalParams *textParams)
{ {
uiTableColumn *c; struct columnParams *p;
c = uiprivNew(uiTableColumn); p = appendColumn(t, name, LVCFMT_LEFT | LVCFMT_IMAGE);
c->name = toUTF16(name); p->textModelColumn = textModelColumn;
c->t = t; p->textEditableColumn = textEditableModelColumn;
c->modelColumn = -1; // -1 = unassigned if (params != NULL)
// we defer the actual ListView_InsertColumn call until a part is added... p->textParams = *params;
t->columns->push_back(c); else
return c; p->textParams = defaultTextColumnOptionalParams;
p->imageModelColumn = imageModelColumn;
}
void uiTableAppendCheckboxColumn(uiTable *t, const char *name, int checkboxModelColumn, int checkboxEditableModelColumn)
{
// TODO
}
void uiTableAppendCheckboxTextColumn(uiTable *t, const char *name, int checkboxModelColumn, int checkboxEditableModelColumn, int textModelColumn, int textEditableModelColumn, uiTableTextColumnOptionalParams *textParams)
{
struct columnParams *p;
p = appendColumn(t, name, LVCFMT_LEFT);
p->textModelColumn = textModelColumn;
p->textEditableColumn = textEditableModelColumn;
if (params != NULL)
p->textParams = *params;
else
p->textParams = defaultTextColumnOptionalParams;
p->checkboxModelColumn = checkboxModelColumn;
p->checkboxEditableColumn = checkboxEditableModelColumn;
}
void uiTableAppendProgressBarColumn(uiTable *t, const char *name, int progressModelColumn)
{
// TODO
}
void uiTableAppendButtonColumn(uiTable *t, const char *name, int buttonTextModelColumn, int buttonClickableModelColumn)
{
// TODO
} }
void uiTableSetRowBackgroundColorModelColumn(uiTable *t, int modelColumn) void uiTableSetRowBackgroundColorModelColumn(uiTable *t, int modelColumn)
@ -254,4 +322,3 @@ uiTable *uiNewTable(uiTableModel *model)
logLastError(L"error calling LVM_SETITEMCOUNT in uiNewTable()"); logLastError(L"error calling LVM_SETITEMCOUNT in uiNewTable()");
return t; return t;
} }