summaryrefslogtreecommitdiff
path: root/alf/alflabel.cpp
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2019-06-30 12:48:57 +0200
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2019-06-30 12:48:57 +0200
commitfe078af239f3b73651c32bb1cdb158dcab39ad5c (patch)
treec855620ab6970e658ea662d2c36b81cb68f50992 /alf/alflabel.cpp
parentecfb4b72fec0c25ef416038ef22db5d34d687ee4 (diff)
label reimplement
Diffstat (limited to 'alf/alflabel.cpp')
-rw-r--r--alf/alflabel.cpp233
1 files changed, 196 insertions, 37 deletions
diff --git a/alf/alflabel.cpp b/alf/alflabel.cpp
index e7550e4..208b033 100644
--- a/alf/alflabel.cpp
+++ b/alf/alflabel.cpp
@@ -2,8 +2,15 @@
/* LABEL */
-static
-int ALF__LabelTopPadding(HWND hwnd)
+typedef struct {
+ DWORD style;
+ HFONT font;
+} ALFLabelPriv;
+
+TCHAR *_alf_labelClass;
+
+static int
+ALF__LabelTopPadding(HWND hwnd)
{
// some pixels on top to align with the edit control
// see also: alfedit.cpp
@@ -12,28 +19,152 @@ int ALF__LabelTopPadding(HWND hwnd)
+ ((LOBYTE(LOWORD(GetVersion())) < 4) ? 2 : 1) /* internal padding in edit control */;
}
+static int
+ALF__LabelLeftPadding(HWND hwnd, HDC hdc)
+{
+ // some pixels on the left to align with the edit control
+ // see also: alfedit.cpp
+ int p = ALF_Compat_GetSystemMetricsForDpi(
+ SM_CXEDGE, ALF_CentipointsToPixels(GetParent(hwnd), 7200));
+
+ p += 1;
+
+ TEXTMETRIC tm;
+ ZeroMemory(&tm, sizeof(tm));
+ if (GetTextMetrics(hdc, &tm)) {
+ if (tm.tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE))
+ p += ALF_GetAveCharWidth(hdc) / 2;
+ }
+
+ return p;
+}
+
+static BOOL CALLBACK
+ALF__Label_Text_DrawStateProc(HDC hdc, LPARAM lData, WPARAM wData, int cx, int cy)
+{
+ (void)wData;
+
+ int oldBkMode = SetBkMode(hdc, TRANSPARENT);
+
+ RECT r = { 0, 0, cx, cy };
+ DrawText(hdc, (TCHAR*)lData, -1, &r, (UINT)wData);
+
+ SetBkMode(hdc, oldBkMode);
+
+ return TRUE;
+}
+
static LRESULT CALLBACK
-ALF__LabelSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
+ALF__LabelWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- (void)uIdSubclass;
- (void)dwRefData;
+ ALFLabelPriv *priv = (ALFLabelPriv*)GetWindowLongPtr(hwnd, 0);
+ if (!priv)
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+
+ if (uMsg == ALF_WM_LBL_GETSTYLE) {
+ return priv->style;
+ } else if (uMsg == ALF_WM_LBL_SETSTYLE) {
+ priv->style = (DWORD)lParam;
+ InvalidateRect(hwnd, NULL, TRUE);
+ return TRUE;
+ } else if (uMsg == WM_GETDLGCODE) {
+ return DLGC_STATIC;
+ } else if (uMsg == WM_SETFONT) {
+ priv->font = (HFONT)wParam;
+ if (LOWORD(lParam) != 0)
+ InvalidateRect(hwnd, NULL, TRUE);
- if (uMsg == ALF_WM_QUERYSIZE) {
+ return 0;
+ } else if (uMsg == WM_GETFONT) {
+ return (LRESULT)priv->font;
+ } else if (uMsg == WM_UPDATEUISTATE) {
+ InvalidateRect(hwnd, NULL, TRUE);
+ } else if (uMsg == WM_PAINT) {
+ PAINTSTRUCT ps;
+ HDC hdc = BeginPaint(hwnd, &ps);
+
+ ALF_Compat_DrawThemeParentBackground(hwnd, hdc, &ps.rcPaint);
+
+ HFONT oldFont = NULL;
+ if (priv->font)
+ oldFont = SelectFont(hdc, priv->font);
+
+ SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
+ SetBkMode(hdc, TRANSPARENT);
+
+ // calc drawtext style
+ UINT format = DT_EXPANDTABS;
+
+ LRESULT uiState = SendMessage(hwnd, WM_QUERYUISTATE, 0, 0);
+ if (uiState & UISF_HIDEACCEL)
+ format |= DT_HIDEPREFIX;
+
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+
+ switch (priv->style & ALF_LABEL_HALIGN_MASK) {
+ case ALF_LABEL_ALIGN_HCENTER:
+ format |= DT_CENTER;
+ break;
+ case ALF_LABEL_ALIGN_RIGHT:
+ format |= DT_RIGHT;
+ break;
+ }
+ switch (priv->style & ALF_LABEL_VALIGN_MASK) {
+ case ALF_LABEL_ALIGN_BOTTOM:
+ format |= DT_BOTTOM;
+ break;
+ case ALF_LABEL_ALIGN_VCENTER:
+ format |= DT_VCENTER;
+ break;
+ }
+
+ if ((priv->style & ALF_LABEL_HALIGN_MASK) == ALF_LABEL_ALIGN_LEFT_LIKE_EDIT)
+ rc.left += ALF__LabelLeftPadding(hwnd, hdc);
+ if ((priv->style & ALF_LABEL_VALIGN_MASK) == ALF_LABEL_ALIGN_TOP_LIKE_EDIT)
+ rc.top += ALF__LabelTopPadding(hwnd);
+
+ TCHAR *text = ALF_Text(hwnd);
+
+ if (!IsWindowEnabled(hwnd)) {
+ if (GetVersion() >= 0x80000000) {
+ // Win9x just uses gray text. DSS_DISABLED is broken there, too,
+ // so we can't get the NT look even if we wanted to
+ SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
+
+ DrawText(hdc, text, -1, &rc, format);
+ } else {
+ // FIXME! This doesn't look good when using uxtheme, even though windows does it the same way
+ // need to investigate whether drawing with disabled button style looks nicer
+ DrawState(hdc, NULL,
+ ALF__Label_Text_DrawStateProc,
+ (LPARAM)text, (WPARAM)format,
+ rc.left,
+ rc.top,
+ rc.right - rc.left,
+ rc.bottom - rc.top,
+ DST_COMPLEX | DSS_DISABLED);
+ }
+ } else {
+ DrawText(hdc, text, -1, &rc, format);
+ }
+
+ ALF_Free(text);
+
+ if (oldFont)
+ SelectFont(hdc, oldFont);
+
+ EndPaint(hwnd, &ps);
+
+ return TRUE;
+ } else if (uMsg == ALF_WM_QUERYSIZE) {
HDC hdcLabel = GetDC(hwnd);
- HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
HFONT oldFont = 0;
- if (font)
- oldFont = SelectFont(hdcLabel, font);
+ if (priv->font)
+ oldFont = SelectFont(hdcLabel, priv->font);
// calc drawtext style
- DWORD style = GetWindowLong(hwnd, GWL_STYLE);
UINT format = DT_LEFT | DT_EXPANDTABS | DT_CALCRECT;
- if (style & SS_NOPREFIX)
- format |= DT_NOPREFIX;
- if (style & SS_EDITCONTROL)
- format |= DT_EDITCONTROL;
- if (style & SS_ENDELLIPSIS || style & SS_PATHELLIPSIS || style & SS_WORDELLIPSIS)
- format |= DT_SINGLELINE;
RECT r = { 0, 0, 100, 100 };
@@ -46,45 +177,44 @@ ALF__LabelSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_
ALF_Free(textbuf);
SIZE *pSize = (SIZE*)(void*)lParam;
- if (pSize->cx == 0)
+ if (pSize->cx == 0) {
pSize->cx = r.right - r.left;
- if (pSize->cy == 0)
- pSize->cy = r.bottom - r.top + ALF__LabelTopPadding(hwnd);
+ if ((priv->style & ALF_LABEL_HALIGN_MASK) == ALF_LABEL_ALIGN_LEFT_LIKE_EDIT)
+ pSize->cx += ALF__LabelLeftPadding(hwnd, hdcLabel);
+ }
+ if (pSize->cy == 0) {
+ pSize->cy = r.bottom - r.top;
+ if ((priv->style & ALF_LABEL_VALIGN_MASK) == ALF_LABEL_ALIGN_TOP_LIKE_EDIT)
+ pSize->cy += ALF__LabelTopPadding(hwnd);
+ }
- if (font)
+ if (oldFont)
SelectFont(hdcLabel, oldFont);
ReleaseDC(hwnd, hdcLabel);
- } else if (uMsg == ALF_WM_APPLYSIZE) {
- RECT *p = (RECT *)lParam;
-
- int topPadding = ALF__LabelTopPadding(hwnd);
-
- return (LRESULT)DeferWindowPos((HDWP)wParam,
- hwnd, NULL,
- p->left, p->top + topPadding,
- p->right - p->left, p->bottom - p->top - topPadding,
- SWP_NOZORDER|SWP_NOACTIVATE);
} else if (uMsg == WM_DESTROY) {
- ALF_Compat_RemoveWindowSubclass(hwnd, ALF__LabelSubclassProc, 0);
+ ALF_Free(priv);
+ SetWindowLongPtr(hwnd, 0, 0);
}
- return ALF_Compat_DefSubclassProc(hwnd, uMsg, wParam, lParam);
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
HWND
ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const TCHAR *text)
{
- HWND hwndLabel = CreateWindow(TEXT("STATIC"),
+ HWND hwndLabel = CreateWindow(_alf_labelClass,
text,
- WS_CHILD | WS_VISIBLE | SS_LEFTNOWORDWRAP,
+ WS_CHILD | WS_VISIBLE | SS_OWNERDRAW,
0, 0, 100, 100,
win,
(HMENU)(int)id,
- (HINSTANCE)GetWindowLongPtr(win, GWLP_HINSTANCE),
+ ALF_HINSTANCE,
NULL);
- ALF_Compat_SetWindowSubclass(hwndLabel, ALF__LabelSubclassProc, 0, 0);
+ ALFLabelPriv *priv = ALF_New(ALFLabelPriv, 1);
+ priv->style = ALF_LABEL_ALIGN_LEFT | ALF_LABEL_ALIGN_TOP_LIKE_EDIT;
+ SetWindowLongPtr(hwndLabel, 0, (LONG_PTR)priv);
ALFWidgetLayoutParams p;
ZeroMemory(&p, sizeof(p));
@@ -93,9 +223,38 @@ ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const TCHAR *text)
p.y = y;
p.width = 0;
p.height = 0;
- p.flags = ALF_QUERYSIZE | ALF_APPLYSIZE | ALF_MESSAGEFONT;
+ p.flags = ALF_QUERYSIZE | ALF_MESSAGEFONT;
ALF_AddWidgetEx(win, &p);
return hwndLabel;
}
+
+
+void
+ALF_RegisterLabelClass(void)
+{
+ WNDCLASS cls;
+ ZeroMemory(&cls, sizeof(cls));
+
+ TCHAR classNameBuf[256];
+ ALF_BuildUniqueName(classNameBuf, TEXT("ALFLabel."), (ULONG_PTR)&_alf_labelClass);
+
+ cls.hInstance = ALF_HINSTANCE;
+ cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW);
+ if (LOBYTE(LOWORD(GetVersion())) >= 4) {
+ cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
+ } else {
+ // NT 3.x has white dialog backgrounds
+ cls.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ }
+ cls.lpszClassName = classNameBuf;
+ cls.cbWndExtra = sizeof(void*);
+ cls.lpfnWndProc = ALF__LabelWindowProc;
+
+ ATOM classatom = RegisterClass(&cls);
+ if (!classatom)
+ MessageBox(NULL, TEXT("FATAL: Could not register label class"), NULL, MB_OK);
+
+ _alf_labelClass = MAKEINTATOM(classatom);
+}