From 536ea04c34ba761d7031eeabb6d50adab0f0f2bd Mon Sep 17 00:00:00 2001 From: Jonas Kümmerlin Date: Thu, 16 Apr 2020 18:17:56 +0200 Subject: rework grid layout Fractional expand is now supported like Qt, and also per row/column instead of as a widget attribute. Instead of margins, you're now supposed to use empty rows/columns instead. Spacer is also gone, use empty rows/columns with minimum size. Layout engine is prepared to directly calculate edit, button, etc. sizes without subclassing these controls --- alf/alf.cpp | 159 ++++++----- alf/alf.h | 116 +++++--- alf/alfbutton.cpp | 13 +- alf/alfcombobox.cpp | 17 +- alf/alfedit.cpp | 13 +- alf/alflabel.cpp | 13 +- alf/alflayout.cpp | 746 ++++++++++++++++++++++++++++++++++++++-------------- alf/alflayout.h | 49 ++-- alf/alfnotebook.cpp | 13 +- alf/alfpanel.cpp | 13 +- alf/alfpriv.h | 4 - alf/alfspacer.cpp | 53 ---- 12 files changed, 770 insertions(+), 439 deletions(-) delete mode 100644 alf/alfspacer.cpp (limited to 'alf') diff --git a/alf/alf.cpp b/alf/alf.cpp index f914e55..de8d9c3 100644 --- a/alf/alf.cpp +++ b/alf/alf.cpp @@ -258,6 +258,7 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } if (msg == WM_CREATE) { + ALF_UpdateFontsPriv(hwnd, priv); if (priv->vtbl->create) { priv->vtbl->create(priv->closure, hwnd); } @@ -266,7 +267,6 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) if (!alwaysUnderline) { SendMessage(hwnd, WM_UPDATEUISTATE, MAKEWPARAM(UIS_INITIALIZE, 0), 0); } - ALF_UpdateFontsPriv(hwnd, priv); ALF_Layout_Apply(&priv->layout, hwnd); } @@ -340,9 +340,9 @@ ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) } void -ALF_AddWidget(HWND win, UINT x, UINT y, HWND widget, UINT minWidth, UINT minHeight, DWORD flags) +ALF_AddWidget(HWND win, int x, int y, HWND widget, int minWidth, int minHeight, DWORD flags) { - ALFWidgetLayoutParams params; + ALFAddWidgetParams params; ZeroMemory(¶ms, sizeof(params)); params.hwnd = widget; params.x = x; @@ -350,12 +350,7 @@ ALF_AddWidget(HWND win, UINT x, UINT y, HWND widget, UINT minWidth, UINT minHeig params.width = minWidth; params.height = minHeight; params.flags = flags; - ALF_AddWidgetEx(win, ¶ms); -} - -void ALF_AddWidgetEx(HWND win, const ALFWidgetLayoutParams* params) -{ - SendMessage(win, ALF_WM_ADDWIDGET, 0, (LPARAM)params); + SendMessage(win, ALF_WM_ADDWIDGET, 0, (LPARAM)¶ms); } static LRESULT CALLBACK @@ -398,7 +393,6 @@ ALF_Initialize(void) ALF_RegisterComboClass(); ALF_RegisterPanelClass(); - ALF_RegisterSpacerClass(); ALF_RegisterLabelClass(); ALF_RegisterNotebookClass(); @@ -423,7 +417,6 @@ ALF_UnInitialize(void) UnregisterClass(_alf_comboClass, ALF_HINSTANCE); UnregisterClass(_alf_panelClass, ALF_HINSTANCE); - UnregisterClass(_alf_spacerClass, ALF_HINSTANCE); UnregisterClass(_alf_labelClass, ALF_HINSTANCE); UnregisterClass(_alf_notebookClass, ALF_HINSTANCE); @@ -709,84 +702,128 @@ ALF_WidgetText(HWND parent, WORD id) DWORD ALF_WidgetLayoutFlags(HWND parent, HWND widget) { - ALFWidgetLayoutParams p; - if (SendMessage(parent, ALF_WM_GETLAYOUTPARAMS, (WPARAM)widget, (LPARAM)&p)) { - return p.flags; - } else { - return 0; - } + return (DWORD)SendMessage(parent, ALF_WM_LYT_GETWDGTFLAGS, (WPARAM)widget, 0); } BOOL ALF_SetWidgetLayoutFlags(HWND parent, HWND widget, DWORD flags) { - ALFWidgetLayoutParams p; - if (SendMessage(parent, ALF_WM_GETLAYOUTPARAMS, (WPARAM)widget, (LPARAM)&p)) { - p.flags = flags; - return SendMessage(parent, ALF_WM_SETLAYOUTPARAMS, (WPARAM)widget, (LPARAM)&p); - } + return (BOOL)SendMessage(parent, ALF_WM_LYT_SETWDGTFLAGS, (WPARAM)widget, (LPARAM)flags); +} - return FALSE; +BOOL +ALF_WidgetLayoutPosition(HWND parent, HWND widget, int *pX, int *pY) +{ + POINT p = { 0, 0 }; + + LRESULT r = SendMessage(parent, ALF_WM_LYT_GETWIDGETPOS, (WPARAM)widget, (LPARAM)&p); + *pX = p.x; + *pY = p.y; + return (BOOL)r; } BOOL -ALF_WidgetLayoutPosition(HWND parent, HWND widget, UINT *pX, UINT *pY) +ALF_SetWidgetLayoutPosition(HWND parent, HWND widget, int x, int y) { - ALFWidgetLayoutParams p; - if (SendMessage(parent, ALF_WM_GETLAYOUTPARAMS, (WPARAM)widget, (LPARAM)&p)) { - *pX = p.x; - *pY = p.y; - return TRUE; - } else { - return FALSE; - } + POINT p = { x, y }; + return (BOOL)SendMessage(parent, ALF_WM_LYT_SETWIDGETPOS, (WPARAM)widget, (LPARAM)&p); } BOOL -ALF_SetWidgetLayoutPosition(HWND parent, HWND widget, UINT x, UINT y) +ALF_WidgetLayoutMinSize(HWND parent, HWND widget, int *pWidth, int *pHeight) { - ALFWidgetLayoutParams p; - if (SendMessage(parent, ALF_WM_GETLAYOUTPARAMS, (WPARAM)widget, (LPARAM)&p)) { - p.x = x; - p.y = y; - return SendMessage(parent, ALF_WM_SETLAYOUTPARAMS, (WPARAM)widget, (LPARAM)&p); - } + SIZE s = { 0, 0 }; + LRESULT r = SendMessage(parent, ALF_WM_LYT_GETWIDGTSIZE, (WPARAM)widget, (LPARAM)&s); + *pWidth = s.cx; + *pHeight = s.cy; + return (BOOL)r; +} + +BOOL +ALF_SetWidgetLayoutMinSize(HWND parent, HWND widget, int width, int height) +{ + SIZE s = { width, height }; + return (BOOL)SendMessage(parent, ALF_WM_LYT_SETWIDGTSIZE, (WPARAM)widget, (LPARAM)&s); +} - return FALSE; +HWND +ALF_WidgetAtLayoutPosition(HWND parent, int x, int y) +{ + int xy[2] = { x, y }; + + return (HWND)SendMessage(parent, ALF_WM_GETWIDGETATPOS, 0, (LPARAM)&xy); +} + +int +ALF_LayoutRowMinSize(HWND parent, int rowno) +{ + return (int)SendMessage(parent, ALF_WM_LYT_GETROWSIZE, (WPARAM)rowno, 0); } BOOL -ALF_WidgetLayoutSize(HWND parent, HWND widget, UINT *pCptWidth, UINT *pCptHeight) +ALF_LayoutSetRowMinSize(HWND parent, int rowno, int rowsize) { - ALFWidgetLayoutParams p; - if (SendMessage(parent, ALF_WM_GETLAYOUTPARAMS, (WPARAM)widget, (LPARAM)&p)) { - *pCptWidth = p.width; - *pCptHeight = p.height; - return TRUE; - } else { - return FALSE; - } + return (BOOL)SendMessage(parent, ALF_WM_LYT_SETROWSIZE, (WPARAM)rowno, (LPARAM)rowsize); +} + +int +ALF_LayoutColumnMinSize(HWND parent, int colno) +{ + return (int)SendMessage(parent, ALF_WM_LYT_GETCOLSIZE, (WPARAM)colno, 0); } BOOL -ALF_SetWidgetLayoutSize(HWND parent, HWND widget, UINT cptWidth, UINT cptHeight) +ALF_LayoutSetColumnMinSize(HWND parent, int colno, int colsize) { - ALFWidgetLayoutParams p; - if (SendMessage(parent, ALF_WM_GETLAYOUTPARAMS, (WPARAM)widget, (LPARAM)&p)) { - p.width = cptWidth; - p.height = cptHeight; - return SendMessage(parent, ALF_WM_SETLAYOUTPARAMS, (WPARAM)widget, (LPARAM)&p); - } + return (BOOL)SendMessage(parent, ALF_WM_LYT_SETCOLSIZE, (WPARAM)colno, (LPARAM)colsize); +} - return FALSE; +DWORD +ALF_LayoutRowFlags(HWND parent, int rowno) +{ + return (DWORD)SendMessage(parent, ALF_WM_LYT_GETROWFLAGS, (WPARAM)rowno, 0); } -HWND -ALF_WidgetAtLayoutPosition(HWND parent, UINT x, UINT y) +BOOL +ALF_LayoutSetRowFlags(HWND parent, int rowno, DWORD flags) { - UINT xy[2] = { x, y }; + return (BOOL)SendMessage(parent, ALF_WM_LYT_SETROWFLAGS, (WPARAM)rowno, (LPARAM)flags); +} - return (HWND)SendMessage(parent, ALF_WM_GETWIDGETATPOS, 0, (LPARAM)&xy); +DWORD +ALF_LayoutColumnFlags(HWND parent, int colno) +{ + return (DWORD)SendMessage(parent, ALF_WM_LYT_GETCOLFLAGS, (WPARAM)colno, 0); +} + +BOOL +ALF_LayoutSetColumnFlags(HWND parent, int colno, DWORD flags) +{ + return (BOOL)SendMessage(parent, ALF_WM_LYT_SETCOLFLAGS, (WPARAM)colno, (LPARAM)flags); +} + +int +ALF_LayoutRowExpandNumerator(HWND parent, int rowno) +{ + return (int)SendMessage(parent, ALF_WM_LYT_GETROWEXPAND, (WPARAM)rowno, 0); +} + +BOOL +ALF_LayoutSetRowExpandNumerator(HWND parent, int rowno, int expand) +{ + return (BOOL)SendMessage(parent, ALF_WM_LYT_SETROWEXPAND, (WPARAM)rowno, (LPARAM)expand); +} + +int +ALF_LayoutColumnExpandNumerator(HWND parent, int colno) +{ + return (int)SendMessage(parent, ALF_WM_LYT_GETCOLEXPAND, (WPARAM)colno, 0); +} + +BOOL +ALF_LayoutSetColumnExpandNumerator(HWND parent, int colno, int expand) +{ + return (int)SendMessage(parent, ALF_WM_LYT_SETCOLEXPAND, (WPARAM)colno, (LPARAM)expand); } BOOL diff --git a/alf/alf.h b/alf/alf.h index a429472..4ebe205 100644 --- a/alf/alf.h +++ b/alf/alf.h @@ -25,11 +25,18 @@ typedef struct { } ALFWindowVTable; // layout flags -#define ALF_QUERYSIZE 0x01 -#define ALF_APPLYSIZE 0x02 -#define ALF_HEXPAND 0x04 -#define ALF_VEXPAND 0x08 -#define ALF_INHERITFONT 0x10 +#define ALF_LAYOUT_SIZE_FIXED 0x00 +#define ALF_LAYOUT_SIZE_QUERY 0x01 +#define ALF_LAYOUT_SIZE_PUSHBUTTON 0x04 /* unimplemented */ +#define ALF_LAYOUT_SIZE_STATICTEXT 0x05 /* unimplemented */ +#define ALF_LAYOUT_SIZE_EDIT 0x06 /* unimplemented */ +#define ALF_LAYOUT_SIZE_RADIOBUTTON 0x07 /* unimplemented */ +#define ALF_LAYOUT_SIZE_CHECKBOX 0x07 /* unimplemented */ +#define ALF_LAYOUT_SIZETYPE_MASK 0x0f +#define ALF_LAYOUT_INHERITFONT 0x10 +#define ALF_LAYOUT_CUSTOMPOS 0x20 +#define ALF_LAYOUT_SIZE_PX 0x40 + // label style flags #define ALF_LABEL_ALIGN_LEFT 0 @@ -57,12 +64,28 @@ typedef struct { #define ALF_WM_CENTIPOINTTOPX (ALF_WM__BASE + 9) #define ALF_WM_SETFOCUS (ALF_WM__BASE + 10) #define ALF_WM_APPLYSIZE (ALF_WM__BASE + 12) -#define ALF_WM_GETLAYOUTPARAMS (ALF_WM__BASE + 13) -#define ALF_WM_SETLAYOUTPARAMS (ALF_WM__BASE + 14) #define ALF_WM_GETWIDGETATPOS (ALF_WM__BASE + 15) #define ALF_WM_PRETRANSLATEMSG (ALF_WM__BASE + 16) #define ALF_WM_INVALIDATELAYOUT (ALF_WM__BASE + 17) #define ALF_WM_VALIDATELAYOUT (ALF_WM__BASE + 18) +#define ALF_WM_LYT_GETWIDGETPOS (ALF_WM__BASE + 19) +#define ALF_WM_LYT_SETWIDGETPOS (ALF_WM__BASE + 20) +#define ALF_WM_LYT_GETWIDGTSIZE (ALF_WM__BASE + 21) +#define ALF_WM_LYT_SETWIDGTSIZE (ALF_WM__BASE + 22) +#define ALF_WM_LYT_GETWDGTFLAGS (ALF_WM__BASE + 23) +#define ALF_WM_LYT_SETWDGTFLAGS (ALF_WM__BASE + 24) +#define ALF_WM_LYT_GETCOLSIZE (ALF_WM__BASE + 25) +#define ALF_WM_LYT_SETCOLSIZE (ALF_WM__BASE + 26) +#define ALF_WM_LYT_GETCOLEXPAND (ALF_WM__BASE + 27) +#define ALF_WM_LYT_SETCOLEXPAND (ALF_WM__BASE + 28) +#define ALF_WM_LYT_GETCOLFLAGS (ALF_WM__BASE + 29) +#define ALF_WM_LYT_SETCOLFLAGS (ALF_WM__BASE + 30) +#define ALF_WM_LYT_GETROWSIZE (ALF_WM__BASE + 31) +#define ALF_WM_LYT_SETROWSIZE (ALF_WM__BASE + 32) +#define ALF_WM_LYT_GETROWEXPAND (ALF_WM__BASE + 33) +#define ALF_WM_LYT_SETROWEXPAND (ALF_WM__BASE + 34) +#define ALF_WM_LYT_GETROWFLAGS (ALF_WM__BASE + 35) +#define ALF_WM_LYT_SETROWFLAGS (ALF_WM__BASE + 36) #define ALF_WM_LBL_GETSTYLE (ALF_WM__BASE + 201) #define ALF_WM_LBL_SETSTYLE (ALF_WM__BASE + 202) @@ -74,16 +97,6 @@ typedef struct { ALFWindowVTable vtbl; } ALFWindowClassParams; -typedef struct { - HWND hwnd; - UINT x; - UINT y; - UINT width; - UINT height; - DWORD flags; - UINT margins[4]; -} ALFWidgetLayoutParams; - typedef enum { ALF_DPI_AWARENESS_UNAWARE, ALF_DPI_AWARENESS_SYSTEM_AWARE, @@ -133,13 +146,13 @@ LRESULT ALF_DefWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); HWND -ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const TCHAR *text); +ALF_AddLabel(HWND win, WORD id, int x, int y, const TCHAR *text); HWND -ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const TCHAR *text); +ALF_AddEdit(HWND win, WORD id, int x, int y, const TCHAR *text); HWND -ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const TCHAR *text); +ALF_AddButton(HWND win, WORD id, int x, int y, const TCHAR *text); void ALF_SetDefaultButton(HWND win, WORD id); @@ -148,10 +161,7 @@ void ALF_DestroyWidget(HWND win, WORD id); void -ALF_AddWidget(HWND win, UINT x, UINT y, HWND widget, UINT cptWidth, UINT cptHeight, DWORD flags); - -void -ALF_AddWidgetEx(HWND win, const ALFWidgetLayoutParams *params); +ALF_AddWidget(HWND win, int x, int y, HWND widget, int width, int height, DWORD flags); HWND ALF_WidgetHwndById(HWND win, WORD id); @@ -211,27 +221,63 @@ ALF_RemoveWidgetLayoutFlag(HWND parent, HWND widget, DWORD flag) } BOOL -ALF_WidgetLayoutPosition(HWND parent, HWND widget, UINT *pX, UINT *pY); +ALF_WidgetLayoutPosition(HWND parent, HWND widget, int *pX, int *pY); BOOL -ALF_SetWidgetLayoutPosition(HWND parent, HWND widget, UINT x, UINT y); +ALF_SetWidgetLayoutPosition(HWND parent, HWND widget, int x, int y); BOOL -ALF_WidgetLayoutSize(HWND parent, HWND widget, UINT *pCptWidth, UINT *pCptHeight); +ALF_WidgetLayoutMinSize(HWND parent, HWND widget, int *pWidth, int *pheight); BOOL -ALF_SetWidgetLayoutSize(HWND parent, HWND widget, UINT cptWidth, UINT cptHeight); +ALF_SetWidgetLayoutMinSize(HWND parent, HWND widget, int width, int height); HWND -ALF_WidgetAtLayoutPosition(HWND parent, UINT x, UINT y); +ALF_WidgetAtLayoutPosition(HWND parent, int x, int y); + +int +ALF_LayoutRowMinSize(HWND parent, int rowno); + +BOOL +ALF_LayoutSetRowMinSize(HWND parent, int rowno, int rowsize); + +int +ALF_LayoutColumnMinSize(HWND parent, int colno); + +BOOL +ALF_LayoutSetColumnMinSize(HWND parent, int colno, int colsize); + +DWORD +ALF_LayoutRowFlags(HWND parent, int rowno); + +BOOL +ALF_LayoutSetRowFlags(HWND parent, int rowno, DWORD flags); + +DWORD +ALF_LayoutColumnFlags(HWND parent, int colno); + +BOOL +ALF_LayoutSetColumnFlags(HWND parent, int colno, DWORD flags); + +int +ALF_LayoutRowExpandNumerator(HWND parent, int rowno); + +BOOL +ALF_LayoutSetRowExpandNumerator(HWND parent, int rowno, int expand); + +int +ALF_LayoutColumnExpandNumerator(HWND parent, int colno); + +BOOL +ALF_LayoutSetColumnExpandNumerator(HWND parent, int colno, int expand); // combo box HWND -ALF_AddEditableComboBox(HWND win, WORD id, UINT x, UINT y, const TCHAR *defaultText); +ALF_AddEditableComboBox(HWND win, WORD id, int x, int y, const TCHAR *defaultText); HWND -ALF_AddSelectionOnlyComboBox(HWND win, WORD id, UINT x, UINT y); +ALF_AddSelectionOnlyComboBox(HWND win, WORD id, int x, int y); int /* index */ ALF_ComboBoxAddString(HWND combo, const TCHAR *text); @@ -259,15 +305,11 @@ ALF_ComboBoxSetText(HWND combo, const TCHAR *text); // panel HWND -ALF_AddPanel(HWND parent, WORD id, UINT x, UINT y); - -// spacer -HWND -ALF_AddSpacer(HWND parent, WORD id, UINT x, UINT y, UINT cptWidth, UINT cptHeight, DWORD layoutFlags); +ALF_AddPanel(HWND parent, WORD id, int x, int y); // tab control HWND -ALF_AddNotebook(HWND parent, WORD id, UINT x, UINT y); +ALF_AddNotebook(HWND parent, WORD id, int x, int y); HWND ALF_NotebookAddTab(HWND notebook, const TCHAR *title); diff --git a/alf/alfbutton.cpp b/alf/alfbutton.cpp index be9a276..67a7236 100644 --- a/alf/alfbutton.cpp +++ b/alf/alfbutton.cpp @@ -485,7 +485,7 @@ ALF__ButtonSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT } HWND -ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const TCHAR *text) +ALF_AddButton(HWND win, WORD id, int x, int y, const TCHAR *text) { HWND hwndButton = CreateWindowEx(0, TEXT("BUTTON"), @@ -505,16 +505,7 @@ ALF_AddButton(HWND win, WORD id, UINT x, UINT y, const TCHAR *text) SendMessage(hwndButton, WM_THEMECHANGED, 0, 0); - ALFWidgetLayoutParams p; - ZeroMemory(&p, sizeof(p)); - p.hwnd = hwndButton; - p.x = x; - p.y = y; - p.width = 0; - p.height = 0; - p.flags = ALF_QUERYSIZE | ALF_INHERITFONT; - - ALF_AddWidgetEx(win, &p); + ALF_AddWidget(win, x, y, hwndButton, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT); return hwndButton; } diff --git a/alf/alfcombobox.cpp b/alf/alfcombobox.cpp index 288e3a8..33a454c 100644 --- a/alf/alfcombobox.cpp +++ b/alf/alfcombobox.cpp @@ -288,7 +288,7 @@ ALF_RegisterComboClass(void) } static HWND -ALF_InternalAddComboBox(HWND win, WORD id, UINT x, UINT y, DWORD style, const TCHAR *defaultText) +ALF_InternalAddComboBox(HWND win, WORD id, int x, int y, DWORD style, const TCHAR *defaultText) { ALFComboCreateParams cp; cp.comboStyle = style; @@ -306,28 +306,19 @@ ALF_InternalAddComboBox(HWND win, WORD id, UINT x, UINT y, DWORD style, const TC if (defaultText) SetWindowText(hwndCombo, defaultText); - ALFWidgetLayoutParams p; - ZeroMemory(&p, sizeof(p)); - p.hwnd = hwndCombo; - p.x = x; - p.y = y; - p.width = 0; - p.height = 0; - p.flags = ALF_QUERYSIZE | ALF_INHERITFONT; - - ALF_AddWidgetEx(win, &p); + ALF_AddWidget(win, x, y, hwndCombo, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT); return hwndCombo; } HWND -ALF_AddEditableComboBox(HWND win, WORD id, UINT x, UINT y, const TCHAR *defaultText) +ALF_AddEditableComboBox(HWND win, WORD id, int x, int y, const TCHAR *defaultText) { return ALF_InternalAddComboBox(win, id, x, y, CBS_DROPDOWN, defaultText); } HWND -ALF_AddSelectionOnlyComboBox(HWND win, WORD id, UINT x, UINT y) +ALF_AddSelectionOnlyComboBox(HWND win, WORD id, int x, int y) { return ALF_InternalAddComboBox(win, id, x, y, CBS_DROPDOWNLIST, NULL); } diff --git a/alf/alfedit.cpp b/alf/alfedit.cpp index ac12e38..afd4d08 100644 --- a/alf/alfedit.cpp +++ b/alf/alfedit.cpp @@ -52,7 +52,7 @@ ALF__EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_P } HWND -ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const TCHAR *text) +ALF_AddEdit(HWND win, WORD id, int x, int y, const TCHAR *text) { DWORD exstyle; DWORD style; @@ -78,16 +78,7 @@ ALF_AddEdit(HWND win, WORD id, UINT x, UINT y, const TCHAR *text) ALF_Compat_SetWindowSubclass(hwndEdit, ALF__EditSubclassProc, 0, 0); SetWindowPos(hwndEdit, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_FRAMECHANGED); - ALFWidgetLayoutParams p; - ZeroMemory(&p, sizeof(p)); - p.hwnd = hwndEdit; - p.x = x; - p.y = y; - p.width = 0; - p.height = 0; - p.flags = ALF_QUERYSIZE | ALF_APPLYSIZE | ALF_INHERITFONT; - - ALF_AddWidgetEx(win, &p); + ALF_AddWidget(win, x, y, hwndEdit, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_CUSTOMPOS | ALF_LAYOUT_INHERITFONT); return hwndEdit; } diff --git a/alf/alflabel.cpp b/alf/alflabel.cpp index f400f4f..b0abc4b 100644 --- a/alf/alflabel.cpp +++ b/alf/alflabel.cpp @@ -212,7 +212,7 @@ ALF__LabelWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } HWND -ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const TCHAR *text) +ALF_AddLabel(HWND win, WORD id, int x, int y, const TCHAR *text) { HWND hwndLabel = CreateWindow(_alf_labelClass, text, @@ -227,16 +227,7 @@ ALF_AddLabel(HWND win, WORD id, UINT x, UINT y, const TCHAR *text) priv->style = ALF_LABEL_ALIGN_LEFT | ALF_LABEL_ALIGN_TOP_LIKE_EDIT; SetWindowLongPtr(hwndLabel, 0, (LONG_PTR)priv); - ALFWidgetLayoutParams p; - ZeroMemory(&p, sizeof(p)); - p.hwnd = hwndLabel; - p.x = x; - p.y = y; - p.width = 0; - p.height = 0; - p.flags = ALF_QUERYSIZE | ALF_INHERITFONT; - - ALF_AddWidgetEx(win, &p); + ALF_AddWidget(win, x, y, hwndLabel, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT); return hwndLabel; } diff --git a/alf/alflayout.cpp b/alf/alflayout.cpp index b98ae93..ce5909f 100644 --- a/alf/alflayout.cpp +++ b/alf/alflayout.cpp @@ -3,11 +3,76 @@ static void ALF_Layout_CalcSizes(ALFLayout *layout, HWND window); +static void +ALF_Layout_EnsureRowExists(ALFLayout *layout, int rowno); + +static void +ALF_Layout_EnsureColumnExists(ALFLayout *layout, int colno); + +static BOOL +ALF_Layout_GetWidgetPos(ALFLayout *layout, HWND window, HWND needle, POINT *p); + +static BOOL +ALF_Layout_SetWidgetPos(ALFLayout *layout, HWND window, HWND needle, POINT *p); + +static BOOL +ALF_Layout_GetWidgetSize(ALFLayout *layout, HWND window, HWND needle, SIZE *s); + +static BOOL +ALF_Layout_SetWidgetSize(ALFLayout *layout, HWND window, HWND needle, SIZE *s); + +static DWORD +ALF_Layout_GetWidgetFlags(ALFLayout *layout, HWND window, HWND needle); + +static BOOL +ALF_Layout_SetWidgetFlags(ALFLayout *layout, HWND window, HWND needle, DWORD flags); + +static int +ALF_Layout_GetColumnSize(ALFLayout *layout, HWND window, int colno); + +static BOOL +ALF_Layout_SetColumnSize(ALFLayout *layout, HWND window, int colno, int size); + +static int +ALF_Layout_GetColumnExpand(ALFLayout *layout, HWND window, int colno); + +static BOOL +ALF_Layout_SetColumnExpand(ALFLayout *layout, HWND window, int colno, int expand); + +static DWORD +ALF_Layout_GetColumnFlags(ALFLayout *layout, HWND window, int colno); + +static BOOL +ALF_Layout_SetColumnFlags(ALFLayout *layout, HWND window, int colno, DWORD flags); + +static int +ALF_Layout_GetRowSize(ALFLayout *layout, HWND window, int rowno); + +static BOOL +ALF_Layout_SetRowSize(ALFLayout *layout, HWND window, int rowno, int size); + +static int +ALF_Layout_GetRowExpand(ALFLayout *layout, HWND window, int rowno); + +static BOOL +ALF_Layout_SetRowExpand(ALFLayout *layout, HWND window, int rowno, int expand); + +static DWORD +ALF_Layout_GetRowFlags(ALFLayout *layout, HWND window, int rowno); + +static BOOL +ALF_Layout_SetRowFlags(ALFLayout *layout, HWND window, int rowno, DWORD flags); + void ALF_Layout_Init(ALFLayout *layout) { ZeroMemory(layout, sizeof(*layout)); ALF_ListInit(&layout->widgets); + + layout->nRows = 1; + layout->rows = ALF_New(ALFLayoutRowOrColumn, layout->nRows); + layout->nColumns = 1; + layout->columns = ALF_New(ALFLayoutRowOrColumn, layout->nColumns); } void @@ -31,108 +96,148 @@ ALF_Layout_ForwardFont(ALFLayout *layout, HWND window, HFONT font, LPARAM redraw (void)window; ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, i) { - if (i->flags & ALF_INHERITFONT) { + if (i->flags & ALF_LAYOUT_INHERITFONT) { SendMessage(i->hwnd, WM_SETFONT, (WPARAM)font, redraw); } } } void -ALF_Layout_CalcSizes(ALFLayout* layout, HWND window) +ALF_Layout_EnsureRowExists(ALFLayout *layout, int rowno) { - for (int i = 0; i < layout->nColumns; ++i) { - ZeroMemory(&layout->columns[i], sizeof(layout->columns[i])); + while (rowno >= layout->nRows) { + layout->nRows *= 2; + layout->rows = ALF_ReNew(layout->rows, ALFLayoutRowOrColumn, layout->nRows); } - for (int i = 0; i < layout->nRows; ++i) { - ZeroMemory(&layout->rows[i], sizeof(layout->rows[i])); +} + +void +ALF_Layout_EnsureColumnExists(ALFLayout *layout, int colno) +{ + while (colno >= layout->nColumns) { + layout->nColumns *= 2; + layout->columns = ALF_ReNew(layout->columns, ALFLayoutRowOrColumn, layout->nColumns); } +} - ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, c) { - while ((int)c->x >= layout->nColumns) { - // FIXME! overflow, use reallocarray(2) equivalent - if (layout->nColumns == 0) { - layout->nColumns = 1; - layout->columns = ALF_New(ALFLayoutRowOrColumn, layout->nColumns); - } else { - layout->nColumns *= 2; - layout->columns = ALF_ReNew(layout->columns, ALFLayoutRowOrColumn, layout->nColumns); - } - } - while ((int)c->y >= layout->nRows) { - // FIXME! overflow, use reallocarray(2) equivalent - if (layout->nRows == 0) { - layout->nRows = 1; - layout->rows = ALF_New(ALFLayoutRowOrColumn, layout->nRows); - } else { - layout->nRows *= 2; - layout->rows = ALF_ReNew(layout->rows, ALFLayoutRowOrColumn, layout->nRows); - } +static void +ALF_Layout_CalcMinWidgetSize(ALFWidgetPriv *c, HWND window, SIZE *s) +{ + if (c->flags & ALF_LAYOUT_SIZE_PX) { + s->cx = c->width; + s->cy = c->height; + } else { + s->cx = ALF_CentipointsToPixels(window, c->width); + s->cy = ALF_CentipointsToPixels(window, c->height); + } + + switch (c->flags & ALF_LAYOUT_SIZETYPE_MASK) { + case ALF_LAYOUT_SIZE_FIXED: + // already done + break; + case ALF_LAYOUT_SIZE_QUERY: + SendMessage(c->hwnd, ALF_WM_QUERYSIZE, 0, (LPARAM)s); + break; + default: + // FIXME! unimplemented + break; + } +} + +void +ALF_Layout_CalcSizes(ALFLayout* layout, HWND window) +{ + layout->biggestColumnNo = 0; + layout->columnExpandDenominator = 0; + for (int i = 0; i < layout->nColumns; ++i) { + if (layout->columns[i].requestedFlags & ALF_LAYOUT_SIZE_PX) { + layout->columns[i].calculatedMinWidth = layout->columns[i].requestedMinWidth; + } else { + layout->columns[i].calculatedMinWidth = ALF_CentipointsToPixels(window, layout->columns[i].requestedMinWidth); } - // TODO: ignore spanning cell + layout->columns[i].calculatedExpandNumerator = layout->columns[i].requestedExpandNumerator; + layout->columnExpandDenominator += layout->columns[i].requestedExpandNumerator; - SIZE qs = { ALF_CentipointsToPixels(window, c->cptWidth), - ALF_CentipointsToPixels(window, c->cptHeight) }; - if ((c->flags & ALF_QUERYSIZE) == ALF_QUERYSIZE) { - SendMessage(c->hwnd, ALF_WM_QUERYSIZE, 0, (LPARAM)&qs); + if (layout->columns[i].requestedExpandNumerator >= layout->columns[layout->biggestColumnNo].requestedExpandNumerator) + layout->biggestColumnNo = i; + } + layout->biggestRowNo = 0; + layout->rowExpandDenominator = 0; + for (int i = 0; i < layout->nRows; ++i) { + if (layout->rows[i].requestedFlags & ALF_LAYOUT_SIZE_PX) { + layout->rows[i].calculatedMinWidth = layout->rows[i].requestedMinWidth; + } else { + layout->rows[i].calculatedMinWidth = ALF_CentipointsToPixels(window, layout->rows[i].requestedMinWidth); } + layout->rows[i].calculatedExpandNumerator = layout->rows[i].requestedExpandNumerator; + layout->rowExpandDenominator += layout->rows[i].requestedExpandNumerator; + + if (layout->rows[i].requestedExpandNumerator >= layout->rows[layout->biggestRowNo].requestedExpandNumerator) + layout->biggestRowNo = i; + } + + ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, c) { + int col = c->x; // TODO: skip spanning cells + int row = c->y; - qs.cx += ALF_CentipointsToPixels(window, c->cptMarginLeft); - qs.cx += ALF_CentipointsToPixels(window, c->cptMarginRight); - qs.cy += ALF_CentipointsToPixels(window, c->cptMarginTop); - qs.cy += ALF_CentipointsToPixels(window, c->cptMarginBottom); + ALF_Layout_EnsureColumnExists(layout, col); + ALF_Layout_EnsureRowExists(layout, row); - if (qs.cx > layout->columns[c->x].minWidth) - layout->columns[c->x].minWidth = qs.cx; - if (qs.cy > layout->rows[c->y].minWidth) - layout->rows[c->y].minWidth = qs.cy; + SIZE qs = { 0, 0 }; + ALF_Layout_CalcMinWidgetSize(c, window, &qs); - // expand flag - if (c->flags & ALF_HEXPAND) - layout->columns[c->x].expand = 1; - if (c->flags & ALF_VEXPAND) - layout->rows[c->y].expand = 1; + if (qs.cx > layout->columns[col].calculatedMinWidth) + layout->columns[col].calculatedMinWidth = qs.cx; + if (qs.cy > layout->rows[row].calculatedMinWidth) + layout->rows[row].calculatedMinWidth = qs.cy; } // TODO: second pass for spanning cells - // update min width bookkeeping + // total minimum bookkeeping layout->totalMinWidth = 0; - layout->expandoColumnCount = 0; for (int i = 0; i < layout->nColumns; ++i) { - layout->totalMinWidth += layout->columns[i].minWidth; + layout->totalMinWidth += layout->columns[i].calculatedMinWidth; + } - if (layout->columns[i].expand) - layout->expandoColumnCount++; + layout->totalMinHeight = 0; + for (int i = 0; i < layout->nRows; ++i) { + layout->totalMinHeight += layout->rows[i].calculatedMinWidth; } - if (layout->expandoColumnCount == 0) { - // mark all columns as expanding + // expando bookkeeping if no expand numerators specified + if (layout->columnExpandDenominator == 0) { for (int i = 0; i < layout->nColumns; ++i) { - if (layout->columns[i].minWidth > 0) { - layout->columns[i].expand = 1; - layout->expandoColumnCount++; + if (layout->columns[i].calculatedMinWidth > 0) { + layout->columnExpandDenominator += 1; + layout->columns[i].calculatedExpandNumerator = 1; + layout->biggestColumnNo = i; } } - } - - layout->totalMinHeight = 0; - layout->expandoRowCount = 0; - for (int i = 0; i < layout->nRows; ++i) { - layout->totalMinHeight += layout->rows[i].minWidth; - if (layout->rows[i].expand) - layout->expandoRowCount++; + // all columns empty? expand first one then + if (layout->columnExpandDenominator == 0) { + layout->columnExpandDenominator = 1; + layout->columns[0].calculatedExpandNumerator = 1; + layout->biggestColumnNo = 0; + } } - - if (layout->expandoRowCount == 0) { - // mark all rows as expanding + if (layout->rowExpandDenominator == 0) { for (int i = 0; i < layout->nRows; ++i) { - if (layout->rows[i].minWidth > 0) { - layout->rows[i].expand = 1; - layout->expandoRowCount++; + if (layout->rows[i].calculatedMinWidth > 0) { + layout->rowExpandDenominator += 1; + layout->rows[i].calculatedExpandNumerator = 1; + layout->biggestRowNo = i; } } + + // all rows empty? expand first one then + if (layout->rowExpandDenominator == 0) { + layout->rowExpandDenominator = 1; + layout->rows[0].calculatedExpandNumerator = 1; + layout->biggestRowNo = 0; + } } layout->layoutValididityFlags &= ~ALF_LAYOUT_NEED_RECALC; @@ -144,8 +249,7 @@ ALF_Layout_Apply(ALFLayout* layout, HWND window) if (layout->layoutValididityFlags & ALF_LAYOUT_NEED_RECALC) ALF_Layout_CalcSizes(layout, window); - // allocate cell positions - // distribute free space + // distribute extra space int extraWidth = 0; int extraHeight = 0; RECT client; @@ -156,77 +260,64 @@ ALF_Layout_Apply(ALFLayout* layout, HWND window) extraHeight = client.bottom - client.top - layout->totalMinHeight; } - int extraWidthPart = 0; - int extraWidthError = 0; - if (layout->expandoColumnCount) { - extraWidthPart = extraWidth / layout->expandoColumnCount; - extraWidthError = extraWidth - extraWidthPart * layout->expandoColumnCount; - } - + int extraWidthLeft = extraWidth; for (int i = 0; i < layout->nColumns; ++i) { - layout->columns[i].allocatedWidth = layout->columns[i].minWidth; + if (i == layout->biggestColumnNo) + continue; - if (layout->columns[i].expand) { - layout->columns[i].allocatedWidth += extraWidthPart; - if (extraWidthError) { - layout->columns[i].allocatedWidth++; - extraWidthError--; - } - } + int extraHere = MulDiv(extraWidth, layout->columns[i].calculatedExpandNumerator, layout->columnExpandDenominator); + if (extraHere > extraWidthLeft) + extraHere = extraWidthLeft; - if (i == 0) { - layout->columns[i].allocatedPosition = 0; - } else { - layout->columns[i].allocatedPosition = - layout->columns[i-1].allocatedPosition + layout->columns[i-1].allocatedWidth; - } + layout->columns[i].allocatedWidth = layout->columns[i].calculatedMinWidth + extraHere; + extraWidthLeft -= extraHere; } + layout->columns[layout->biggestColumnNo].allocatedWidth = + layout->columns[layout->biggestColumnNo].calculatedMinWidth + extraWidthLeft; + + int extraHeightLeft = extraHeight; + for (int i = 0; i < layout->nRows; ++i) { + if (i == layout->biggestRowNo) + continue; + int extraHere = MulDiv(extraHeight, layout->rows[i].calculatedExpandNumerator, layout->rowExpandDenominator); + if (extraHere > extraHeightLeft) + extraHere = extraHeightLeft; - int extraHeightPart = 0; - int extraHeightError = 0; - if (layout->expandoRowCount) { - extraHeightPart = extraHeight / layout->expandoRowCount; - extraHeightError = extraHeight - extraHeightPart * layout->expandoRowCount; + layout->rows[i].allocatedWidth = layout->rows[i].calculatedMinWidth + extraHere; + extraHeightLeft -= extraHere; } + layout->rows[layout->biggestRowNo].allocatedWidth = + layout->rows[layout->biggestRowNo].calculatedMinWidth + extraHeightLeft; + // set row/column positions + int x = 0; + for (int i = 0; i < layout->nColumns; ++i) { + layout->columns[i].allocatedPosition = x; + x += layout->columns[i].allocatedWidth; + } + int y = 0; for (int i = 0; i < layout->nRows; ++i) { - layout->rows[i].allocatedWidth = layout->rows[i].minWidth; - - if (layout->rows[i].expand) { - layout->rows[i].allocatedWidth += extraHeightPart; - if (extraHeightError) { - layout->rows[i].allocatedWidth++; - extraHeightError--; - } - } - - if (i == 0) { - layout->rows[i].allocatedPosition = 0; - } else { - layout->rows[i].allocatedPosition = - layout->rows[i-1].allocatedPosition + layout->rows[i-1].allocatedWidth; - } + layout->rows[i].allocatedPosition = y; + y += layout->rows[i].allocatedWidth; } + // now apply positions to widgets HDWP hdwp = BeginDeferWindowPos(layout->nColumns * layout->nRows); ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, c) { - if ((int)c->x >= layout->nColumns || (int)c->y >= layout->nRows) - continue; - - int marginleft = ALF_CentipointsToPixels(window, c->cptMarginLeft); - int marginright = ALF_CentipointsToPixels(window, c->cptMarginRight); - int margintop = ALF_CentipointsToPixels(window, c->cptMarginTop); - int marginbottom = ALF_CentipointsToPixels(window, c->cptMarginBottom); + int col = c->x; + int row = c->y; + if (col >= layout->nColumns || row >= layout->nRows) + continue; // FIXME! can that actually happen? RECT r = { 0,0,0,0 }; - r.left = layout->columns[c->x].allocatedPosition + marginleft; - r.right = r.left + layout->columns[c->x].allocatedWidth - marginleft - marginright; - r.top = layout->rows[c->y].allocatedPosition + margintop; - r.bottom = r.top + layout->rows[c->y].allocatedWidth - margintop - marginbottom; + r.left = layout->columns[col].allocatedPosition; + r.right = r.left + layout->columns[col].allocatedWidth; + r.top = layout->rows[row].allocatedPosition; + r.bottom = r.top + layout->rows[row].allocatedWidth; - if (c->flags & ALF_APPLYSIZE) { + if (c->flags & ALF_LAYOUT_CUSTOMPOS) { hdwp = (HDWP)SendMessage(c->hwnd, ALF_WM_APPLYSIZE, (WPARAM)hdwp, (LPARAM)&r); } else { hdwp = DeferWindowPos(hdwp, @@ -242,24 +333,20 @@ ALF_Layout_Apply(ALFLayout* layout, HWND window) } void -ALF_Layout_AddWidget(ALFLayout* layout, HWND window, const ALFWidgetLayoutParams* params) +ALF_Layout_AddWidget(ALFLayout* layout, HWND window, const ALFAddWidgetParams* params) { ALFWidgetPriv *w = ALF_New(ALFWidgetPriv, 1); w->hwnd = params->hwnd; w->x = params->x; w->y = params->y; - w->cptWidth = params->width; - w->cptHeight = params->height; + w->width = params->width; + w->height = params->height; w->flags = params->flags; - w->cptMarginTop = params->margins[0]; - w->cptMarginRight = params->margins[1]; - w->cptMarginBottom = params->margins[2]; - w->cptMarginLeft = params->margins[3]; if (GetParent(w->hwnd) != window) SetParent(w->hwnd, window); - if (w->flags & ALF_INHERITFONT) { + if (w->flags & ALF_LAYOUT_INHERITFONT) { SendMessage(w->hwnd, WM_SETFONT, (WPARAM)SendMessage(window, WM_GETFONT, 0, 0), 0); } @@ -268,59 +355,8 @@ ALF_Layout_AddWidget(ALFLayout* layout, HWND window, const ALFWidgetLayoutParams ALF_InvalidateLayout(window); } -BOOL -ALF_Layout_SetWidgetParams(ALFLayout* layout, HWND window, const ALFWidgetLayoutParams* params, HWND widget) -{ - ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, w) { - if (w->hwnd == widget) { - w->hwnd = params->hwnd; - w->x = params->x; - w->y = params->y; - w->cptWidth = params->width; - w->cptHeight = params->height; - w->flags = params->flags; - w->cptMarginTop = params->margins[0]; - w->cptMarginRight = params->margins[1]; - w->cptMarginBottom = params->margins[2]; - w->cptMarginLeft = params->margins[3]; - - if (w->flags & ALF_INHERITFONT) - SendMessage(w->hwnd, WM_SETFONT, (WPARAM)SendMessage(window, WM_GETFONT, 0, 0), 0); - - ALF_InvalidateLayout(window); - - return TRUE; - } - } - - return FALSE; -} - -BOOL -ALF_Layout_GetWidgetParams(ALFLayout* layout, ALFWidgetLayoutParams* params, HWND widget) -{ - ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, w) { - if (w->hwnd == widget) { - params->hwnd = w->hwnd; - params->x = w->x; - params->y = w->y; - params->width = w->cptWidth; - params->height = w->cptHeight; - params->flags = w->flags; - params->margins[0] = w->cptMarginTop; - params->margins[1] = w->cptMarginRight; - params->margins[2] = w->cptMarginBottom; - params->margins[3] = w->cptMarginLeft; - - return TRUE; - } - } - - return FALSE; -} - HWND -ALF_Layout_WidgetAtPos(ALFLayout* layout, UINT x, UINT y) +ALF_Layout_WidgetAtPos(ALFLayout* layout, int x, int y) { ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, w) { if (w->x == x && w->y == y) { @@ -377,6 +413,244 @@ ALF_Layout_GetMinSize(ALFLayout *layout, HWND window, SIZE *size) size->cy = layout->totalMinHeight; } +BOOL +ALF_Layout_GetWidgetPos(ALFLayout *layout, HWND window, HWND needle, POINT *p) +{ + (void)window; + + ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, w) { + if (w->hwnd == needle) { + p->x = w->x; + p->y = w->y; + return TRUE; + } + } + + return FALSE; +} + +static BOOL +ALF_Layout_SetWidgetPos(ALFLayout *layout, HWND window, HWND needle, POINT *p) +{ + ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, w) { + if (w->hwnd == needle) { + w->x = p->x; + w->y = p->y; + + ALF_InvalidateLayout(window); + + return TRUE; + } + } + + return FALSE; +} + +static BOOL +ALF_Layout_GetWidgetSize(ALFLayout *layout, HWND window, HWND needle, SIZE *s) +{ + (void)window; + + ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, w) { + if (w->hwnd == needle) { + s->cx = w->width; + s->cy = w->height; + return TRUE; + } + } + + return FALSE; +} + +static BOOL +ALF_Layout_SetWidgetSize(ALFLayout *layout, HWND window, HWND needle, SIZE *s) +{ + ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, w) { + if (w->hwnd == needle) { + w->width = s->cx; + w->height = s->cy; + + ALF_InvalidateLayout(window); + + return TRUE; + } + } + + return FALSE; +} + +static DWORD +ALF_Layout_GetWidgetFlags(ALFLayout *layout, HWND window, HWND needle) +{ + (void)window; + + ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, w) { + if (w->hwnd == needle) { + return w->flags; + } + } + + return 0; +} + +static BOOL +ALF_Layout_SetWidgetFlags(ALFLayout *layout, HWND window, HWND needle, DWORD flags) +{ + ALF_FOR_LIST(ALFWidgetPriv, list, &layout->widgets, w) { + if (w->hwnd == needle) { + w->flags = flags; + + if (flags & ALF_LAYOUT_INHERITFONT) + SendMessage(w->hwnd, WM_SETFONT, (LPARAM)SendMessage(window, WM_GETFONT, 0, 0), 0); + + ALF_InvalidateLayout(window); + + return TRUE; + } + } + + return FALSE; +} + +int +ALF_Layout_GetColumnSize(ALFLayout *layout, HWND window, int colno) +{ + (void)window; + + if (colno >= layout->nColumns) + return 0; + + return layout->columns[colno].requestedMinWidth; +} + +BOOL +ALF_Layout_SetColumnSize(ALFLayout *layout, HWND window, int colno, int size) +{ + ALF_Layout_EnsureColumnExists(layout, colno); + + layout->columns[colno].requestedMinWidth = size; + + ALF_InvalidateLayout(window); + + return TRUE; +} + +int +ALF_Layout_GetColumnExpand(ALFLayout *layout, HWND window, int colno) +{ + (void)window; + + if (colno >= layout->nColumns) + return 0; + + return layout->columns[colno].requestedExpandNumerator; +} + +static BOOL +ALF_Layout_SetColumnExpand(ALFLayout *layout, HWND window, int colno, int expand) +{ + ALF_Layout_EnsureColumnExists(layout, colno); + + layout->columns[colno].requestedExpandNumerator = expand; + + ALF_InvalidateLayout(window); + + return TRUE; +} + +static DWORD +ALF_Layout_GetColumnFlags(ALFLayout *layout, HWND window, int colno) +{ + (void)window; + + if (colno >= layout->nColumns) + return 0; + + return layout->columns[colno].requestedFlags; +} + +static BOOL +ALF_Layout_SetColumnFlags(ALFLayout *layout, HWND window, int colno, DWORD flags) +{ + ALF_Layout_EnsureColumnExists(layout, colno); + + layout->columns[colno].requestedFlags = flags; + + ALF_InvalidateLayout(window); + + return TRUE; +} + +static int +ALF_Layout_GetRowSize(ALFLayout *layout, HWND window, int rowno) +{ + (void)window; + + if (rowno >= layout->nRows) + return 0; + + return layout->rows[rowno].requestedMinWidth; +} + +static BOOL +ALF_Layout_SetRowSize(ALFLayout *layout, HWND window, int rowno, int size) +{ + ALF_Layout_EnsureRowExists(layout, rowno); + + layout->rows[rowno].requestedMinWidth = size; + + ALF_InvalidateLayout(window); + + return TRUE; +} + +static int +ALF_Layout_GetRowExpand(ALFLayout *layout, HWND window, int rowno) +{ + (void)window; + + if (rowno >= layout->nRows) + return 0; + + return layout->rows[rowno].requestedExpandNumerator; +} + +static BOOL +ALF_Layout_SetRowExpand(ALFLayout *layout, HWND window, int rowno, int expand) +{ + ALF_Layout_EnsureRowExists(layout, rowno); + + layout->rows[rowno].requestedExpandNumerator = expand; + + ALF_InvalidateLayout(window); + + return TRUE; +} + +static DWORD +ALF_Layout_GetRowFlags(ALFLayout *layout, HWND window, int rowno) +{ + (void)window; + + if (rowno >= layout->nRows) + return 0; + + return layout->rows[rowno].requestedFlags; +} + +static BOOL +ALF_Layout_SetRowFlags(ALFLayout *layout, HWND window, int rowno, DWORD flags) +{ + ALF_Layout_EnsureRowExists(layout, rowno); + + layout->rows[rowno].requestedFlags = flags; + + ALF_InvalidateLayout(window); + + return TRUE; +} + + BOOL ALF_Layout_HandleMessage(ALFLayout *layout, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, LRESULT *pRet) { @@ -393,22 +667,12 @@ ALF_Layout_HandleMessage(ALFLayout *layout, HWND hwnd, UINT msg, WPARAM wparam, } if (msg == ALF_WM_ADDWIDGET) { - ALF_Layout_AddWidget(layout, hwnd, (ALFWidgetLayoutParams *)lparam); - return TRUE; - } - - if (msg == ALF_WM_GETLAYOUTPARAMS) { - *pRet = (LRESULT)ALF_Layout_GetWidgetParams(layout, (ALFWidgetLayoutParams *)lparam, (HWND)wparam); - return TRUE; - } - - if (msg == ALF_WM_SETLAYOUTPARAMS) { - *pRet = (LRESULT)ALF_Layout_SetWidgetParams(layout, hwnd, (const ALFWidgetLayoutParams *)lparam, (HWND)wparam); + ALF_Layout_AddWidget(layout, hwnd, (ALFAddWidgetParams *)lparam); return TRUE; } if (msg == ALF_WM_GETWIDGETATPOS) { - *pRet = (LRESULT)ALF_Layout_WidgetAtPos(layout, ((UINT*)lparam)[0], ((UINT*)lparam)[1]); + *pRet = (LRESULT)ALF_Layout_WidgetAtPos(layout, ((int*)lparam)[0], ((int*)lparam)[1]); return TRUE; } @@ -427,5 +691,95 @@ ALF_Layout_HandleMessage(ALFLayout *layout, HWND hwnd, UINT msg, WPARAM wparam, return TRUE; } + if (msg == ALF_WM_LYT_GETWIDGETPOS) { + *pRet = (LRESULT)ALF_Layout_GetWidgetPos(layout, hwnd, (HWND)wparam, (POINT *)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_SETWIDGETPOS) { + *pRet = (LRESULT)ALF_Layout_SetWidgetPos(layout, hwnd, (HWND)wparam, (POINT *)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_GETWIDGTSIZE) { + *pRet = (LRESULT)ALF_Layout_GetWidgetSize(layout, hwnd, (HWND)wparam, (SIZE *)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_SETWIDGTSIZE) { + *pRet = (LRESULT)ALF_Layout_SetWidgetSize(layout, hwnd, (HWND)wparam, (SIZE *)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_GETWDGTFLAGS) { + *pRet = (LRESULT)ALF_Layout_GetWidgetFlags(layout, hwnd, (HWND)wparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_SETWDGTFLAGS) { + *pRet = (LRESULT)ALF_Layout_SetWidgetFlags(layout, hwnd, (HWND)wparam, (DWORD)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_GETCOLSIZE) { + *pRet = (LRESULT)ALF_Layout_GetColumnSize(layout, hwnd, (int)wparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_SETCOLSIZE) { + *pRet = (LRESULT)ALF_Layout_SetColumnSize(layout, hwnd, (int)wparam, (int)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_GETCOLEXPAND) { + *pRet = (LRESULT)ALF_Layout_GetColumnExpand(layout, hwnd, (int)wparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_SETCOLEXPAND) { + *pRet = (LRESULT)ALF_Layout_SetColumnExpand(layout, hwnd, (int)wparam, (int)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_GETCOLFLAGS) { + *pRet = (LRESULT)ALF_Layout_GetColumnFlags(layout, hwnd, (int)wparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_SETCOLFLAGS) { + *pRet = (LRESULT)ALF_Layout_SetColumnFlags(layout, hwnd, (int)wparam, (int)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_GETROWSIZE) { + *pRet = (LRESULT)ALF_Layout_GetRowSize(layout, hwnd, (int)wparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_SETROWSIZE) { + *pRet = (LRESULT)ALF_Layout_SetRowSize(layout, hwnd, (int)wparam, (int)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_GETROWEXPAND) { + *pRet = (LRESULT)ALF_Layout_GetRowExpand(layout, hwnd, (int)wparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_SETROWEXPAND) { + *pRet = (LRESULT)ALF_Layout_SetRowExpand(layout, hwnd, (int)wparam, (int)lparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_GETROWFLAGS) { + *pRet = (LRESULT)ALF_Layout_GetRowFlags(layout, hwnd, (int)wparam); + return TRUE; + } + + if (msg == ALF_WM_LYT_SETROWFLAGS) { + *pRet = (LRESULT)ALF_Layout_SetRowFlags(layout, hwnd, (int)wparam, (int)lparam); + return TRUE; + } + return FALSE; } diff --git a/alf/alflayout.h b/alf/alflayout.h index e326490..10fa09d 100644 --- a/alf/alflayout.h +++ b/alf/alflayout.h @@ -6,22 +6,35 @@ typedef struct { ALFListHeader list; HWND hwnd; - UINT x; - UINT y; - UINT cptWidth; - UINT cptHeight; - UINT cptMarginTop; - UINT cptMarginRight; - UINT cptMarginBottom; - UINT cptMarginLeft; + int x; + int y; + int width; + int height; DWORD flags; } ALFWidgetPriv; typedef struct { - int minWidth; + HWND hwnd; + int x; + int y; + int width; + int height; + DWORD flags; +} ALFAddWidgetParams; + +typedef struct { + // properties set by user + int requestedMinWidth; + int requestedExpandNumerator; + int requestedFlags; + + // calculated properties + int calculatedMinWidth; + int calculatedExpandNumerator; + + // allocated size for layout application int allocatedWidth; int allocatedPosition; - int expand : 1; } ALFLayoutRowOrColumn; #define ALF_LAYOUT_NEED_RECALC ((DWORD)1) @@ -35,8 +48,10 @@ typedef struct { int nRows; int totalMinWidth; int totalMinHeight; - int expandoColumnCount; - int expandoRowCount; + int columnExpandDenominator; + int rowExpandDenominator; + int biggestColumnNo; + int biggestRowNo; DWORD layoutValididityFlags; } ALFLayout; @@ -53,22 +68,16 @@ void ALF_Layout_Apply(ALFLayout *layout, HWND window); void -ALF_Layout_AddWidget(ALFLayout *layout, HWND window, const ALFWidgetLayoutParams *params); +ALF_Layout_AddWidget(ALFLayout *layout, HWND window, const ALFAddWidgetParams *params); BOOL ALF_Layout_RemoveWidget(ALFLayout *layout, HWND window, HWND widget, BOOL destroy); -BOOL -ALF_Layout_SetWidgetParams(ALFLayout *layout, HWND window, const ALFWidgetLayoutParams *params, HWND widget); - -BOOL -ALF_Layout_GetWidgetParams(ALFLayout *layout, ALFWidgetLayoutParams *params, HWND widget); - BOOL ALF_Layout_HandleMessage(ALFLayout *layout, HWND window, UINT msg, WPARAM wparam, LPARAM lparam, LRESULT *ret); HWND -ALF_Layout_WidgetAtPos(ALFLayout *layout, UINT x, UINT y); +ALF_Layout_WidgetAtPos(ALFLayout *layout, int x, int y); void ALF_Layout_Invalidate(ALFLayout *layout, HWND window); diff --git a/alf/alfnotebook.cpp b/alf/alfnotebook.cpp index 25e2904..8eaea6b 100644 --- a/alf/alfnotebook.cpp +++ b/alf/alfnotebook.cpp @@ -322,7 +322,7 @@ ALF_RegisterNotebookClass(void) // tab control HWND -ALF_AddNotebook(HWND parent, WORD id, UINT x, UINT y) +ALF_AddNotebook(HWND parent, WORD id, int x, int y) { HWND hwndNtbk = CreateWindowEx(WS_EX_CONTROLPARENT, _alf_notebookClass, @@ -334,16 +334,7 @@ ALF_AddNotebook(HWND parent, WORD id, UINT x, UINT y) ALF_HINSTANCE, NULL); - ALFWidgetLayoutParams p; - ZeroMemory(&p, sizeof(p)); - p.hwnd = hwndNtbk; - p.x = x; - p.y = y; - p.width = 0; - p.height = 0; - p.flags = ALF_QUERYSIZE | ALF_INHERITFONT; - - ALF_AddWidgetEx(parent, &p); + ALF_AddWidget(parent, x, y, hwndNtbk, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT); return hwndNtbk; } diff --git a/alf/alfpanel.cpp b/alf/alfpanel.cpp index 076bd9f..bd48721 100644 --- a/alf/alfpanel.cpp +++ b/alf/alfpanel.cpp @@ -156,20 +156,11 @@ ALF_CreatePanelWindow(HWND parent, WORD id) } HWND -ALF_AddPanel(HWND parent, WORD id, UINT x, UINT y) +ALF_AddPanel(HWND parent, WORD id, int x, int y) { HWND hwndPanel = ALF_CreatePanelWindow(parent, id); - ALFWidgetLayoutParams p; - ZeroMemory(&p, sizeof(p)); - p.hwnd = hwndPanel; - p.x = x; - p.y = y; - p.width = 0; - p.height = 0; - p.flags = ALF_QUERYSIZE | ALF_INHERITFONT; - - ALF_AddWidgetEx(parent, &p); + ALF_AddWidget(parent, x, y, hwndPanel, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT); return hwndPanel; } diff --git a/alf/alfpriv.h b/alf/alfpriv.h index a38cd25..a145f8f 100644 --- a/alf/alfpriv.h +++ b/alf/alfpriv.h @@ -30,7 +30,6 @@ typedef struct { extern TCHAR *_alf_comboClass; extern TCHAR *_alf_panelClass; -extern TCHAR *_alf_spacerClass; extern TCHAR *_alf_labelClass; extern TCHAR *_alf_notebookClass; @@ -49,9 +48,6 @@ ALF_RegisterComboClass(void); void ALF_RegisterPanelClass(void); -void -ALF_RegisterSpacerClass(void); - void ALF_RegisterLabelClass(void); diff --git a/alf/alfspacer.cpp b/alf/alfspacer.cpp deleted file mode 100644 index 7c0f776..0000000 --- a/alf/alfspacer.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "alfpriv.h" - -TCHAR *_alf_spacerClass = NULL; - -void -ALF_RegisterSpacerClass(void) -{ - WNDCLASS cls; - ZeroMemory(&cls, sizeof(cls)); - - TCHAR classNameBuf[256]; - ALF_BuildUniqueName(classNameBuf, TEXT("ALFSpacer."), (ULONG_PTR)&_alf_spacerClass); - - cls.hInstance = ALF_HINSTANCE; - cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW); - cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); - cls.lpszClassName = classNameBuf; - cls.cbWndExtra = sizeof(void*); - cls.lpfnWndProc = DefWindowProc; - - ATOM classatom = RegisterClass(&cls); - if (!classatom) - MessageBox(NULL, TEXT("FATAL: Could not register spacer class"), NULL, MB_OK); - - _alf_spacerClass = MAKEINTATOM(classatom); -} - -HWND -ALF_AddSpacer(HWND parent, WORD id, UINT x, UINT y, UINT cptWidth, UINT cptHeight, DWORD layoutFlags) -{ - HWND hwndSpacer = CreateWindowEx(0, - _alf_spacerClass, - TEXT(""), - WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, - 0, 0, 0, 0, - parent, - (HMENU)(int)id, - ALF_HINSTANCE, - NULL); - - ALFWidgetLayoutParams p; - ZeroMemory(&p, sizeof(p)); - p.hwnd = hwndSpacer; - p.x = x; - p.y = y; - p.width = cptWidth; - p.height = cptHeight; - p.flags = layoutFlags; - - ALF_AddWidgetEx(parent, &p); - - return hwndSpacer; -} -- cgit v1.2.3