summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alf/alf.h10
-rw-r--r--alf/alflayout.cpp44
-rw-r--r--alf/alflayout.h10
-rw-r--r--alf/alfpanel.cpp110
-rw-r--r--widgetfactory.cpp16
5 files changed, 164 insertions, 26 deletions
diff --git a/alf/alf.h b/alf/alf.h
index faeb177..6d6b333 100644
--- a/alf/alf.h
+++ b/alf/alf.h
@@ -115,6 +115,8 @@ typedef struct {
#define ALF_WM_LBL_SETSTYLE (ALF_WM__BASE + 202)
#define ALF_WM_PANEL_SETVTABLE (ALF_WM__BASE + 201)
+#define ALF_WM_PANEL_GETEDGE (ALF_WM__BASE + 202)
+#define ALF_WM_PANEL_SETEDGE (ALF_WM__BASE + 203)
#define ALF_WM_NTBK_GETFLAGS (ALF_WM__BASE + 201)
#define ALF_WM_NTBK_SETFLAGS (ALF_WM__BASE + 202)
@@ -386,7 +388,7 @@ HWND
ALF_AddPanel(HWND parent, WORD id, int x, int y);
void
-ALF_Panel_SetVTable(HWND panel, const ALFPanelVTable *vtbl, void *closure);
+ALF_PanelSetVTable(HWND panel, const ALFPanelVTable *vtbl, void *closure);
LRESULT
ALF_Panel_DefWindowProc(HWND panel, UINT msg, WPARAM wparam, LPARAM lparam);
@@ -394,6 +396,12 @@ ALF_Panel_DefWindowProc(HWND panel, UINT msg, WPARAM wparam, LPARAM lparam);
void
ALF_Panel_DefPaint(HWND panel, HDC hDC, RECT *rcPaint);
+DWORD
+ALF_PanelEdge(HWND panel);
+
+void
+ALF_PanelSetEdge(HWND panel, DWORD edge);
+
// tab control
HWND
ALF_AddNotebook(HWND parent, WORD id, int x, int y);
diff --git a/alf/alflayout.cpp b/alf/alflayout.cpp
index 1cdd328..9c35b65 100644
--- a/alf/alflayout.cpp
+++ b/alf/alflayout.cpp
@@ -278,6 +278,11 @@ 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);
+ }
+
layout->biggestColumnNo = 0;
layout->columnExpandDenominator = 0;
for (int i = 0; i < layout->nColumns; ++i) {
@@ -371,6 +376,12 @@ ALF_Layout_CalcSizes(ALFLayout* layout, HWND window)
}
}
+ if (layout->totalMinWidth < containerMinSize.cx - layout->containerMargins.left - layout->containerMargins.right)
+ layout->totalMinWidth = containerMinSize.cx - layout->containerMargins.left - layout->containerMargins.right;
+
+ if (layout->totalMinHeight < containerMinSize.cy - layout->containerMargins.top - layout->containerMargins.bottom)
+ layout->totalMinHeight = containerMinSize.cy - layout->containerMargins.top - layout->containerMargins.bottom;
+
layout->layoutValididityFlags &= ~ALF_LAYOUT_NEED_RECALC;
}
@@ -380,16 +391,26 @@ ALF_Layout_Apply(ALFLayout* layout, HWND window)
if (layout->layoutValididityFlags & ALF_LAYOUT_NEED_RECALC)
ALF_Layout_CalcSizes(layout, window);
+ GetClientRect(window, &layout->allocatedWidgetRect);
+ layout->allocatedWidgetRect.left += layout->containerMargins.left;
+ layout->allocatedWidgetRect.right -= layout->containerMargins.right;
+ layout->allocatedWidgetRect.top += layout->containerMargins.top;
+ layout->allocatedWidgetRect.bottom -= layout->containerMargins.bottom;
+
+ // FIXME! can that happen?
+ if (layout->allocatedWidgetRect.right < layout->allocatedWidgetRect.left)
+ layout->allocatedWidgetRect.right = layout->allocatedWidgetRect.left;
+ if (layout->allocatedWidgetRect.bottom < layout->allocatedWidgetRect.top)
+ layout->allocatedWidgetRect.bottom = layout->allocatedWidgetRect.top;
+
// distribute extra space
int extraWidth = 0;
int extraHeight = 0;
- RECT client;
- if (GetClientRect(window, &client)) {
- if (client.right - client.left > layout->totalMinWidth)
- extraWidth = client.right - client.left - layout->totalMinWidth;
- if (client.bottom - client.top > layout->totalMinHeight)
- extraHeight = client.bottom - client.top - layout->totalMinHeight;
- }
+
+ if (layout->allocatedWidgetRect.right - layout->allocatedWidgetRect.left > layout->totalMinWidth)
+ extraWidth = layout->allocatedWidgetRect.right - layout->allocatedWidgetRect.left - layout->totalMinWidth;
+ if (layout->allocatedWidgetRect.bottom - layout->allocatedWidgetRect.top > layout->totalMinHeight)
+ extraHeight = layout->allocatedWidgetRect.bottom - layout->allocatedWidgetRect.top - layout->totalMinHeight;
int extraWidthLeft = extraWidth;
for (int i = 0; i < layout->nColumns; ++i) {
@@ -422,12 +443,12 @@ ALF_Layout_Apply(ALFLayout* layout, HWND window)
layout->rows[layout->biggestRowNo].calculatedMinWidth + extraHeightLeft;
// set row/column positions
- int x = 0;
+ int x = layout->allocatedWidgetRect.left;
for (int i = 0; i < layout->nColumns; ++i) {
layout->columns[i].allocatedPosition = x;
x += layout->columns[i].allocatedWidth;
}
- int y = 0;
+ int y = layout->allocatedWidgetRect.top;
for (int i = 0; i < layout->nRows; ++i) {
layout->rows[i].allocatedPosition = y;
y += layout->rows[i].allocatedWidth;
@@ -568,8 +589,8 @@ ALF_Layout_GetMinSize(ALFLayout *layout, HWND window, SIZE *size)
ALF_Layout_CalcSizes(layout, window);
}
- size->cx = layout->totalMinWidth;
- size->cy = layout->totalMinHeight;
+ size->cx = layout->totalMinWidth + layout->containerMargins.left + layout->containerMargins.right;
+ size->cy = layout->totalMinHeight + layout->containerMargins.top + layout->containerMargins.bottom;
}
BOOL
@@ -813,7 +834,6 @@ ALF_Layout_SetRowFlags(ALFLayout *layout, HWND window, int rowno, DWORD flags)
return TRUE;
}
-
BOOL
ALF_Layout_HandleMessage(ALFLayout *layout, HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, LRESULT *pRet)
{
diff --git a/alf/alflayout.h b/alf/alflayout.h
index bd966cc..9170db7 100644
--- a/alf/alflayout.h
+++ b/alf/alflayout.h
@@ -37,10 +37,11 @@ typedef struct {
int allocatedPosition;
} ALFLayoutRowOrColumn;
-#define ALF_LAYOUT_NEED_RECALC ((DWORD)1)
-#define ALF_LAYOUT_NEED_REAPPLY ((DWORD)2)
+#define ALF_LAYOUT_NEED_RECALC ((DWORD)1)
+#define ALF_LAYOUT_NEED_REAPPLY ((DWORD)2)
+#define ALF_LAYOUT_NEED_RECALC_CONTAINER ((DWORD)4)
-typedef struct {
+typedef struct tagALFLayout {
ALFListHeader widgets;
ALFLayoutRowOrColumn *columns;
ALFLayoutRowOrColumn *rows;
@@ -56,6 +57,9 @@ typedef struct {
int dpi;
HFONT font;
ALFColor bgcolor;
+ RECT containerMargins;
+ void (*calculateContainerMetrics)(struct tagALFLayout *layout, HWND hwnd, RECT *margins, SIZE *minSize);
+ RECT allocatedWidgetRect;
} ALFLayout;
void
diff --git a/alf/alfpanel.cpp b/alf/alfpanel.cpp
index 2f2ee68..31c485f 100644
--- a/alf/alfpanel.cpp
+++ b/alf/alfpanel.cpp
@@ -6,12 +6,16 @@ typedef struct {
ALFLayout layout;
const ALFPanelVTable *vtbl;
void *closure;
+ DWORD edge;
} ALFPanelPriv;
+static void ALF_Panel_CalculateContainerMetrics(ALFLayout *layout, HWND hwnd, RECT *margins, SIZE *minSize);
+
static void
ALF_Panel_IntializePriv(ALFPanelPriv *priv)
{
ALF_Layout_Init(&priv->layout);
+ priv->layout.calculateContainerMetrics = ALF_Panel_CalculateContainerMetrics;
}
static void
@@ -23,10 +27,17 @@ ALF_Panel_ClearPriv(ALFPanelPriv *priv)
static void
ALF_Panel_InternalDefPaint(ALFPanelPriv *priv, HWND hwnd, HDC dc, RECT *r)
{
+ RECT r2;
+ GetClientRect(hwnd, &r2);
+ if (priv->edge) {
+ DrawEdge(dc, &r2, priv->edge, BF_ADJUST|BF_RECT);
+ }
+
+ IntersectRect(&r2, &r2, r);
if (priv->layout.bgcolor == ALF_COLOR_TRANSPARENT) {
- ALF_Compat_DrawThemeParentBackground(hwnd, dc, r);
+ ALF_Compat_DrawThemeParentBackground(hwnd, dc, &r2);
} else {
- ALF_FillRect(dc, r, priv->layout.bgcolor);
+ ALF_FillRect(dc, &r2, priv->layout.bgcolor);
}
}
@@ -48,13 +59,42 @@ ALF_Panel_Paint(ALFPanelPriv *priv, HWND hwnd, HDC dc, RECT *r)
}
}
+static void
+ALF_Panel_InternalSetEdge(ALFPanelPriv *priv, HWND hwnd, DWORD edge)
+{
+ if (priv->edge == edge)
+ return;
+
+ priv->edge = edge;
+ ALF_Layout_Invalidate(&priv->layout, hwnd);
+ InvalidateRect(hwnd, NULL, TRUE);
+}
+
void
-ALF_Panel_SetVTable(HWND panel, const ALFPanelVTable *vtbl, void *closure)
+ALF_PanelSetVTable(HWND panel, const ALFPanelVTable *vtbl, void *closure)
{
ALFPanelSetVtblParams p = { vtbl, closure };
SendMessage(panel, ALF_WM_PANEL_SETVTABLE, 0, (LPARAM)&p);
}
+static void
+ALF_Panel_CalculateContainerMetrics(ALFLayout *layout, HWND hwnd, RECT *margins, SIZE *minSize)
+{
+ (void)hwnd;
+ ALFPanelPriv *priv = (ALFPanelPriv *)layout;
+
+ int w = 0;
+
+ if (priv->edge & BDR_INNER)
+ w++;
+
+ if (priv->edge & BDR_OUTER)
+ w++;
+
+ margins->left = margins->right = margins->top = margins->bottom = w;
+ minSize->cx = minSize->cy = 2*w;
+}
+
LRESULT
ALF_Panel_DefWindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
{
@@ -102,10 +142,58 @@ ALF_Panel_DefWindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
return TRUE;
}
+ if (msg == ALF_WM_PANEL_GETEDGE) {
+ return (LRESULT)priv->edge;
+ }
+
+ if (msg == ALF_WM_PANEL_SETEDGE) {
+ ALF_Panel_InternalSetEdge(priv, window, (DWORD)lparam);
+ return TRUE;
+ }
+
if (ALF_ShouldMessageBubble(window, msg, wparam, lparam))
return SendMessage(GetParent(window), msg, wparam, lparam);
if (msg == WM_SIZE) {
+ // if we have a border, invalidate that (and only that) when resizing
+ if (priv->edge) {
+ 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);
}
@@ -116,8 +204,20 @@ ALF_Panel_DefWindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
return DefWindowProc(window, msg, wparam, lparam);
}
+DWORD
+ALF_PanelEdge(HWND panel)
+{
+ return (DWORD)SendMessage(panel, ALF_WM_PANEL_GETEDGE, 0, 0);
+}
+
+void
+ALF_PanelSetEdge(HWND panel, DWORD edge)
+{
+ SendMessage(panel, ALF_WM_PANEL_SETEDGE, 0, (LPARAM)edge);
+}
+
static LRESULT WINAPI
-ALF__PanelWindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
+ALF_Panel_WindowProc(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
{
if (msg == WM_NCCREATE) {
ALFPanelPriv *p = ALF_New(ALFPanelPriv, 1);
@@ -160,7 +260,7 @@ ALF_RegisterPanelClass(void)
cls.hCursor = LoadCursor(NULL, (LPTSTR)IDC_ARROW);
cls.lpszClassName = classNameBuf;
cls.cbWndExtra = sizeof(void*);
- cls.lpfnWndProc = ALF__PanelWindowProc;
+ cls.lpfnWndProc = ALF_Panel_WindowProc;
ATOM classatom = RegisterClass(&cls);
if (!classatom)
diff --git a/widgetfactory.cpp b/widgetfactory.cpp
index 3e8dceb..3885df4 100644
--- a/widgetfactory.cpp
+++ b/widgetfactory.cpp
@@ -237,6 +237,8 @@ buttonPanelAttach(void *closure, HWND outerPanel)
HWND b;
HWND panel;
+ ALF_PanelSetEdge(outerPanel, BDR_SUNKENOUTER);
+
panel = ALF_AddPanel(outerPanel, (WORD)-1, 0, 0);
ALF_AddLabel(panel, (WORD)-1, 0, 2, TEXT("normal"));
@@ -303,6 +305,8 @@ buttonPanelAttach(void *closure, HWND outerPanel)
ALF_LayoutSetColumnExpandNumerator(panel, 9, 1);
+ ALF_PanelSetEdge(panel, BDR_RAISEDINNER);
+
panel = ALF_AddPanel(outerPanel, (WORD)-1, 0, 1);
ALF_AddButton(panel, (WORD)-1, 2, 2, TEXT("Standard"));
@@ -355,6 +359,8 @@ buttonPanelAttach(void *closure, HWND outerPanel)
ALF_LayoutSetRowExpandNumerator(panel, 4, 1);
ALF_LayoutSetRowExpandNumerator(panel, 6, 1);
+ ALF_PanelSetEdge(panel, BDR_RAISEDINNER);
+
ALF_LayoutSetRowExpandNumerator(outerPanel, 1, 1);
@@ -404,7 +410,7 @@ buttonPanelAddToNotebook(HWND hwndNotebook)
{
HWND panel = ALF_NotebookAddTab(hwndNotebook, TEXT("Buttons"));
CommonPanelPriv *priv = ALF_New(CommonPanelPriv, 1);
- ALF_Panel_SetVTable(panel, &buttonPanelVtbl, priv);
+ ALF_PanelSetVTable(panel, &buttonPanelVtbl, priv);
}
/* label panel */
@@ -444,7 +450,7 @@ labelPanelAddToNotebook(HWND hwndNotebook)
{
HWND panel = ALF_NotebookAddTab(hwndNotebook, TEXT("Label"));
CommonPanelPriv *priv = ALF_New(CommonPanelPriv, 1);
- ALF_Panel_SetVTable(panel, &labelPanelVtbl, priv);
+ ALF_PanelSetVTable(panel, &labelPanelVtbl, priv);
}
/* combo box panel */
@@ -498,7 +504,7 @@ comboPanelAddToNotebook(HWND hwndNotebook)
{
HWND panel = ALF_NotebookAddTab(hwndNotebook, TEXT("Combo Box"));
CommonPanelPriv *priv = ALF_New(CommonPanelPriv, 1);
- ALF_Panel_SetVTable(panel, &comboPanelVtbl, priv);
+ ALF_PanelSetVTable(panel, &comboPanelVtbl, priv);
}
/* notebook panel */
@@ -549,7 +555,7 @@ notebookPanelAddToNotebook(HWND hwndNotebook)
{
HWND panel = ALF_NotebookAddTab(hwndNotebook, TEXT("Notebook"));
CommonPanelPriv *priv = ALF_New(CommonPanelPriv, 1);
- ALF_Panel_SetVTable(panel, &notebookPanelVtbl, priv);
+ ALF_PanelSetVTable(panel, &notebookPanelVtbl, priv);
}
/* checkbox panel */
@@ -586,7 +592,7 @@ checkboxPanelAddToNotebook(HWND hwndNotebook)
{
HWND panel = ALF_NotebookAddTab(hwndNotebook, TEXT("Checkbox"));
CommonPanelPriv *priv = ALF_New(CommonPanelPriv, 1);
- ALF_Panel_SetVTable(panel, &checkboxPanelVtbl, priv);
+ ALF_PanelSetVTable(panel, &checkboxPanelVtbl, priv);
}
int CALLBACK