summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2020-05-01 19:00:24 +0200
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2020-05-01 19:00:24 +0200
commitfa2220862856936839a4023fdb6e000f3c93d86f (patch)
tree7bf06e85490246b661c825d005551aaa76abbea3
parent3e069b70cf30a69ea2a3f71233b8f258f54284bc (diff)
groupbox first implementation
only classic theme for now, will do uxtheme soon
-rw-r--r--Makefile.mingw7
-rw-r--r--Makefile.vc65
-rw-r--r--Makefile.vc6-ansi5
-rw-r--r--alf/alf.cpp2
-rw-r--r--alf/alf.h4
-rw-r--r--alf/alfgroupbox.cpp299
-rw-r--r--alf/alflayout.cpp49
-rw-r--r--alf/alflayout.h7
-rw-r--r--alf/alfpanel.cpp11
-rw-r--r--alf/alfpriv.h4
-rw-r--r--alf/alfwindow.cpp1
-rw-r--r--widgetfactory.cpp72
12 files changed, 438 insertions, 28 deletions
diff --git a/Makefile.mingw b/Makefile.mingw
index 8b5a3e2..a836bf8 100644
--- a/Makefile.mingw
+++ b/Makefile.mingw
@@ -8,7 +8,7 @@ LDFLAGS = -luser32 -lcomctl32 -lshell32 -lversion -static
all: out/widgetfactory.exe out/alf/alf.c out/widgetfactory-c.exe
-out/widgetfactory.exe: out/widgetfactory.o out/alfbutton.o out/alfcheckbox.o out/alfcombobox.o out/alfcompat.o out/alf.o out/alfdpiaware.o out/alfedit.o out/alflabel.o out/alflayout.o out/alfnotebook.o out/alfpanel.o out/alfwindow.o
+out/widgetfactory.exe: out/widgetfactory.o out/alfbutton.o out/alfcheckbox.o out/alfcombobox.o out/alfcompat.o out/alf.o out/alfdpiaware.o out/alfedit.o out/alfgroupbox.o out/alflabel.o out/alflayout.o out/alfnotebook.o out/alfpanel.o out/alfwindow.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
out/alfbutton.o: alf/alfbutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
@@ -32,6 +32,9 @@ out/alfdpiaware.o: alf/alfdpiaware.cpp alf/alfcompat.h alf/alf.h alf/alflayout.
out/alfedit.o: alf/alfedit.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
+out/alfgroupbox.o: alf/alfgroupbox.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CXXFLAGS) -c -o $@ $<
+
out/alflabel.o: alf/alflabel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
@@ -50,7 +53,7 @@ out/alfwindow.o: alf/alfwindow.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h al
out/widgetfactory.o: widgetfactory.cpp alf/alf.h
$(CXX) $(CXXFLAGS) -c -o $@ $<
-out/alf/alf.c: alf/alflist.h alf/alflayout.h alf/alfcompat.h alf/alfpriv.h alf/alfbutton.cpp alf/alfcheckbox.cpp alf/alfcombobox.cpp alf/alfcompat.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfwindow.cpp
+out/alf/alf.c: alf/alflist.h alf/alflayout.h alf/alfcompat.h alf/alfpriv.h alf/alfbutton.cpp alf/alfcheckbox.cpp alf/alfcombobox.cpp alf/alfcompat.cpp alf/alf.cpp alf/alfdpiaware.cpp alf/alfedit.cpp alf/alfgroupbox.cpp alf/alflabel.cpp alf/alflayout.cpp alf/alfnotebook.cpp alf/alfpanel.cpp alf/alfwindow.cpp
@mkdir -p out/alf
@printf "#include \"alf.h\"\\n" > $@
@cat $^ | grep -v "^#pragma once" | grep -v "^#include \"alf" >> $@
diff --git a/Makefile.vc6 b/Makefile.vc6
index 9f34366..29317de 100644
--- a/Makefile.vc6
+++ b/Makefile.vc6
@@ -4,7 +4,7 @@ CXX = cl.exe
CFLAGS = -O2 -GA -W3 -DUNICODE -D_UNICODE -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo
LDFLAGS = /link unicows.lib kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib
-out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcheckbox.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcheckbox.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.obj
$(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)
out/alfbutton.obj: alf/alfbutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
@@ -28,6 +28,9 @@ out/alfdpiaware.obj: alf/alfdpiaware.cpp alf/alfcompat.h alf/alf.h alf/alflayou
out/alfedit.obj: alf/alfedit.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alfedit.cpp
+out/alfgroupbox.obj: alf/alfgroupbox.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfgroupbox.cpp
+
out/alflabel.obj: alf/alflabel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alflabel.cpp
diff --git a/Makefile.vc6-ansi b/Makefile.vc6-ansi
index feaade7..efd1375 100644
--- a/Makefile.vc6-ansi
+++ b/Makefile.vc6-ansi
@@ -4,7 +4,7 @@ CXX = cl.exe
CFLAGS = -O2 -GA -W3 -D_WIN32=0x0501 -D_WIN32_WINNT=0x0501 -D_WIN32_IE=0x0501 -nologo
LDFLAGS = /link /entry:_entry /opt:nowin98 /fixed:no kernel32.lib user32.lib comctl32.lib shell32.lib gdi32.lib version.lib
-out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcheckbox.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.obj
+out/widgetfactory.exe: out/widgetfactory.obj out/alfbutton.obj out/alfcheckbox.obj out/alfcombobox.obj out/alfcompat.obj out/alf.obj out/alfdpiaware.obj out/alfedit.obj out/alfgroupbox.obj out/alflabel.obj out/alflayout.obj out/alfnotebook.obj out/alfpanel.obj out/alfwindow.obj
$(CXX) $(CFLAGS) -Fe$@ $** $(LDFLAGS)
out/alfbutton.obj: alf/alfbutton.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
@@ -28,6 +28,9 @@ out/alfdpiaware.obj: alf/alfdpiaware.cpp alf/alfcompat.h alf/alf.h alf/alflayou
out/alfedit.obj: alf/alfedit.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alfedit.cpp
+out/alfgroupbox.obj: alf/alfgroupbox.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
+ $(CXX) $(CFLAGS) -c -Fo$@ alf/alfgroupbox.cpp
+
out/alflabel.obj: alf/alflabel.cpp alf/alfcompat.h alf/alf.h alf/alflayout.h alf/alflist.h alf/alfpriv.h
$(CXX) $(CFLAGS) -c -Fo$@ alf/alflabel.cpp
diff --git a/alf/alf.cpp b/alf/alf.cpp
index 25dcd21..7c0fa2a 100644
--- a/alf/alf.cpp
+++ b/alf/alf.cpp
@@ -50,6 +50,7 @@ ALF_Initialize(void)
ALF_RegisterLabelClass();
ALF_RegisterNotebookClass();
ALF_RegisterButtonClass();
+ ALF_RegisterGroupBoxClass();
ALF_Compat_BufferedPaintInit();
}
@@ -75,6 +76,7 @@ ALF_UnInitialize(void)
UnregisterClass(_alf_labelClass, ALF_HINSTANCE);
UnregisterClass(_alf_notebookClass, ALF_HINSTANCE);
UnregisterClass(_alf_buttonClass, ALF_HINSTANCE);
+ UnregisterClass(_alf_groupboxClass, ALF_HINSTANCE);
ALF_UnloadCompatFunctions();
}
diff --git a/alf/alf.h b/alf/alf.h
index 6d6b333..db42113 100644
--- a/alf/alf.h
+++ b/alf/alf.h
@@ -444,6 +444,10 @@ ALF_NotebookRemoveFlag(HWND notebook, DWORD flag) {
HWND
ALF_AddCheckbox(HWND parent, WORD id, int x, int y, const TCHAR *text);
+// groupbox
+HWND
+ALF_AddGroupBox(HWND parent, WORD id, int x, int y, const TCHAR *text);
+
#ifdef __cplusplus
} // extern C
#endif
diff --git a/alf/alfgroupbox.cpp b/alf/alfgroupbox.cpp
new file mode 100644
index 0000000..a2dfb9b
--- /dev/null
+++ b/alf/alfgroupbox.cpp
@@ -0,0 +1,299 @@
+#include "alfpriv.h"
+
+TCHAR *_alf_groupboxClass = NULL;
+
+typedef struct {
+ ALFLayout layout;
+ HTHEME theme;
+ HWND label;
+ SIZE calculatedLabelSize;
+} ALFGroupBoxPriv;
+
+static void ALF_GroupBox_BeginCalcSizes(ALFLayout *layout, HWND hwnd);
+
+static void ALF_GroupBox_HandleContainerWidgetSize(ALFLayout *layout, HWND groupbox, HWND child, SIZE *s);
+
+static void ALF_GroupBox_EndCalcSizes(ALFLayout *layout, HWND hwnd, SIZE *containerMinSize);
+
+static void ALF_GroupBox_PreContainerWidgetApplyPos(ALFLayout *layout, HWND groupbox, HWND child, RECT *r);
+
+static void
+ALF_GroupBox_IntializePriv(ALFGroupBoxPriv *priv, HWND window, const TCHAR *text)
+{
+ ALF_Layout_Init(&priv->layout);
+ priv->layout.beginCalcSizes = ALF_GroupBox_BeginCalcSizes;
+ priv->layout.handleContainerWidgetSize = ALF_GroupBox_HandleContainerWidgetSize;
+ priv->layout.endCalcSizes = ALF_GroupBox_EndCalcSizes;
+ priv->layout.preApplyLayoutToContainerWidget = ALF_GroupBox_PreContainerWidgetApplyPos;
+
+ priv->label = ALF_AddLabel(window, (WORD)-1, -1, -1, text);
+ ALF_LabelSetStyle(priv->label, ALF_LABEL_ALIGN_LEFT | ALF_LABEL_ALIGN_TOP);
+}
+
+static void
+ALF_GroupBox_ClearPriv(ALFGroupBoxPriv *priv)
+{
+ ALF_Layout_Clear(&priv->layout);
+}
+
+static void
+ALF_GroupBox_PaintFrameClassic(ALFGroupBoxPriv *priv, HWND hwnd, HDC dc)
+{
+ (void)priv;
+
+ HFONT oldfont = SelectFont(dc, priv->layout.font);
+
+ RECT rcClient = { 0,0,0,0 };
+ GetClientRect(hwnd, &rcClient);
+
+
+ RECT rcLabel = { 0,0,0,0 };
+ GetWindowRect(priv->label, &rcLabel);
+ MapWindowRect(NULL, hwnd, &rcLabel);
+
+ RECT rcFrame;
+ rcFrame.top = (rcLabel.bottom - rcLabel.top) / 2;
+ rcFrame.left = 0;
+ rcFrame.bottom = rcLabel.bottom;
+ rcFrame.right = rcLabel.left - 2; // XXX: is that correct?
+ DrawEdge(dc, &rcFrame, EDGE_ETCHED, BF_TOPLEFT);
+
+ rcFrame.left = rcLabel.right + 2; // XXX: is that correct?
+ rcFrame.right = rcClient.right;
+ DrawEdge(dc, &rcFrame, EDGE_ETCHED, BF_TOPRIGHT);
+
+ rcFrame.top = rcLabel.bottom;
+ rcFrame.left = 0;
+ rcFrame.right = rcClient.right;
+ rcFrame.bottom = rcClient.bottom;
+ DrawEdge(dc, &rcFrame, EDGE_ETCHED, BF_LEFT | BF_BOTTOM | BF_RIGHT);
+
+ SelectFont(dc, oldfont);
+}
+
+static void
+ALF_GroupBox_Paint(ALFGroupBoxPriv *priv, HWND hwnd, HDC dc, RECT *r)
+{
+ if (priv->layout.bgcolor == ALF_COLOR_TRANSPARENT) {
+ ALF_Compat_DrawThemeParentBackground(hwnd, dc, r);
+ } else {
+ ALF_FillRect(dc, r, priv->layout.bgcolor);
+ }
+
+ // unthemed paint
+ ALF_GroupBox_PaintFrameClassic(priv, hwnd, dc);
+}
+
+static void
+ALF_GroupBox_BeginCalcSizes(ALFLayout *layout, HWND hwnd)
+{
+ ALFGroupBoxPriv *priv = (ALFGroupBoxPriv *)layout;
+ (void)hwnd;
+
+ priv->layout.containerMargins.left = 2 + ALF_CentipointsToPixels(525, priv->layout.dpi);
+ priv->layout.containerMargins.top = 2 + ALF_CentipointsToPixels(300, priv->layout.dpi);
+ priv->layout.containerMargins.right = 2 + ALF_CentipointsToPixels(525, priv->layout.dpi);
+ priv->layout.containerMargins.bottom = 2 + ALF_CentipointsToPixels(525, priv->layout.dpi);
+ priv->calculatedLabelSize.cx = 0;
+ priv->calculatedLabelSize.cy = 0;
+}
+
+static void
+ALF_GroupBox_HandleContainerWidgetSize(ALFLayout *layout, HWND groupbox, HWND child, SIZE *s)
+{
+ ALFGroupBoxPriv *priv = (ALFGroupBoxPriv *)layout;
+ (void)groupbox;
+
+ if (child == priv->label) {
+ priv->calculatedLabelSize = *s;
+
+ int h = priv->calculatedLabelSize.cy + ALF_CentipointsToPixels(300, priv->layout.dpi);
+ if (h > priv->layout.containerMargins.top) {
+ priv->layout.containerMargins.top = h;
+ }
+ }
+}
+
+static void ALF_GroupBox_EndCalcSizes(ALFLayout *layout, HWND hwnd, SIZE *containerMinSize)
+{
+ ALFGroupBoxPriv *priv = (ALFGroupBoxPriv *)layout;
+ (void)hwnd;
+
+ containerMinSize->cx = priv->layout.containerMargins.left + priv->layout.containerMargins.right
+ + priv->calculatedLabelSize.cx;
+ containerMinSize->cy = priv->layout.containerMargins.top + priv->layout.containerMargins.bottom;
+}
+
+static void ALF_GroupBox_PreContainerWidgetApplyPos(ALFLayout *layout, HWND groupbox, HWND child, RECT *r)
+{
+ ALFGroupBoxPriv *priv = (ALFGroupBoxPriv *)layout;
+
+ if (child == priv->label) {
+ RECT rOld;
+ GetClientRect(child, &rOld);
+
+ if (rOld.bottom - rOld.top != priv->calculatedLabelSize.cy ||
+ rOld.right - rOld.left != priv->calculatedLabelSize.cx) {
+ // if the label changed, the top part of the border needs to be redrawn
+ RECT rcGb;
+ GetClientRect(groupbox, &rcGb);
+ RECT i = { 0, 0, rcGb.right - rcGb.left, priv->calculatedLabelSize.cy };
+ InvalidateRect(groupbox, &i, TRUE);
+ }
+
+
+ r->left = priv->layout.containerMargins.left;
+ r->top = 0;
+ r->right = r->left + priv->calculatedLabelSize.cx;
+ r->bottom = priv->calculatedLabelSize.cy;
+ }
+}
+
+static LRESULT WINAPI
+ALF_GroupBox_WindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ if (msg == WM_NCCREATE) {
+ ALFGroupBoxPriv *p = ALF_New(ALFGroupBoxPriv, 1);
+ SetWindowLongPtr(window, 0, (LONG_PTR)p);
+
+ ALF_GroupBox_IntializePriv(p, window, ((CREATESTRUCT *)lparam)->lpszName);
+ }
+
+ ALFGroupBoxPriv *priv = (ALFGroupBoxPriv *)GetWindowLongPtr(window, 0);
+ if (!priv)
+ return DefWindowProc(window, msg, wparam, lparam); // FIXME! shouldn't happen
+
+ if (msg == WM_NCDESTROY) {
+ ALF_GroupBox_ClearPriv(priv);
+ ALF_Free(priv);
+ priv = NULL;
+ SetWindowLongPtr(window, 0, 0);
+ }
+
+ if (msg == WM_ERASEBKGND) {
+ return TRUE;
+ }
+
+ if (msg == WM_PRINTCLIENT) {
+ RECT r = { 0, 0, 0, 0 };
+ GetClientRect(window, &r);
+
+ ALF_GroupBox_Paint(priv, window, (HDC)wparam, &r);
+
+ return TRUE;
+ }
+
+ if (msg == WM_PAINT) {
+ PAINTSTRUCT ps;
+ HDC dc = BeginPaint(window, &ps);
+
+ ALF_GroupBox_Paint(priv, window, dc, &ps.rcPaint);
+
+ EndPaint(window, &ps);
+
+ return 0;
+ }
+
+ if (msg == WM_SETTEXT) {
+ return SendMessage(priv->label, WM_SETTEXT, wparam, lparam);
+ }
+
+ if (msg == WM_GETTEXT) {
+ return SendMessage(priv->label, WM_GETTEXT, wparam, lparam);
+ }
+
+ if (ALF_ShouldMessageBubble(window, msg, wparam, lparam))
+ return SendMessage(GetParent(window), msg, wparam, lparam);
+
+ if (msg == WM_SIZE) {
+ RECT c;
+ GetClientRect(window, &c);
+
+ if (c.right > priv->layout.allocatedWidgetRect.right + priv->layout.containerMargins.right) {
+ // enlarged to the right -> invalidate place occupied by old border
+ RECT i = { priv->layout.allocatedWidgetRect.right,
+ 0,
+ c.right,
+ c.bottom };
+ InvalidateRect(window, &i, TRUE);
+ }
+ if (c.bottom > priv->layout.allocatedWidgetRect.bottom + priv->layout.containerMargins.bottom) {
+ // enlarged to the bottom -> invalidate place occupied by old border
+ RECT i = { 0,
+ priv->layout.allocatedWidgetRect.bottom,
+ c.right,
+ c.bottom };
+ InvalidateRect(window, &i, TRUE);
+ }
+ if (c.right < priv->layout.allocatedWidgetRect.right + priv->layout.containerMargins.right) {
+ // shrunk horizontally -> invalidate place now occupied by new border
+ RECT i = { c.right - priv->layout.containerMargins.right,
+ 0,
+ c.right,
+ c.bottom };
+ InvalidateRect(window, &i, TRUE);
+ }
+ if (c.bottom < priv->layout.allocatedWidgetRect.bottom + priv->layout.containerMargins.bottom) {
+ // shrunk vertically -> invalidate place now ocuupied by new border
+ RECT i = { 0,
+ c.bottom - priv->layout.containerMargins.bottom,
+ c.right,
+ c.bottom };
+ InvalidateRect(window, &i, TRUE);
+ }
+
+
+ ALF_Layout_Apply(&priv->layout, window);
+ }
+
+ if (msg == WM_ENABLE) {
+ EnableWindow(priv->label, (BOOL)wparam);
+ }
+
+ LRESULT ret = 0;
+ if (ALF_Layout_HandleMessage(&priv->layout, window, msg, wparam, lparam, &ret))
+ return ret;
+
+ return DefWindowProc(window, msg, wparam, lparam);
+}
+
+void
+ALF_RegisterGroupBoxClass(void)
+{
+ WNDCLASS cls;
+ ZeroMemory(&cls, sizeof(cls));
+
+ TCHAR classNameBuf[256];
+ ALF_BuildUniqueName(classNameBuf, TEXT("ALFGroupBox."), (ULONG_PTR)&_alf_groupboxClass);
+
+ cls.hInstance = ALF_HINSTANCE;
+ cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW);
+ cls.lpszClassName = classNameBuf;
+ cls.cbWndExtra = sizeof(void*);
+ cls.lpfnWndProc = ALF_GroupBox_WindowProc;
+
+ ATOM classatom = RegisterClass(&cls);
+ if (!classatom)
+ MessageBox(NULL, TEXT("FATAL: Could not register groupbox class"), NULL, MB_OK);
+
+ _alf_groupboxClass = MAKEINTATOM(classatom);
+}
+
+HWND
+ALF_AddGroupBox(HWND parent, WORD id, int x, int y, const TCHAR *text)
+{
+ HWND hwndPanel = CreateWindowEx(WS_EX_CONTROLPARENT,
+ _alf_groupboxClass,
+ text,
+ WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_TABSTOP,
+ 0, 0, 0, 0,
+ parent,
+ (HMENU)(UINT_PTR)id,
+ ALF_HINSTANCE,
+ NULL);
+
+ ALF_AddWidget(parent, x, y, hwndPanel, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_SENDBGCHANGE | ALF_LAYOUT_SENDDPICHANGE);
+
+ return hwndPanel;
+}
+
diff --git a/alf/alflayout.cpp b/alf/alflayout.cpp
index 9c35b65..8035e74 100644
--- a/alf/alflayout.cpp
+++ b/alf/alflayout.cpp
@@ -278,9 +278,8 @@ ALF_Layout_CalcMinWidgetSize(ALFLayout *layout, ALFWidgetPriv *c, HWND window, S
void
ALF_Layout_CalcSizes(ALFLayout* layout, HWND window)
{
- SIZE containerMinSize = { 0, 0 };
- if (layout->calculateContainerMetrics) {
- layout->calculateContainerMetrics(layout, window, &layout->containerMargins, &containerMinSize);
+ if (layout->beginCalcSizes) {
+ layout->beginCalcSizes(layout, window);
}
layout->biggestColumnNo = 0;
@@ -317,16 +316,21 @@ ALF_Layout_CalcSizes(ALFLayout* layout, HWND window)
int col = c->x; // TODO: skip spanning cells
int row = c->y;
- ALF_Layout_EnsureColumnExists(layout, col);
- ALF_Layout_EnsureRowExists(layout, row);
-
SIZE qs = { 0, 0 };
ALF_Layout_CalcMinWidgetSize(layout, c, window, &qs);
- 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;
+ if (col < 0 || row < 0) {
+ if (layout->handleContainerWidgetSize)
+ layout->handleContainerWidgetSize(layout, window, c->hwnd, &qs);
+ } else {
+ ALF_Layout_EnsureColumnExists(layout, col);
+ ALF_Layout_EnsureRowExists(layout, row);
+
+ 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
@@ -376,6 +380,10 @@ ALF_Layout_CalcSizes(ALFLayout* layout, HWND window)
}
}
+ SIZE containerMinSize = { 0,0 };
+ if (layout->endCalcSizes)
+ layout->endCalcSizes(layout, window, &containerMinSize);
+
if (layout->totalMinWidth < containerMinSize.cx - layout->containerMargins.left - layout->containerMargins.right)
layout->totalMinWidth = containerMinSize.cx - layout->containerMargins.left - layout->containerMargins.right;
@@ -461,13 +469,18 @@ ALF_Layout_Apply(ALFLayout* layout, HWND window)
int col = c->x;
int row = c->y;
if (col >= layout->nColumns || row >= layout->nRows)
- continue; // FIXME! can that actually happen?
+ continue; // FIXME: wat?
RECT r = { 0,0,0,0 };
- 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 (row < 0 || col < 0) {
+ if (layout->preApplyLayoutToContainerWidget)
+ layout->preApplyLayoutToContainerWidget(layout, window, c->hwnd, &r);
+ } else {
+ 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_LAYOUT_CUSTOMPOS) {
hdwp = (HDWP)SendMessage(c->hwnd, ALF_WM_APPLYSIZE, (WPARAM)hdwp, (LPARAM)&r);
@@ -495,9 +508,9 @@ ALF_Layout_Apply(ALFLayout* layout, HWND window)
}
hdwp = DeferWindowPos(hdwp,
- c->hwnd, 0,
- r.left, r.top, r.right - r.left, r.bottom - r.top,
- flags);
+ c->hwnd, 0,
+ r.left, r.top, r.right - r.left, r.bottom - r.top,
+ flags);
}
}
diff --git a/alf/alflayout.h b/alf/alflayout.h
index 9170db7..183c336 100644
--- a/alf/alflayout.h
+++ b/alf/alflayout.h
@@ -57,9 +57,12 @@ typedef struct tagALFLayout {
int dpi;
HFONT font;
ALFColor bgcolor;
- RECT containerMargins;
- void (*calculateContainerMetrics)(struct tagALFLayout *layout, HWND hwnd, RECT *margins, SIZE *minSize);
+ RECT containerMargins; // may be written to by the following functions
+ void (*beginCalcSizes)(struct tagALFLayout *layout, HWND hwnd);
+ void (*handleContainerWidgetSize)(struct tagALFLayout *layout, HWND hwnd, HWND hwndContainerWidget, SIZE *s);
+ void (*endCalcSizes)(struct tagALFLayout *layout, HWND hwnd, SIZE *minSize);
RECT allocatedWidgetRect;
+ void (*preApplyLayoutToContainerWidget)(struct tagALFLayout *layout, HWND hwnd, HWND hwndContainerWidget, RECT *pos); // should modify pos
} ALFLayout;
void
diff --git a/alf/alfpanel.cpp b/alf/alfpanel.cpp
index 31c485f..476bdb4 100644
--- a/alf/alfpanel.cpp
+++ b/alf/alfpanel.cpp
@@ -9,13 +9,13 @@ typedef struct {
DWORD edge;
} ALFPanelPriv;
-static void ALF_Panel_CalculateContainerMetrics(ALFLayout *layout, HWND hwnd, RECT *margins, SIZE *minSize);
+static void ALF_Panel_CalculateContainerMetrics(ALFLayout *layout, HWND hwnd, SIZE *minSize);
static void
ALF_Panel_IntializePriv(ALFPanelPriv *priv)
{
ALF_Layout_Init(&priv->layout);
- priv->layout.calculateContainerMetrics = ALF_Panel_CalculateContainerMetrics;
+ priv->layout.endCalcSizes = ALF_Panel_CalculateContainerMetrics;
}
static void
@@ -78,7 +78,7 @@ ALF_PanelSetVTable(HWND panel, const ALFPanelVTable *vtbl, void *closure)
}
static void
-ALF_Panel_CalculateContainerMetrics(ALFLayout *layout, HWND hwnd, RECT *margins, SIZE *minSize)
+ALF_Panel_CalculateContainerMetrics(ALFLayout *layout, HWND hwnd, SIZE *minSize)
{
(void)hwnd;
ALFPanelPriv *priv = (ALFPanelPriv *)layout;
@@ -91,7 +91,10 @@ ALF_Panel_CalculateContainerMetrics(ALFLayout *layout, HWND hwnd, RECT *margins,
if (priv->edge & BDR_OUTER)
w++;
- margins->left = margins->right = margins->top = margins->bottom = w;
+ priv->layout.containerMargins.left = w;
+ priv->layout.containerMargins.top = w;
+ priv->layout.containerMargins.right = w;
+ priv->layout.containerMargins.bottom = w;
minSize->cx = minSize->cy = 2*w;
}
diff --git a/alf/alfpriv.h b/alf/alfpriv.h
index 2c79fcd..c0e83da 100644
--- a/alf/alfpriv.h
+++ b/alf/alfpriv.h
@@ -22,6 +22,7 @@ extern TCHAR *_alf_panelClass;
extern TCHAR *_alf_labelClass;
extern TCHAR *_alf_notebookClass;
extern TCHAR *_alf_buttonClass;
+extern TCHAR *_alf_groupboxClass;
void
ALF_RegisterComboClass(void);
@@ -38,6 +39,9 @@ ALF_RegisterNotebookClass(void);
void
ALF_RegisterButtonClass(void);
+void
+ALF_RegisterGroupBoxClass(void);
+
HWND
ALF_CreatePanelWindow(HWND parent, WORD id);
diff --git a/alf/alfwindow.cpp b/alf/alfwindow.cpp
index d3cbfcd..02ef921 100644
--- a/alf/alfwindow.cpp
+++ b/alf/alfwindow.cpp
@@ -62,6 +62,7 @@ ALF_UpdateFontsPriv(HWND win, ALFWindowPriv *priv)
if (priv->hMessageFont) {
DeleteObject(priv->hMessageFont);
}
+
priv->hMessageFont = CreateFontIndirect(&lfMessageFont);
SendMessage(win, WM_SETFONT, (WPARAM)priv->hMessageFont, (LPARAM)1);
diff --git a/widgetfactory.cpp b/widgetfactory.cpp
index 3885df4..b0c0fdd 100644
--- a/widgetfactory.cpp
+++ b/widgetfactory.cpp
@@ -595,6 +595,77 @@ checkboxPanelAddToNotebook(HWND hwndNotebook)
ALF_PanelSetVTable(panel, &checkboxPanelVtbl, priv);
}
+/* groupbox panel */
+
+static void
+groupboxPanelAttach(void *closure, HWND panel)
+{
+ (void)closure;
+
+ ALF_AddLabel(panel, (WORD)-1, 1, 1, TEXT("ALF"));
+ ALF_AddLabel(panel, (WORD)-1, 3, 1, TEXT("native"));
+
+ HWND hwndGb0 = ALF_AddGroupBox(panel, (WORD)-1, 1, 3, TEXT("Test Bo&x"));
+
+ HWND hwndGb1 = CreateWindowEx(WS_EX_TRANSPARENT,
+ TEXT("BUTTON"),
+ TEXT("Test Box"),
+ WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_GROUPBOX,
+ 0, 0, 100, 100,
+ panel,
+ (HMENU)(WORD)-1,
+ (HINSTANCE)GetModuleHandle(NULL),
+ NULL);
+ ALF_AddWidget(panel, 3, 3, hwndGb1, 0, 0, ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_TRANSPARENTBG);
+
+ ALF_AddEdit(hwndGb0, (WORD)-1, 0, 0, TEXT("Dummy"));
+
+ HWND hwndGb3 = ALF_AddGroupBox(panel, (WORD)-1, 1, 5, TEXT("Disabled"));
+ EnableWindow(hwndGb3, FALSE);
+
+ HWND hwndGb2 = CreateWindowEx(WS_EX_TRANSPARENT,
+ TEXT("BUTTON"),
+ TEXT("Disabled"),
+ WS_CHILD | WS_TABSTOP | WS_VISIBLE | BS_GROUPBOX,
+ 0, 0, 100, 100,
+ panel,
+ (HMENU)(WORD)-1,
+ (HINSTANCE)GetModuleHandle(NULL),
+ NULL);
+ ALF_AddWidget(panel, 3, 5, hwndGb2, 0, 0, ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_TRANSPARENTBG);
+ EnableWindow(hwndGb2, FALSE);
+
+ ALF_LayoutSetRowMinSize(panel, 0, 825);
+ ALF_LayoutSetRowMinSize(panel, 2, 825);
+ ALF_LayoutSetRowMinSize(panel, 4, 825);
+ ALF_LayoutSetRowMinSize(panel, 6, 825);
+ ALF_LayoutSetColumnMinSize(panel, 0, 825);
+ ALF_LayoutSetColumnMinSize(panel, 2, 825);
+ ALF_LayoutSetColumnMinSize(panel, 4, 825);
+ ALF_LayoutSetRowExpandNumerator(panel, 3, 1);
+ ALF_LayoutSetRowExpandNumerator(panel, 5, 1);
+ ALF_LayoutSetColumnExpandNumerator(panel, 1, 1);
+ ALF_LayoutSetColumnExpandNumerator(panel, 3, 1);
+}
+
+static ALFPanelVTable groupboxPanelVtbl = {
+ groupboxPanelAttach,
+ commonPanelDestroy,
+ commonPanelMessage,
+ NULL,
+ NULL,
+ commonPanelPaint,
+ NULL
+};
+
+static void
+groupboxPanelAddToNotebook(HWND hwndNotebook)
+{
+ HWND panel = ALF_NotebookAddTab(hwndNotebook, TEXT("GroupBox"));
+ CommonPanelPriv *priv = ALF_New(CommonPanelPriv, 1);
+ ALF_PanelSetVTable(panel, &groupboxPanelVtbl, priv);
+}
+
int CALLBACK
#ifdef UNICODE
wWinMain
@@ -643,6 +714,7 @@ WinMain
comboPanelAddToNotebook(hwndNtbk);
notebookPanelAddToNotebook(hwndNtbk);
checkboxPanelAddToNotebook(hwndNtbk);
+ groupboxPanelAddToNotebook(hwndNtbk);
ALF_SetDefaultButton(win, ID_HELLO);