summaryrefslogtreecommitdiff
path: root/prev/wintable/checkboxes.h
diff options
context:
space:
mode:
Diffstat (limited to 'prev/wintable/checkboxes.h')
-rw-r--r--prev/wintable/checkboxes.h247
1 files changed, 0 insertions, 247 deletions
diff --git a/prev/wintable/checkboxes.h b/prev/wintable/checkboxes.h
deleted file mode 100644
index b44a0d0..0000000
--- a/prev/wintable/checkboxes.h
+++ /dev/null
@@ -1,247 +0,0 @@
-// 16 august 2014
-
-enum {
- checkboxStateChecked = 1 << 0,
- checkboxStateHot = 1 << 1,
- checkboxStatePushed = 1 << 2,
- checkboxnStates = 1 << 3,
-};
-
-// TODO actually make this
-#define panichresult(a, b) panic(a)
-
-static UINT dfcState(int cbstate)
-{
- UINT ret;
-
- ret = DFCS_BUTTONCHECK;
- if ((cbstate & checkboxStateChecked) != 0)
- ret |= DFCS_CHECKED;
- if ((cbstate & checkboxStateHot) != 0)
- ret |= DFCS_HOT;
- if ((cbstate & checkboxStatePushed) != 0)
- ret |= DFCS_PUSHED;
- return ret;
-}
-
-static void drawFrameControlCheckbox(HDC dc, RECT *r, int cbState)
-{
- if (DrawFrameControl(dc, r, DFC_BUTTON, dfcState(cbState)) == 0)
- panic("error drawing Table checkbox image with DrawFrameControl()");
-}
-
-static void getFrameControlCheckboxSize(HDC dc, int *width, int *height)
-{
- // there's no real metric around
- // let's use SM_CX/YSMICON and hope for the best
- *width = GetSystemMetrics(SM_CXSMICON);
- *height = GetSystemMetrics(SM_CYSMICON);
-}
-
-static int themestates[checkboxnStates] = {
- CBS_UNCHECKEDNORMAL, // 0
- CBS_CHECKEDNORMAL, // checked
- CBS_UNCHECKEDHOT, // hot
- CBS_CHECKEDHOT, // checked | hot
- CBS_UNCHECKEDPRESSED, // pushed
- CBS_CHECKEDPRESSED, // checked | pushed
- CBS_UNCHECKEDPRESSED, // hot | pushed
- CBS_CHECKEDPRESSED, // checked | hot | pushed
-};
-
-static SIZE getStateSize(HDC dc, int cbState, HTHEME theme)
-{
- SIZE s;
- HRESULT res;
-
- res = GetThemePartSize(theme, dc, BP_CHECKBOX, themestates[cbState], NULL, TS_DRAW, &s);
- if (res != S_OK)
- panichresult("error getting theme part size for Table checkboxes", res);
- return s;
-}
-
-static void drawThemeCheckbox(HDC dc, RECT *r, int cbState, HTHEME theme)
-{
- HRESULT res;
-
- res = DrawThemeBackground(theme, dc, BP_CHECKBOX, themestates[cbState], r, NULL);
- if (res != S_OK)
- panichresult("error drawing Table checkbox image from theme", res);
-}
-
-static void getThemeCheckboxSize(HDC dc, int *width, int *height, HTHEME theme)
-{
- SIZE size;
- int cbState;
-
- size = getStateSize(dc, 0, theme);
- for (cbState = 1; cbState < checkboxnStates; cbState++) {
- SIZE against;
-
- against = getStateSize(dc, cbState, theme);
- if (size.cx != against.cx || size.cy != against.cy)
- // TODO make this use a no-information (or two ints) panic()
- panic("size mismatch in Table checkbox states");
- }
- *width = (int) size.cx;
- *height = (int) size.cy;
-}
-
-static void drawCheckbox(struct table *t, HDC dc, RECT *r, int cbState)
-{
- if (t->theme != NULL) {
- drawThemeCheckbox(dc, r, cbState, t->theme);
- return;
- }
- drawFrameControlCheckbox(dc, r, cbState);
-}
-
-static void freeCheckboxThemeData(struct table *t)
-{
- if (t->theme != NULL) {
- HRESULT res;
-
- res = CloseThemeData(t->theme);
- if (res != S_OK)
- panichresult("error closing Table checkbox theme", res);
- t->theme = NULL;
- }
-}
-
-static void loadCheckboxThemeData(struct table *t)
-{
- HDC dc;
-
- freeCheckboxThemeData(t);
- dc = GetDC(t->hwnd);
- if (dc == NULL)
- panic("error getting Table DC for loading checkbox theme data");
- // ignore error; if it can't be done, we can fall back to DrawFrameControl()
- if (t->theme == NULL) // try to open the theme
- t->theme = OpenThemeData(t->hwnd, L"button");
- if (t->theme != NULL) // use the theme
- getThemeCheckboxSize(dc, &(t->checkboxWidth), &(t->checkboxHeight), t->theme);
- else // couldn't open; fall back
- getFrameControlCheckboxSize(dc, &(t->checkboxWidth), &(t->checkboxHeight));
- if (ReleaseDC(t->hwnd, dc) == 0)
- panic("error releasing Table DC for loading checkbox theme data");
-}
-
-static void redrawCheckboxRect(struct table *t, LPARAM lParam)
-{
- struct rowcol rc;
- RECT r;
-
- rc = lParamToRowColumn(t, lParam);
- if (rc.row == -1 && rc.column == -1)
- return;
- if (t->columnTypes[rc.column] != tableColumnCheckbox)
- return;
- if (!rowColumnToClientRect(t, rc, &r))
- return;
- // TODO only the checkbox rect?
- if (InvalidateRect(t->hwnd, &r, TRUE) == 0)
- panic("error redrawing Table checkbox rect for mouse events");
-}
-
-HANDLER(checkboxMouseMoveHandler)
-{
- // don't actually check to see if the mouse is in the checkbox rect
- // if there's scrolling without mouse movement, that will change
- // instead, drawCell() will handle it
- if (!t->checkboxMouseOverLast) {
- t->checkboxMouseOverLast = TRUE;
- retrack(t);
- } else
- redrawCheckboxRect(t, t->checkboxMouseOverLastPoint);
- t->checkboxMouseOverLastPoint = lParam;
- redrawCheckboxRect(t, t->checkboxMouseOverLastPoint);
- *lResult = 0;
- return TRUE;
-}
-
-HANDLER(checkboxMouseLeaveHandler)
-{
- if (t->checkboxMouseOverLast)
- redrawCheckboxRect(t, t->checkboxMouseOverLastPoint);
- // TODO remember what I wanted to do here in the case of a held mouse button
- t->checkboxMouseOverLast = FALSE;
- *lResult = 0;
- return TRUE;
-}
-
-HANDLER(checkboxMouseDownHandler)
-{
- struct rowcol rc;
- RECT r;
- POINT pt;
-
- rc = lParamToRowColumn(t, lParam);
- if (rc.row == -1 || rc.column == -1)
- return FALSE;
- if (t->columnTypes[rc.column] != tableColumnCheckbox)
- return FALSE;
- if (!rowColumnToClientRect(t, rc, &r))
- return FALSE;
- toCheckboxRect(t, &r, 0);
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- if (PtInRect(&r, pt) == 0)
- return FALSE;
- t->checkboxMouseDown = TRUE;
- t->checkboxMouseDownRow = rc.row;
- t->checkboxMouseDownColumn = rc.column;
- // TODO redraw the whole cell?
- if (InvalidateRect(t->hwnd, &r, TRUE) == 0)
- panic("error redrawing Table checkbox after mouse down");
- *lResult = 0;
- return TRUE;
-}
-
-HANDLER(checkboxMouseUpHandler)
-{
- struct rowcol rc;
- RECT r;
- POINT pt;
-
- if (!t->checkboxMouseDown)
- return FALSE;
- // the logic behind goto wrongUp is that the mouse must be released on the same checkbox
- rc = lParamToRowColumn(t, lParam);
- if (rc.row == -1 || rc.column == -1)
- goto wrongUp;
- if (rc.row != t->checkboxMouseDownRow || rc.column != t->checkboxMouseDownColumn)
- goto wrongUp;
- if (t->columnTypes[rc.column] != tableColumnCheckbox)
- goto wrongUp;
- if (!rowColumnToClientRect(t, rc, &r))
- goto wrongUp;
- toCheckboxRect(t, &r, 0);
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- if (PtInRect(&r, pt) == 0)
- goto wrongUp;
- notify(t, tableNotificationCellCheckboxToggled, rc.row, rc.column, 0);
- t->checkboxMouseDown = FALSE;
- // TODO redraw the whole cell?
- if (InvalidateRect(t->hwnd, &r, TRUE) == 0)
- panic("error redrawing Table checkbox after mouse up");
- // TODO really only the row? no way to specify column too?
- NotifyWinEvent(EVENT_OBJECT_STATECHANGE, t->hwnd, OBJID_CLIENT, rc.row);
- *lResult = 0;
- return TRUE;
-wrongUp:
- if (t->checkboxMouseDown) {
- rc.row = t->checkboxMouseDownRow;
- rc.column = t->checkboxMouseDownColumn;
- if (rowColumnToClientRect(t, rc, &r))
- // TODO only the checkbox rect?
- if (InvalidateRect(t->hwnd, &r, TRUE) == 0)
- panic("error redrawing Table checkbox rect for aborted mouse up event");
- }
- // if we landed on another checkbox, be sure to draw that one too
- if (t->checkboxMouseOverLast)
- redrawCheckboxRect(t, t->checkboxMouseOverLastPoint);
- t->checkboxMouseDown = FALSE;
- return FALSE; // TODO really?
-}