summaryrefslogtreecommitdiff
path: root/alf/alfpanel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'alf/alfpanel.cpp')
-rw-r--r--alf/alfpanel.cpp110
1 files changed, 105 insertions, 5 deletions
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)