diff options
| -rw-r--r-- | alf/alf.h | 10 | ||||
| -rw-r--r-- | alf/alflayout.cpp | 44 | ||||
| -rw-r--r-- | alf/alflayout.h | 10 | ||||
| -rw-r--r-- | alf/alfpanel.cpp | 110 | ||||
| -rw-r--r-- | widgetfactory.cpp | 16 |
5 files changed, 164 insertions, 26 deletions
@@ -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, ¬ebookPanelVtbl, priv); + ALF_PanelSetVTable(panel, ¬ebookPanelVtbl, 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 |
