diff options
Diffstat (limited to 'alf')
| -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 |
4 files changed, 153 insertions, 21 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) |
