diff options
Diffstat (limited to 'prev/wintable/checkboxes.h')
| -rw-r--r-- | prev/wintable/checkboxes.h | 247 |
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? -} |
