diff options
| -rw-r--r-- | Makefile.mingw | 7 | ||||
| -rw-r--r-- | Makefile.vc6 | 5 | ||||
| -rw-r--r-- | Makefile.vc6-ansi | 5 | ||||
| -rw-r--r-- | alf/alf.cpp | 2 | ||||
| -rw-r--r-- | alf/alf.h | 4 | ||||
| -rw-r--r-- | alf/alfgroupbox.cpp | 299 | ||||
| -rw-r--r-- | alf/alflayout.cpp | 49 | ||||
| -rw-r--r-- | alf/alflayout.h | 7 | ||||
| -rw-r--r-- | alf/alfpanel.cpp | 11 | ||||
| -rw-r--r-- | alf/alfpriv.h | 4 | ||||
| -rw-r--r-- | alf/alfwindow.cpp | 1 | ||||
| -rw-r--r-- | widgetfactory.cpp | 72 |
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(); } @@ -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); |
