Started using normal images for checkboxes in Windows uiTables. It doesn't quite work yet.
This commit is contained in:
parent
4c5f0961fe
commit
405a6defd2
|
@ -9,6 +9,9 @@ static uiTableTextColumnOptionalParams defaultTextColumnOptionalParams = {
|
||||||
/*TODO.ColorModelColumn = */-1,
|
/*TODO.ColorModelColumn = */-1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define nCheckboxImages 4
|
||||||
|
#define nLVN_GETDISPINFOSkip 3
|
||||||
|
|
||||||
struct columnParams {
|
struct columnParams {
|
||||||
int textModelColumn;
|
int textModelColumn;
|
||||||
int textEditableColumn;
|
int textEditableColumn;
|
||||||
|
@ -159,17 +162,13 @@ nm->item.pszText=L"abcdefg";
|
||||||
b = uiprivWICToGDI(wb, dc);
|
b = uiprivWICToGDI(wb, dc);
|
||||||
if (ReleaseDC(t->hwnd, dc) == 0)
|
if (ReleaseDC(t->hwnd, dc) == 0)
|
||||||
logLastError(L"error calling ReleaseDC() in onLVN_GETDISPINFO()");
|
logLastError(L"error calling ReleaseDC() in onLVN_GETDISPINFO()");
|
||||||
if (ImageList_GetImageCount(t->smallImages) <= t->smallIndex) {
|
if (ImageList_Replace(t->smallImages, t->smallIndex + nCheckboxImages, b, NULL) == 0)
|
||||||
if (ImageList_Add(t->smallImages, b, NULL) == -1)
|
logLastError(L"error calling ImageList_Replace() in onLVN_GETDISPINFO()");
|
||||||
logLastError(L"error calling ImageList_Add() in onLVN_GETDISPINFO()");
|
|
||||||
} else
|
|
||||||
if (ImageList_Replace(t->smallImages, t->smallIndex, b, NULL) == 0)
|
|
||||||
logLastError(L"error calling ImageList_Replace() in onLVN_GETDISPINFO()");
|
|
||||||
// TODO error check
|
// TODO error check
|
||||||
DeleteObject(b);
|
DeleteObject(b);
|
||||||
nm->item.iImage = t->smallIndex;
|
nm->item.iImage = t->smallIndex + nCheckboxImages;
|
||||||
t->smallIndex++;
|
t->smallIndex++;
|
||||||
t->smallIndex %= 3; // TODO don't hardcode this
|
t->smallIndex %= nLVN_GETDISPINFOSkip;
|
||||||
}
|
}
|
||||||
|
|
||||||
// having an image list always leaves space for an image on the main item :|
|
// having an image list always leaves space for an image on the main item :|
|
||||||
|
@ -180,20 +179,16 @@ nm->item.pszText=L"abcdefg";
|
||||||
nm->item.iIndent = -1;
|
nm->item.iIndent = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nm->item.mask & LVIF_STATE) != 0)
|
if (p->checkboxModelColumn != -1) {
|
||||||
if (p->checkboxModelColumn != -1) {
|
// TODO handle enabled
|
||||||
// TODO handle enabled
|
data = (*(t->model->mh->CellValue))(t->model->mh, t->model, nm->item.iItem, p->textModelColumn);
|
||||||
data = (*(t->model->mh->CellValue))(t->model->mh, t->model, nm->item.iItem, p->textModelColumn);
|
checked = uiTableDataInt(data) != 0;
|
||||||
checked = uiTableDataInt(data) != 0;
|
uiFreeTableData(data);
|
||||||
uiFreeTableData(data);
|
nm->item.iImage = 0;
|
||||||
nm->item.state = INDEXTOSTATEIMAGEMASK(1);
|
if (checked)
|
||||||
if (checked)
|
nm->item.iImage = 1;
|
||||||
nm->item.state = INDEXTOSTATEIMAGEMASK(2);
|
nm->item.mask |= LVIF_IMAGE;
|
||||||
nm->item.stateMask = LVIS_STATEIMAGEMASK;
|
}
|
||||||
} else {
|
|
||||||
nm->item.state = INDEXTOSTATEIMAGEMASK(0);
|
|
||||||
nm->item.stateMask = LVIS_STATEIMAGEMASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we don't want to pop from an empty queue, so if nothing updated the queue (no info was filled in above), just push NULL
|
// we don't want to pop from an empty queue, so if nothing updated the queue (no info was filled in above), just push NULL
|
||||||
if (!queueUpdated)
|
if (!queueUpdated)
|
||||||
|
@ -448,17 +443,14 @@ static void mkCheckboxesUnthemed(uiTable *t, int cx, int cy)
|
||||||
HDC cdc;
|
HDC cdc;
|
||||||
HBITMAP prevBitmap;
|
HBITMAP prevBitmap;
|
||||||
RECT r;
|
RECT r;
|
||||||
int i, n;
|
int i;
|
||||||
|
|
||||||
// + 1 because we can't actually use image index 0 — that index is used to mean "no state image" in LVITEMW
|
|
||||||
n = ARRAYSIZE(unthemedStates) + 1;
|
|
||||||
|
|
||||||
dc = GetDC(t->hwnd);
|
dc = GetDC(t->hwnd);
|
||||||
if (dc == NULL)
|
if (dc == NULL)
|
||||||
logLastError(L"error calling GetDC() in mkCheckboxesUnthemed()");
|
logLastError(L"error calling GetDC() in mkCheckboxesUnthemed()");
|
||||||
ZeroMemory(&bmi, sizeof (BITMAPINFO));
|
ZeroMemory(&bmi, sizeof (BITMAPINFO));
|
||||||
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
|
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
|
||||||
bmi.bmiHeader.biWidth = cx * n;
|
bmi.bmiHeader.biWidth = cx * nCheckboxImages;
|
||||||
bmi.bmiHeader.biHeight = cy;
|
bmi.bmiHeader.biHeight = cy;
|
||||||
bmi.bmiHeader.biPlanes = 1;
|
bmi.bmiHeader.biPlanes = 1;
|
||||||
bmi.bmiHeader.biBitCount = 32;
|
bmi.bmiHeader.biBitCount = 32;
|
||||||
|
@ -474,12 +466,11 @@ static void mkCheckboxesUnthemed(uiTable *t, int cx, int cy)
|
||||||
// TODO error check
|
// TODO error check
|
||||||
prevBitmap = (HBITMAP) SelectObject(cdc, b);
|
prevBitmap = (HBITMAP) SelectObject(cdc, b);
|
||||||
|
|
||||||
// note we start at cx to start at index 1
|
r.left = 0;
|
||||||
r.left = cx;
|
|
||||||
r.top = 0;
|
r.top = 0;
|
||||||
r.right = cx * 2;
|
r.right = cx;
|
||||||
r.bottom = cy;
|
r.bottom = cy;
|
||||||
for (i = 0; i < ARRAYSIZE(unthemedStates); i++) {
|
for (i = 0; i < nCheckboxImages; i++) {
|
||||||
if (DrawFrameControl(cdc, &r,
|
if (DrawFrameControl(cdc, &r,
|
||||||
DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT | unthemedStates[i]) == 0)
|
DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT | unthemedStates[i]) == 0)
|
||||||
logLastError(L"error calling DrawFrameControl() in mkCheckboxesUnthemed()");
|
logLastError(L"error calling DrawFrameControl() in mkCheckboxesUnthemed()");
|
||||||
|
@ -494,14 +485,8 @@ static void mkCheckboxesUnthemed(uiTable *t, int cx, int cy)
|
||||||
if (ReleaseDC(t->hwnd, dc) == 0)
|
if (ReleaseDC(t->hwnd, dc) == 0)
|
||||||
logLastError(L"error calling ReleaseDC() in mkCheckboxesUnthemed()");
|
logLastError(L"error calling ReleaseDC() in mkCheckboxesUnthemed()");
|
||||||
|
|
||||||
t->checkboxImages = ImageList_Create(cx, cy, ILC_COLOR32,
|
if (ImageList_Replace(t->smallImages, 0, b, NULL) == 0)
|
||||||
n, n);
|
logLastError(L"error calling ImageList_Replace() in mkCheckboxesUnthemed()");
|
||||||
if (t->checkboxImages == NULL)
|
|
||||||
logLastError(L"error calling ImageList_Create() in mkCheckboxesUnthemed()");
|
|
||||||
if (ImageList_Add(t->checkboxImages, b, NULL) == -1)
|
|
||||||
logLastError(L"error calling ImageList_Add() in mkCheckboxesUnthemed()");
|
|
||||||
// TODO will this return NULL here because it's an initial state?
|
|
||||||
SendMessageW(t->hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM) (t->checkboxImages));
|
|
||||||
|
|
||||||
// TODO error check
|
// TODO error check
|
||||||
DeleteObject(b);
|
DeleteObject(b);
|
||||||
|
@ -511,6 +496,7 @@ uiTable *uiNewTable(uiTableModel *model)
|
||||||
{
|
{
|
||||||
uiTable *t;
|
uiTable *t;
|
||||||
int n;
|
int n;
|
||||||
|
int i;
|
||||||
|
|
||||||
uiWindowsNewControl(uiTable, t);
|
uiWindowsNewControl(uiTable, t);
|
||||||
|
|
||||||
|
@ -536,26 +522,21 @@ uiTable *uiNewTable(uiTableModel *model)
|
||||||
|
|
||||||
t->dispinfoStrings = new std::queue<WCHAR *>;
|
t->dispinfoStrings = new std::queue<WCHAR *>;
|
||||||
// this encodes the idea that two LVN_GETDISPINFOs must complete before we can free a string: the first real one is for the fourth call to free
|
// this encodes the idea that two LVN_GETDISPINFOs must complete before we can free a string: the first real one is for the fourth call to free
|
||||||
t->dispinfoStrings->push(NULL);
|
for (i = 0; i < nLVN_GETDISPINFOSkip; i++)
|
||||||
t->dispinfoStrings->push(NULL);
|
t->dispinfoStrings->push(NULL);
|
||||||
t->dispinfoStrings->push(NULL);
|
|
||||||
|
|
||||||
// TODO update these when the DPI changes
|
// TODO update these when the DPI changes
|
||||||
// TODO handle errors
|
// TODO handle errors
|
||||||
// TODO try adding a real transparent image
|
|
||||||
t->smallImages = ImageList_Create(
|
t->smallImages = ImageList_Create(
|
||||||
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
|
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
|
||||||
ILC_COLOR32,
|
ILC_COLOR32,
|
||||||
0, 3);
|
nCheckboxImages + nLVN_GETDISPINFOSkip, nCheckboxImages + nLVN_GETDISPINFOSkip);
|
||||||
if (t->smallImages == NULL)
|
if (t->smallImages == NULL)
|
||||||
logLastError(L"error calling ImageList_Create() in uiNewTable()");
|
logLastError(L"error calling ImageList_Create() in uiNewTable()");
|
||||||
// TODO will this return NULL here because it's an initial state?
|
// TODO will this return NULL here because it's an initial state?
|
||||||
SendMessageW(t->hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM) (t->smallImages));
|
SendMessageW(t->hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM) (t->smallImages));
|
||||||
|
|
||||||
mkCheckboxesUnthemed(t, 16, 16);
|
mkCheckboxesUnthemed(t, 16, 16);
|
||||||
// and we need to enable LVN_GETDISPINFO for states
|
|
||||||
if (SendMessageW(t->hwnd, LVM_SETCALLBACKMASK, LVIS_STATEIMAGEMASK, 0) == FALSE)
|
|
||||||
logLastError(L"error calling LVM_SETCALLBACKMASK in uiTableAdd()");
|
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue