summaryrefslogtreecommitdiff
path: root/alf/alfnotebook.cpp
diff options
context:
space:
mode:
authorJonas Kümmerlin <jonas@kuemmerlin.eu>2020-06-06 23:45:50 +0200
committerJonas Kümmerlin <jonas@kuemmerlin.eu>2020-06-06 23:45:50 +0200
commit57ee7c6f709ed1243fee0c96af3a0f7f51380545 (patch)
tree7d28a0933154d688a72bdbb910e7dc5ced2f2c15 /alf/alfnotebook.cpp
parent12ba6ccef311641c991c4bf1334627b27d8e263e (diff)
notebook: completely homegrown reimplementation
for now only classic theme, also not well tested outside of winxp
Diffstat (limited to 'alf/alfnotebook.cpp')
-rw-r--r--alf/alfnotebook.cpp914
1 files changed, 621 insertions, 293 deletions
diff --git a/alf/alfnotebook.cpp b/alf/alfnotebook.cpp
index 8bf6b5e..f6ae937 100644
--- a/alf/alfnotebook.cpp
+++ b/alf/alfnotebook.cpp
@@ -2,149 +2,245 @@
#include "alfcompat.h"
#define TABP_BODY 10
-#define TMT_FILLCOLORHINT 3821
-typedef struct {
- HWND hwndTabCtrl;
- HTHEME hTheme;
- ALFColor tabPaneBgColor;
- DWORD flags;
- int dpi;
- int prevSelectedIndex;
-} ALFNotebookPriv;
+#define ALF_NB_FLAG_TAB_RECTS_INVALID 1
+#define ALF_NB_FLAG_SWITCHER_FOCUSED 2
+#define ALF_NB_FLAG_SWITCHER_HIDEFOCUS 4
typedef struct {
- TCITEMHEADER header;
- DWORD layoutFlags;
- HWND panel;
+ ALFListHeader list;
+ TCHAR title[64]; // FIXME
+ DWORD layoutFlags;
+ HWND hwndPanel;
+ RECT calculatedTabRect;
+ SIZE contentSize;
} ALFNotebookPage;
+typedef struct {
+ HWND hwndContainer;
+ HWND hwndSwitcher;
+ HTHEME hTheme;
+ ALFColor tabPaneBgColor;
+ DWORD flags;
+ int dpi;
+ ALFListHeader pages;
+ ALFNotebookPage *selectedPage;
+ int totalSwitcherWidth;
+ HFONT font;
+ int fontHeight;
+ SIZE oldContainerSize;
+ SIZE oldSwitcherSize;
+} ALFNotebookPriv;
+
static ALFNotebookPriv *
ALF_Notebook_CreatePriv(void)
{
ALFNotebookPriv *priv = ALF_New(ALFNotebookPriv, 1);
priv->tabPaneBgColor = ALF_COLOR_SYS(COLOR_BTNFACE);
- priv->prevSelectedIndex = -1;
+ priv->fontHeight = 12; // FIXME!
+
+ ALF_ListInit(&priv->pages);
return priv;
}
-void
+static int
+ALF_Notebook_SwitcherHeight(ALFNotebookPriv *priv)
+{
+ return priv->fontHeight + 8;
+}
+
+static void
+ALF_Notebook_PanelRect(ALFNotebookPriv *priv, RECT *rc)
+{
+ GetClientRect(priv->hwndContainer, rc);
+
+ rc->left += 4;
+ rc->right -= 4;
+ rc->top += ALF_Notebook_SwitcherHeight(priv) + 1;
+ rc->bottom -= 4;
+}
+
+static void
+ALF_Notebook_PanelToContainerRect(ALFNotebookPriv *priv, RECT *rc)
+{
+ rc->left -= 4;
+ rc->right += 4;
+ rc->top -= ALF_Notebook_SwitcherHeight(priv) + 1;
+ rc->bottom += 4;
+}
+
+static void
+ALF_Notebook_FreePage(ALFNotebookPriv *priv, ALFNotebookPage *page)
+{
+ (void)priv;
+
+ DestroyWindow(page->hwndPanel);
+ ALF_Free(page);
+}
+
+static void
ALF_Notebook_FreePriv(ALFNotebookPriv *priv)
{
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ ALF_Notebook_FreePage(priv, p);
+ }
+
ALF_Compat_CloseThemeData(priv->hTheme);
priv->hTheme = NULL;
ALF_Free(priv);
}
static int
-ALF_Notebook_InternalTabCount(HWND notebook, HWND tabControl)
+ALF_Notebook_InternalTabCount(ALFNotebookPriv *priv)
{
- (void)notebook;
- return TabCtrl_GetItemCount(tabControl);
+ int i = 0;
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ ++i;
+ }
+ return i;
}
static HWND
-ALF_Notebook_InternalTabPanel(HWND notebook, HWND tabControl, int index)
+ALF_Notebook_InternalTabPanel(ALFNotebookPriv *priv, int index)
{
- (void)notebook;
+ int i = 0;
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ if (i == index) {
+ return p->hwndPanel;
+ }
- ALFNotebookPage p;
- ZeroMemory(&p, sizeof(p));
+ ++i;
+ }
- p.header.mask = TCIF_PARAM;
+ return NULL;
+}
- if (TabCtrl_GetItem(tabControl, index, &p)) {
- return p.panel;
+static HWND
+ALF_Notebook_InternalSelectedPanel(ALFNotebookPriv *priv)
+{
+ if (priv->selectedPage) {
+ return priv->selectedPage->hwndPanel;
} else {
return NULL;
}
}
-static int
-ALF_Notebook_InternalSelectedIndex(HWND notebook, HWND tabControl)
-{
- (void)notebook;
-
- return TabCtrl_GetCurSel(tabControl);
-}
-
-
static void
-ALF_Notebook_InternalHandleTabChange(HWND hwndNotebook, ALFNotebookPriv *priv)
+ALF_Notebook_InternalDoTabChange(ALFNotebookPriv *priv, ALFNotebookPage *newSelected)
{
- int selectedIndex = ALF_Notebook_InternalSelectedIndex(hwndNotebook, priv->hwndTabCtrl);
- int n = ALF_Notebook_InternalTabCount(hwndNotebook, priv->hwndTabCtrl);
+ ALFNotebookPage *oldSelected = priv->selectedPage;
+ priv->selectedPage = newSelected;
- for (int i = 0; i < n; ++i) {
- if (i == selectedIndex) {
- SetWindowPos(ALF_Notebook_InternalTabPanel(hwndNotebook, priv->hwndTabCtrl, i), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ if (p == priv->selectedPage) {
+ SetWindowPos(p->hwndPanel, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER);
} else {
- ShowWindow(ALF_Notebook_InternalTabPanel(hwndNotebook, priv->hwndTabCtrl, i), SW_HIDE);
+ SetWindowPos(p->hwndPanel, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_HIDEWINDOW | SWP_NOZORDER);
}
}
- if (selectedIndex != priv->prevSelectedIndex) {
- HWND currentFocus = GetFocus();
- if (currentFocus != priv->hwndTabCtrl) {
- HWND focusControl = GetNextDlgTabItem(hwndNotebook, priv->hwndTabCtrl, FALSE);
- ALF_SetFocus(focusControl);
- }
+ // redraw only part that changed
+ if (oldSelected) {
+ RECT rcOld = oldSelected->calculatedTabRect;
+ InflateRect(&rcOld, 2, 0);
+ InvalidateRect(priv->hwndSwitcher, &rcOld, TRUE);
}
- priv->prevSelectedIndex = selectedIndex;
+ RECT rcNew = newSelected->calculatedTabRect;
+ InflateRect(&rcNew, 2, 0);
+ InvalidateRect(priv->hwndSwitcher, &rcNew, TRUE);
+
+ HWND currentFocus = GetFocus();
+ if (currentFocus != priv->hwndSwitcher) {
+ HWND focusControl = GetNextDlgTabItem(priv->hwndContainer, priv->hwndSwitcher, FALSE);
+ ALF_SetFocus(focusControl);
+ }
}
static void
-ALF_Notebook_SetSingleTabBackground(HWND hwndNotebook, ALFNotebookPriv *priv, HWND panel)
+ALF_Notebook_SetSingleTabBackground(ALFNotebookPriv *priv, HWND panel)
{
- (void)hwndNotebook;
SendMessage(panel, ALF_WM_SETBGCOLOR, 0, (LPARAM)priv->tabPaneBgColor);
}
static void
-ALF_Notebook_SetAllTabBackgrounds(HWND hwndNotebook, ALFNotebookPriv *priv)
+ALF_Notebook_SetAllTabBackgrounds(ALFNotebookPriv *priv)
{
- int n = ALF_Notebook_InternalTabCount(hwndNotebook, priv->hwndTabCtrl);
- for (int i = 0; i < n; ++i) {
- ALFNotebookPage p;
- ZeroMemory(&p, sizeof(p));
- p.header.mask = TCIF_PARAM;
-
- if (TabCtrl_GetItem(priv->hwndTabCtrl, i, &p)) {
- if (p.layoutFlags & ALF_LAYOUT_INHERITBGCOLOR) {
- ALF_Notebook_SetSingleTabBackground(hwndNotebook, priv, p.panel);
- }
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ if (p->layoutFlags & ALF_LAYOUT_INHERITBGCOLOR) {
+ ALF_Notebook_SetSingleTabBackground(priv, p->hwndPanel);
}
}
}
static void
-ALF_Notebook_PropagateFontToPages(HWND hwndNotebook, ALFNotebookPriv *priv, HFONT font, LPARAM lparam)
+ALF_Notebook_PropagateFontToPages(ALFNotebookPriv *priv, HFONT font, LPARAM lparam)
{
- int n = ALF_Notebook_InternalTabCount(hwndNotebook, priv->hwndTabCtrl);
- for (int i = 0; i < n; ++i) {
- ALFNotebookPage p;
- ZeroMemory(&p, sizeof(p));
- p.header.mask = TCIF_PARAM;
-
- if (TabCtrl_GetItem(priv->hwndTabCtrl, i, &p)) {
- if (p.layoutFlags & ALF_LAYOUT_INHERITFONT) {
- SendMessage(p.panel, WM_SETFONT, (WPARAM)font, lparam);
- }
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ if (p->layoutFlags & ALF_LAYOUT_INHERITFONT) {
+ SendMessage(p->hwndPanel, WM_SETFONT, (WPARAM)font, lparam);
}
}
}
static void
-ALF_Notebook_PropagateDpiChange(HWND hwndNotebook, ALFNotebookPriv *priv, WPARAM wparam, LPARAM lparam)
+ALF_Notebook_PropagateDpiChange(ALFNotebookPriv *priv, WPARAM wparam, LPARAM lparam)
+{
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ SendMessage(p->hwndPanel, ALF_WM_DPICHANGE, wparam, lparam);
+ }
+}
+
+static void
+ALF_Notebook_CalculateTabContentSize(ALFNotebookPriv *priv, ALFNotebookPage *page)
+{
+ // FIXME! content size invalidation
+
+ HDC dc = GetDC(priv->hwndSwitcher);
+ HFONT oldfont = SelectFont(dc, priv->font);
+
+ RECT rc = { 0, 0, 0, 0 };
+ DrawText(dc, page->title, -1, &rc, DT_SINGLELINE|DT_NOPREFIX|DT_CALCRECT);
+
+ SelectFont(dc, oldfont);
+ ReleaseDC(priv->hwndSwitcher, dc);
+
+ page->contentSize.cx = rc.right - rc.left;
+ page->contentSize.cy = priv->fontHeight;
+}
+
+static void
+ALF_Notebook_InvalidateTabRects(ALFNotebookPriv *priv)
+{
+ priv->flags |= ALF_NB_FLAG_TAB_RECTS_INVALID;
+ InvalidateRect(priv->hwndSwitcher, NULL, TRUE);
+ ALF_InvalidateLayout(priv->hwndContainer);
+}
+
+static void
+ALF_Notebook_ValidateTabRects(ALFNotebookPriv *priv)
{
- int n = ALF_Notebook_InternalTabCount(hwndNotebook, priv->hwndTabCtrl);
- for (int i = 0; i < n; ++i) {
- HWND hwndPanel = ALF_Notebook_TabPanel(hwndNotebook, i);
- SendMessage(hwndPanel, ALF_WM_DPICHANGE, wparam, lparam);
+ if (!(priv->flags & ALF_NB_FLAG_TAB_RECTS_INVALID))
+ return;
+
+ priv->flags &= ~(DWORD)ALF_NB_FLAG_TAB_RECTS_INVALID;
+
+ priv->totalSwitcherWidth = 2;
+
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ ALF_Notebook_CalculateTabContentSize(priv, p);
+
+ p->calculatedTabRect.left = priv->totalSwitcherWidth;
+ p->calculatedTabRect.top = 0;
+ p->calculatedTabRect.right = priv->totalSwitcherWidth + p->contentSize.cx + 12;
+ p->calculatedTabRect.bottom = ALF_Notebook_SwitcherHeight(priv);
+
+ priv->totalSwitcherWidth = p->calculatedTabRect.right;
}
+
+ priv->totalSwitcherWidth += 2;
}
static BOOL
@@ -183,123 +279,368 @@ ALF_Notebook_InternalHandleThemeChange(HWND hwndNotebook, ALFNotebookPriv *priv)
ALF_InvalidateLayout(hwndNotebook);
if (priv->hTheme) {
- if (priv->flags & ALF_NOTEBOOK_SOLID_TAB_BACKGROUND) {
- COLORREF c;
- if (SUCCEEDED(ALF_Compat_GetThemeColor(priv->hTheme, TABP_BODY, 0, TMT_FILLCOLORHINT, &c))) {
- priv->tabPaneBgColor = (ALFColor)c;
- }
- } else {
- priv->tabPaneBgColor = ALF_COLOR_TRANSPARENT;
-
- // SPEED HACK: check if tab pane background is a single solid color
- // Windows 10 really sucks at stretching a completely white bitmap
- HDC dcNotebook = GetDC(hwndNotebook);
- HDC dcMem = CreateCompatibleDC(dcNotebook);
- SIZE s;
- if (SUCCEEDED(ALF_Compat_GetThemePartSize(priv->hTheme, dcNotebook, TABP_BODY, 0, NULL, TS_TRUE, &s))) {
- BITMAPINFO bi;
- ZeroMemory(&bi, sizeof(bi));
-
- bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
- bi.bmiHeader.biWidth = s.cx;
- bi.bmiHeader.biHeight = s.cy;
- bi.bmiHeader.biPlanes = 1;
- bi.bmiHeader.biBitCount = 32;
- bi.bmiHeader.biCompression = BI_RGB;
-
- void *bits = NULL;
- HBITMAP hDib = CreateDIBSection(dcMem, &bi, DIB_RGB_COLORS, &bits, NULL, 0);
- if (hDib) {
- HBITMAP hbmOld = SelectBitmap(dcMem, hDib);
-
- RECT r = { 0, 0, s.cx, s.cy };
- if (SUCCEEDED(ALF_Compat_DrawThemeBackground(priv->hTheme, dcMem, TABP_BODY, 0, &r, NULL))) {
- GdiFlush();
-
- COLORREF c = 0;
- if (ALF_Notebook_CheckSingleColorBits(bits, s, &c)) {
- priv->tabPaneBgColor = (ALFColor)c;
- }
- }
+ priv->tabPaneBgColor = ALF_COLOR_TRANSPARENT;
- SelectBitmap(dcMem, hbmOld);
- DeleteObject(hDib);
+ // SPEED HACK: check if tab pane background is a single solid color
+ // Windows 10 really sucks at stretching a completely white bitmap
+ HDC dcNotebook = GetDC(hwndNotebook);
+ HDC dcMem = CreateCompatibleDC(dcNotebook);
+ SIZE s;
+ if (SUCCEEDED(ALF_Compat_GetThemePartSize(priv->hTheme, dcNotebook, TABP_BODY, 0, NULL, TS_TRUE, &s))) {
+ BITMAPINFO bi;
+ ZeroMemory(&bi, sizeof(bi));
+
+ bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
+ bi.bmiHeader.biWidth = s.cx;
+ bi.bmiHeader.biHeight = s.cy;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+
+ void *bits = NULL;
+ HBITMAP hDib = CreateDIBSection(dcMem, &bi, DIB_RGB_COLORS, &bits, NULL, 0);
+ if (hDib) {
+ HBITMAP hbmOld = SelectBitmap(dcMem, hDib);
+
+ RECT r = { 0, 0, s.cx, s.cy };
+ if (SUCCEEDED(ALF_Compat_DrawThemeBackground(priv->hTheme, dcMem, TABP_BODY, 0, &r, NULL))) {
+ GdiFlush();
+
+ COLORREF c = 0;
+ if (ALF_Notebook_CheckSingleColorBits(bits, s, &c)) {
+ priv->tabPaneBgColor = (ALFColor)c;
+ }
}
- }
- DeleteDC(dcMem);
- ReleaseDC(hwndNotebook, dcNotebook);
+ SelectBitmap(dcMem, hbmOld);
+ DeleteObject(hDib);
+ }
}
+
+ DeleteDC(dcMem);
+ ReleaseDC(hwndNotebook, dcNotebook);
}
- ALF_Notebook_SetAllTabBackgrounds(hwndNotebook, priv);
+ ALF_Notebook_SetAllTabBackgrounds(priv);
}
-static HWND
-ALF_Notebook_InternalAddTab(HWND notebook, ALFNotebookPriv *priv, const TCHAR *title)
+static ALFNotebookPage *
+ALF_Notebook_AppendPage(ALFNotebookPriv *priv, const TCHAR *title)
{
+ ALFNotebookPage *page = ALF_New(ALFNotebookPage, 1);
+
+ page->hwndPanel = ALF_CreatePanelWindow(priv->hwndContainer, (WORD)-1);
+ page->layoutFlags = ALF_LAYOUT_SENDBGCHANGE | ALF_LAYOUT_SENDDPICHANGE | ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_INHERITFONT;
+ lstrcpyn(page->title, title, sizeof(page->title)/sizeof(page->title[0]));
+
RECT r;
- GetClientRect(priv->hwndTabCtrl, &r);
- TabCtrl_AdjustRect(priv->hwndTabCtrl, FALSE, &r);
- MapWindowRect(priv->hwndTabCtrl, notebook, &r);
+ ALF_Notebook_PanelRect(priv, &r);
+
+ SetWindowPos(page->hwndPanel, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOOWNERZORDER);
+
+ SendMessage(page->hwndPanel, WM_SETFONT, (WPARAM)priv->font, 0);
+ SendMessage(page->hwndPanel, ALF_WM_DPICHANGE, 0, (LPARAM)priv->dpi);
+ ALF_Notebook_SetSingleTabBackground(priv, page->hwndPanel);
- HWND hwndPanel = ALF_CreatePanelWindow(notebook, (WORD)-1);
- SetWindowPos(hwndPanel, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOOWNERZORDER);
+ ALF_ListInsert(priv->pages.prev, &page->list);
+ ALF_Notebook_InvalidateTabRects(priv);
- SendMessage(hwndPanel, WM_SETFONT, (WPARAM)SendMessage(priv->hwndTabCtrl, WM_GETFONT, 0, 0), 0);
- SendMessage(hwndPanel, ALF_WM_DPICHANGE, 0, (LPARAM)priv->dpi);
+ if (page->list.prev == &priv->pages && page->list.next == &priv->pages) {
+ // we are the only tab
+ ALF_Notebook_InternalDoTabChange(priv, page);
+ }
+
+ return page;
+}
+
+static void
+ALF_Notebook_SwitcherPaint(ALFNotebookPriv *priv, HDC dc, RECT *rcDraw)
+{
+ (void)rcDraw; // TODO: restrict some of our drawing to the invalidation rect
- ALF_Notebook_SetSingleTabBackground(notebook, priv, hwndPanel);
+ ALF_Notebook_ValidateTabRects(priv);
- ALFNotebookPage p;
- ZeroMemory(&p, sizeof(p));
+ HFONT oldfont = SelectFont(dc, priv->font);
- p.header.mask = TCIF_TEXT | TCIF_PARAM;
- p.header.pszText = (TCHAR*)title;
- p.layoutFlags = ALF_LAYOUT_INHERITBGCOLOR | ALF_LAYOUT_INHERITFONT;
- p.panel = hwndPanel;
+ RECT rcClient;
+ GetClientRect(priv->hwndSwitcher, &rcClient);
- TabCtrl_InsertItem(priv->hwndTabCtrl, ALF_Notebook_InternalTabCount(notebook, priv->hwndTabCtrl), &p);
- ALF_Notebook_InternalHandleTabChange(notebook, priv);
+ HBRUSH hbrBtnFace = GetSysColorBrush(COLOR_BTNFACE);
+ COLORREF clrBtnFace = GetSysColor(COLOR_BTNFACE);
+ COLORREF clrBtnHilight = GetSysColor(COLOR_3DHILIGHT);
+ COLORREF clrBtnDdkShadow = GetSysColor(COLOR_3DDKSHADOW);
+ COLORREF clrBtnText = GetSysColor(COLOR_BTNTEXT);
+
+ if (!priv->selectedPage || priv->pages.next != &priv->selectedPage->list) {
+ RECT rcLeftTop = { 0,
+ ALF_Notebook_SwitcherHeight(priv) - 1,
+ 2,
+ ALF_Notebook_SwitcherHeight(priv) };
+ DrawEdge(dc, &rcLeftTop, EDGE_RAISED, BF_SOFT|BF_TOPLEFT);
+
+ RECT rcLeftSpace = { 0,
+ 0,
+ rcLeftTop.right,
+ rcLeftTop.top };
+ FillRect(dc, &rcLeftSpace, hbrBtnFace);
+ }
+
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ RECT r = p->calculatedTabRect;
+
+ if (p != priv->selectedPage) {
+ RECT rBottom = { r.left + 2,
+ r.bottom - 1,
+ r.right - 2,
+ r.bottom };
+
+ r.bottom -= 1;
+ r.top += 2;
+
+ if (!priv->selectedPage || p->list.prev != &priv->selectedPage->list) {
+ RECT rLeft = { r.left,
+ r.top + 2,
+ r.left + 2,
+ r.bottom };
+ DrawEdge(dc, &rLeft, EDGE_RAISED, BF_LEFT|BF_SOFT);
+
+ // could have used the BF_DIAGONAL_* funtions here, but we want
+ // to draw each pixel at most once for flicker-free display
+ SetPixel(dc, r.left + 1, r.top + 1, clrBtnHilight);
+ SetPixel(dc, r.left, r.top, clrBtnFace);
+ SetPixel(dc, r.left + 1, r.top, clrBtnFace);
+ SetPixel(dc, r.left, r.top + 1, clrBtnFace);
+
+ rBottom.left -= 2;
+ }
+
+ if (!priv->selectedPage || p->list.next != &priv->selectedPage->list) {
+ RECT rRight = { r.right - 2,
+ r.top + 2,
+ r.right,
+ r.bottom };
+ DrawEdge(dc, &rRight, EDGE_RAISED, BF_RIGHT|BF_SOFT);
+
+ // could have used the BF_DIAGONAL_* funtions here, but we want
+ // to draw each pixel at most once for flicker-free display
+ SetPixel(dc, r.right - 2, r.top + 1, clrBtnDdkShadow);
+ SetPixel(dc, r.right - 2, r.top, clrBtnFace);
+ SetPixel(dc, r.right - 1, r.top, clrBtnFace);
+ SetPixel(dc, r.right - 1, r.top + 1, clrBtnFace);
+
+ rBottom.right += 2;
+ }
+
+ RECT rTop = { r.left + 2, r.top, r.right - 2, r.top + 2 };
+ DrawEdge(dc, &rTop, EDGE_RAISED, BF_TOP|BF_SOFT);
+ DrawEdge(dc, &rBottom, EDGE_RAISED, BF_SOFT|BF_TOP);
+
+ RECT rTopSpace = { rBottom.left, r.top-2, rBottom.right, r.top };
+ FillRect(dc, &rTopSpace, hbrBtnFace);
+
+ r.left += 2;
+ r.right -= 2;
+ } else {
+ InflateRect(&r, 2, 0);
+
+ RECT rLeft = { r.left,
+ r.top + 2,
+ r.left + 2,
+ r.bottom };
+ RECT rRight = { r.right - 2,
+ r.top + 2,
+ r.right,
+ r.bottom };
+ RECT rTop = { r.left + 2,
+ r.top,
+ r.right - 2,
+ r.top + 1 };
+
+ DrawEdge(dc, &rLeft, EDGE_RAISED, BF_SOFT|BF_LEFT);
+ DrawEdge(dc, &rRight, EDGE_RAISED, BF_SOFT|BF_RIGHT);
+ DrawEdge(dc, &rTop, EDGE_RAISED, BF_SOFT|BF_TOP);
+
+
+ // could have used the BF_DIAGONAL_* funtions here, but we want
+ // to draw each pixel at most once for flicker-free display
+ SetPixel(dc, r.left + 1, r.top + 1, clrBtnHilight);
+ SetPixel(dc, r.left, r.top, clrBtnFace);
+ SetPixel(dc, r.left + 1, r.top, clrBtnFace);
+ SetPixel(dc, r.left, r.top + 1, clrBtnFace);
+
+ // could have used the BF_DIAGONAL_* funtions here, but we want
+ // to draw each pixel at most once for flicker-free display
+ SetPixel(dc, r.right - 2, r.top + 1, clrBtnDdkShadow);
+ SetPixel(dc, r.right - 2, r.top, clrBtnFace);
+ SetPixel(dc, r.right - 1, r.top, clrBtnFace);
+ SetPixel(dc, r.right - 1, r.top + 1, clrBtnFace);
+
+ r.left += 2;
+ r.right -= 2;
+
+ RECT rBottom = { r.left, r.bottom - 2, r.right, r.bottom };
+ FillRect(dc, &rBottom, hbrBtnFace);
+
+ r.bottom -= 2;
+ }
- ALF_InvalidateLayout(notebook);
+ r.top += 1;
- return hwndPanel;
+ SetBkColor(dc, clrBtnFace);
+ SetBkMode(dc, OPAQUE);
+ SetTextColor(dc, clrBtnText);
+
+ int textX = r.left + (r.right - r.left - p->contentSize.cx) / 2;
+ int textY = r.top + (r.bottom - r.top - p->contentSize.cy) / 2;
+
+ ExtTextOut(dc, textX, textY, ETO_OPAQUE, &r, p->title, (UINT)lstrlen(p->title), NULL);
+
+ if (p == priv->selectedPage && priv->flags & ALF_NB_FLAG_SWITCHER_FOCUSED && !(priv->flags & ALF_NB_FLAG_SWITCHER_HIDEFOCUS)) {
+ RECT rcFocus = { p->calculatedTabRect.left + 1,
+ p->calculatedTabRect.top + 3,
+ p->calculatedTabRect.right - 1,
+ p->calculatedTabRect.bottom - 2 };
+ DrawFocusRect(dc, &rcFocus);
+ }
+ }
+
+ RECT rcRightTop = { priv->totalSwitcherWidth, ALF_Notebook_SwitcherHeight(priv) - 1,
+ rcClient.right-rcClient.left, ALF_Notebook_SwitcherHeight(priv) };
+
+ if (!priv->selectedPage || priv->pages.prev != &priv->selectedPage->list) {
+ rcRightTop.left -= 2;
+ }
+
+ if (rcRightTop.left < rcRightTop.right) {
+ DrawEdge(dc, &rcRightTop, EDGE_RAISED, BF_SOFT|BF_TOPRIGHT);
+
+ RECT rcRightSpace = { rcRightTop.left, 0,
+ rcRightTop.right, rcRightTop.top };
+ FillRect(dc, &rcRightSpace, GetSysColorBrush(COLOR_BTNFACE));
+ }
+
+ SelectFont(dc, oldfont);
}
+static void
+ALF_Notebook_HandleSwitcherUIState(ALFNotebookPriv *priv)
+{
+ LRESULT uistate = SendMessage(priv->hwndSwitcher, WM_QUERYUISTATE, 0, 0);
+ if (uistate & UISF_HIDEFOCUS) {
+ priv->flags |= ALF_NB_FLAG_SWITCHER_HIDEFOCUS;
+ } else {
+ priv->flags &= ~(DWORD)ALF_NB_FLAG_SWITCHER_HIDEFOCUS;
+ }
+
+ if (priv->selectedPage) {
+ InvalidateRect(priv->hwndSwitcher, &priv->selectedPage->calculatedTabRect, TRUE);
+ }
+}
static LRESULT CALLBACK
-ALF_Notebook_TabCtrlWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ALF_Notebook_SwitcherWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- WNDPROC oldWndProc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ ALFNotebookPriv *priv = (ALFNotebookPriv *)GetWindowLongPtr(hwnd, 0);
+ if (!priv)
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
if (uMsg == WM_ERASEBKGND) {
- // see: http://www.virtualdub.org/blog/pivot/entry.php?id=291
- HDC hdc = (HDC)wParam;
+ return TRUE;
+ } else if (uMsg == WM_PAINT) {
+ PAINTSTRUCT ps;
+ HDC dc = BeginPaint(hwnd, &ps);
- RECT r;
- GetClientRect(hwnd, &r);
- TabCtrl_AdjustRect(hwnd, FALSE, &r);
+ ALF_Notebook_SwitcherPaint(priv, dc, &ps.rcPaint);
- ExcludeClipRect(hdc, r.left, r.top, r.right, r.bottom);
- }
- if (uMsg == WM_DESTROY) {
- SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)oldWndProc);
+ EndPaint(hwnd, &ps);
+
+ return 0;
+ } else if (uMsg == WM_LBUTTONDOWN) {
+ int xpos = GET_X_LPARAM(lParam);
+ int ypos = GET_Y_LPARAM(lParam);
+
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ if (xpos >= p->calculatedTabRect.left && xpos < p->calculatedTabRect.right &&
+ ypos >= p->calculatedTabRect.top && ypos < p->calculatedTabRect.bottom) {
+ if (p != priv->selectedPage) {
+ ALF_Notebook_InternalDoTabChange(priv, p);
+ } else {
+ SetFocus(priv->hwndSwitcher);
+ }
+ break;
+ }
+ }
+ } else if (uMsg == WM_WINDOWPOSCHANGED) {
+ WINDOWPOS *pos = (WINDOWPOS *)lParam;
+ if (!(pos->flags & SWP_NOSIZE)) {
+ RECT rcClient;
+ GetClientRect(hwnd, &rcClient);
+
+ if (rcClient.bottom - rcClient.top != priv->oldSwitcherSize.cy) {
+ // height changed - this should basically never happen, do it the easy way
+ InvalidateRect(hwnd, NULL, TRUE);
+ }
+ if (rcClient.right - rcClient.left > priv->oldSwitcherSize.cx) {
+ // width increased
+ RECT rc = { priv->oldSwitcherSize.cx - 2, 0,
+ rcClient.right - rcClient.left, rcClient.bottom - rcClient.top };
+ InvalidateRect(hwnd, &rc, TRUE);
+ }
+ if (rcClient.right - rcClient.left < priv->oldSwitcherSize.cx) {
+ // width decreased
+ RECT rc = { rcClient.right - rcClient.left - 2,
+ rcClient.bottom - rcClient.top - 1,
+ rcClient.right - rcClient.left,
+ rcClient.bottom - rcClient.top };
+ InvalidateRect(hwnd, &rc, TRUE);
+ }
+
+ priv->oldSwitcherSize.cx = rcClient.right - rcClient.left;
+ priv->oldSwitcherSize.cy = rcClient.bottom - rcClient.top;
+ }
+ } else if (uMsg == WM_SETFOCUS) {
+ priv->flags |= ALF_NB_FLAG_SWITCHER_FOCUSED;
+
+ if (priv->selectedPage) {
+ InvalidateRect(hwnd, &priv->selectedPage->calculatedTabRect, TRUE);
+ }
+ } else if (uMsg == WM_KILLFOCUS) {
+ priv->flags &= ~(DWORD)ALF_NB_FLAG_SWITCHER_FOCUSED;
+
+ if (priv->selectedPage) {
+ InvalidateRect(hwnd, &priv->selectedPage->calculatedTabRect, TRUE);
+ }
+ } else if (uMsg == WM_UPDATEUISTATE) {
+ LRESULT r = DefWindowProc(hwnd, uMsg, wParam, lParam);
+
+ ALF_Notebook_HandleSwitcherUIState(priv);
+
+ return r;
+ } else if (uMsg == WM_KEYDOWN) {
+ if (wParam == VK_LEFT && priv->selectedPage && priv->selectedPage->list.prev != &priv->pages) {
+ ALF_Notebook_InternalDoTabChange(priv, ALF_LIST_CONTAINER(ALFNotebookPage, list, priv->selectedPage->list.prev));
+ return 0;
+ }
+ if (wParam == VK_RIGHT && priv->selectedPage && priv->selectedPage->list.next != &priv->pages) {
+ ALF_Notebook_InternalDoTabChange(priv, ALF_LIST_CONTAINER(ALFNotebookPage, list, priv->selectedPage->list.next));
+ return 0;
+ }
+ } else if (uMsg == WM_GETDLGCODE) {
+ return DLGC_WANTARROWS;
+ } else if (uMsg == WM_DESTROY) {
SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
}
- return CallWindowProc(oldWndProc, hwnd, uMsg, wParam, lParam);
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
static void
-ALF_Notebook_InternalPaint(HWND hwnd, ALFNotebookPriv *priv, HDC dc, RECT *f)
+ALF_Notebook_ContainerPaint(ALFNotebookPriv *priv, HDC dc, RECT *f)
{
if (priv->hTheme != NULL) {
RECT r;
- GetClientRect(priv->hwndTabCtrl, &r);
- TabCtrl_AdjustRect(priv->hwndTabCtrl, FALSE, &r);
- MapWindowRect(priv->hwndTabCtrl, hwnd, &r);
+ ALF_Notebook_PanelRect(priv, &r);
SIZE s;
if (SUCCEEDED(ALF_Compat_GetThemePartSize(priv->hTheme, dc, TABP_BODY, 0, NULL, TS_TRUE, &s))) {
@@ -323,22 +664,23 @@ ALF_Notebook_InternalPaint(HWND hwnd, ALFNotebookPriv *priv, HDC dc, RECT *f)
ExcludeClipRect(dc, r.left, r.top, r.right, r.bottom);
}
- FillRect(dc, f, GetSysColorBrush(COLOR_BTNFACE));
+ RECT rcClient;
+ GetClientRect(priv->hwndContainer, &rcClient);
+
+ RECT rcBorder = { 0, ALF_Notebook_SwitcherHeight(priv),
+ rcClient.right - rcClient.left,
+ rcClient.bottom - rcClient.top
+ };
+ DrawEdge(dc, &rcBorder, EDGE_RAISED, BF_SOFT|BF_LEFT|BF_RIGHT|BF_BOTTOM|BF_ADJUST);
+ FillRect(dc, &rcBorder, GetSysColorBrush(COLOR_BTNFACE));
}
static DWORD
-ALF_Notebook_GetControlFlags(HWND hwndNotebook, ALFNotebookPriv *priv, HWND control)
+ALF_Notebook_GetControlFlags(ALFNotebookPriv *priv, HWND control)
{
- int n = ALF_Notebook_InternalTabCount(hwndNotebook, priv->hwndTabCtrl);
- for (int i = 0; i < n; ++i) {
- ALFNotebookPage p;
- ZeroMemory(&p, sizeof(p));
- p.header.mask = TCIF_PARAM;
-
- if (TabCtrl_GetItem(priv->hwndTabCtrl, i, &p)) {
- if (p.panel == control) {
- return p.layoutFlags;
- }
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ if (p->hwndPanel == control) {
+ return p->layoutFlags;
}
}
@@ -346,30 +688,22 @@ ALF_Notebook_GetControlFlags(HWND hwndNotebook, ALFNotebookPriv *priv, HWND cont
}
static BOOL
-ALF_Notebook_SetControlFlags(HWND hwndNotebook, ALFNotebookPriv *priv, HWND control, DWORD flags)
+ALF_Notebook_SetControlFlags(ALFNotebookPriv *priv, HWND control, DWORD flags)
{
- int n = ALF_Notebook_InternalTabCount(hwndNotebook, priv->hwndTabCtrl);
- for (int i = 0; i < n; ++i) {
- ALFNotebookPage p;
- ZeroMemory(&p, sizeof(p));
- p.header.mask = TCIF_PARAM;
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ if (p->hwndPanel == control) {
+ if (p->layoutFlags == flags)
+ return TRUE;
- if (TabCtrl_GetItem(priv->hwndTabCtrl, i, &p)) {
- if (p.panel == control) {
- if (p.layoutFlags == flags)
- return TRUE;
-
- if ((flags & ALF_LAYOUT_INHERITFONT) && !(p.layoutFlags & ALF_LAYOUT_INHERITFONT)) {
- SendMessage(p.panel, WM_SETFONT, (WPARAM)SendMessage(priv->hwndTabCtrl, WM_GETFONT, 0, 0), TRUE);
- }
- if ((flags & ALF_LAYOUT_INHERITBGCOLOR) && !(p.layoutFlags & ALF_LAYOUT_INHERITBGCOLOR)) {
- ALF_Notebook_SetSingleTabBackground(hwndNotebook, priv, p.panel);
- }
-
- p.layoutFlags = flags;
-
- return TabCtrl_SetItem(priv->hwndTabCtrl, i, &p);
+ if ((flags & ALF_LAYOUT_INHERITFONT) && !(p->layoutFlags & ALF_LAYOUT_INHERITFONT)) {
+ SendMessage(p->hwndPanel, WM_SETFONT, (WPARAM)priv->font, TRUE);
+ }
+ if ((flags & ALF_LAYOUT_INHERITBGCOLOR) && !(p->layoutFlags & ALF_LAYOUT_INHERITBGCOLOR)) {
+ ALF_Notebook_SetSingleTabBackground(priv, p->hwndPanel);
}
+
+ p->layoutFlags = flags;
+ return TRUE;
}
}
@@ -377,66 +711,67 @@ ALF_Notebook_SetControlFlags(HWND hwndNotebook, ALFNotebookPriv *priv, HWND cont
}
static LRESULT CALLBACK
-ALF_Notebook_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ALF_Notebook_ContainerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ALFNotebookPriv *priv = (ALFNotebookPriv *)GetWindowLongPtr(hwnd, 0);
- if (uMsg == WM_NOTIFY) {
- NMHDR *pnmh = (NMHDR*)lParam;
- if (pnmh->hwndFrom == priv->hwndTabCtrl && pnmh->code == TCN_SELCHANGE) {
- ALF_Notebook_InternalHandleTabChange(hwnd, priv);
-
- return TRUE;
- }
- }
-
if (ALF_ShouldMessageBubble(hwnd, uMsg, wParam, lParam))
return SendMessage(GetParent(hwnd), uMsg, wParam, lParam);
if (uMsg == WM_CREATE && priv == NULL) {
priv = ALF_Notebook_CreatePriv();
- priv->hwndTabCtrl = CreateWindowEx(0,
- WC_TABCONTROL,
- TEXT(""),
- WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS,
- 0, 0, 100, 100,
- hwnd,
- NULL,
- ALF_HINSTANCE,
- NULL);
-
- TabCtrl_SetItemExtra(priv->hwndTabCtrl, sizeof(ALFNotebookPage) - sizeof(TCITEMHEADER));
-
- LONG_PTR wndProc = GetWindowLongPtr(priv->hwndTabCtrl, GWLP_WNDPROC);
- SetWindowLongPtr(priv->hwndTabCtrl, GWLP_USERDATA, wndProc);
- SetWindowLongPtr(priv->hwndTabCtrl, GWLP_WNDPROC, (LONG_PTR)ALF_Notebook_TabCtrlWndProc);
-
- SetWindowLongPtr(hwnd, 0, (LONG_PTR)priv);
+ priv->hwndContainer = hwnd;
+ priv->hwndSwitcher = ALF_CreateControlWindow(0,
+ TEXT(""),
+ WS_CHILD | WS_VISIBLE | WS_TABSTOP,
+ 0, 0, 100, 40, // FIXME!
+ priv->hwndContainer,
+ NULL,
+ ALF_Notebook_SwitcherWndProc,
+ NULL);
+ SetWindowLongPtr(priv->hwndSwitcher, 0, (LONG_PTR)priv);
+ SetWindowLongPtr(priv->hwndContainer, 0, (LONG_PTR)priv);
ALF_Notebook_InternalHandleThemeChange(hwnd, priv);
+ ALF_Notebook_InvalidateTabRects(priv);
+ ALF_Notebook_HandleSwitcherUIState(priv);
}
if (!priv)
return DefWindowProc(hwnd, uMsg, wParam, lParam);
if (uMsg == WM_DESTROY) {
+ DestroyWindow(priv->hwndSwitcher);
ALF_Notebook_FreePriv(priv);
SetWindowLongPtr(hwnd, 0, 0);
priv = NULL;
} else if (uMsg == WM_SETFONT) {
- SendMessage(priv->hwndTabCtrl, WM_SETFONT, wParam, lParam);
+ priv->font = (HFONT)wParam;
+
+ HDC dc = GetDC(hwnd);
+ HFONT oldfont = SelectFont(dc, priv->font);
+
+ TEXTMETRIC tm;
+ ZeroMemory(&tm, sizeof(tm));
- ALF_Notebook_PropagateFontToPages(hwnd, priv, (HFONT)wParam, lParam);
+ if (GetTextMetrics(dc, &tm)) {
+ priv->fontHeight = tm.tmHeight;
+ }
+
+ SelectFont(dc, oldfont);
+ ReleaseDC(hwnd, dc);
+ ALF_Notebook_PropagateFontToPages(priv, (HFONT)wParam, lParam);
+ ALF_Notebook_InvalidateTabRects(priv);
ALF_InvalidateLayout(hwnd);
} else if (uMsg == WM_GETFONT) {
- return SendMessage(priv->hwndTabCtrl, WM_GETFONT, wParam, lParam);
+ return (LRESULT)priv->font;
} else if (uMsg == ALF_WM_QUERYSIZE) {
- int n = ALF_Notebook_InternalTabCount(hwnd, priv->hwndTabCtrl);
+ ALF_Notebook_ValidateTabRects(priv);
+
RECT r = { 0, 0, 0, 0 };
- for (int i = 0; i < n; ++i) {
- HWND p = ALF_Notebook_InternalTabPanel(hwnd, priv->hwndTabCtrl, i);
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
SIZE s = { 0, 0 };
- SendMessage(p, ALF_WM_QUERYSIZE, 0, (LPARAM)&s);
+ SendMessage(p->hwndPanel, ALF_WM_QUERYSIZE, 0, (LPARAM)&s);
if (s.cx > r.right)
r.right = s.cx;
if (s.cy > r.bottom)
@@ -448,7 +783,10 @@ ALF_Notebook_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (!r.bottom)
r.bottom = 100; // FIXME!
- TabCtrl_AdjustRect(priv->hwndTabCtrl, TRUE, &r);
+ ALF_Notebook_PanelToContainerRect(priv, &r);
+
+ if (r.right - r.left < priv->totalSwitcherWidth)
+ r.right = r.left + priv->totalSwitcherWidth;
SIZE *ps = (SIZE*)lParam;
if (ps->cx < r.right - r.left) {
@@ -463,52 +801,74 @@ ALF_Notebook_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} else if (uMsg == WM_WINDOWPOSCHANGED) {
WINDOWPOS *pos = (WINDOWPOS *)lParam;
if (!(pos->flags & SWP_NOSIZE)) {
- RECT r;
- GetClientRect(hwnd, &r);
- int n = ALF_Notebook_InternalTabCount(hwnd, priv->hwndTabCtrl);
-
- RECT oldR;
- GetWindowRect(priv->hwndTabCtrl, &oldR);
- TabCtrl_AdjustRect(priv->hwndTabCtrl, FALSE, &oldR);
-
- HDWP hdwp = BeginDeferWindowPos(n+1);
+ RECT rcPanel;
+ RECT rcClient;
+ ALF_Notebook_PanelRect(priv, &rcPanel);
+ GetClientRect(hwnd, &rcClient);
- // SWP_COPYBITS: NT 3.51 sadness, will not invalidate bottom edge properly on resize
- // even though it redraws everything else with great flicker
- // the flicker problem is present in every other version of windows, too
- hdwp = DeferWindowPos(hdwp, priv->hwndTabCtrl, NULL,
- 0, 0, r.right-r.left, r.bottom-r.top,
- SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOCOPYBITS);
+ HDWP hdwp = BeginDeferWindowPos(10 /*FIXME*/);
- TabCtrl_AdjustRect(priv->hwndTabCtrl, FALSE, &r);
+ hdwp = DeferWindowPos(hdwp, priv->hwndSwitcher, NULL,
+ 0, 0, rcClient.right-rcClient.left, ALF_Notebook_SwitcherHeight(priv),
+ SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
- for (int i = 0; i < n; ++i) {
- HWND p = ALF_Notebook_InternalTabPanel(hwnd, priv->hwndTabCtrl, i);
+ RECT oldPanelRect = { 0,0,0,0 };
+ if (priv->selectedPage) {
+ GetClientRect(priv->selectedPage->hwndPanel, &oldPanelRect);
+ }
- hdwp = DeferWindowPos(hdwp, p, NULL,
- r.left, r.top, r.right - r.left, r.bottom - r.top,
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, p) {
+ hdwp = DeferWindowPos(hdwp, p->hwndPanel, NULL,
+ rcPanel.left, rcPanel.top,
+ rcPanel.right - rcPanel.left, rcPanel.bottom - rcPanel.top,
SWP_NOACTIVATE|SWP_NOZORDER);
}
EndDeferWindowPos(hdwp);
- if (priv->hTheme
+ if (priv->selectedPage && priv->hTheme
&& priv->tabPaneBgColor == ALF_COLOR_TRANSPARENT
- && ((oldR.bottom - oldR.top) != (r.bottom - r.top))) {
+ && ((oldPanelRect.bottom - oldPanelRect.top) != (rcClient.bottom - rcClient.top))) {
// only needed when height changes, since bg is tiled horizontally
- HWND panel = ALF_Notebook_SelectedPanel(hwnd);
- if (panel != NULL)
- ALF_InvalidateBackground(panel);
+ ALF_InvalidateBackground(priv->selectedPage->hwndPanel);
+ }
+
+ if (rcClient.bottom - rcClient.top > priv->oldContainerSize.cy) {
+ // height increased
+ RECT rc = { 0, priv->oldContainerSize.cy - 4,
+ rcClient.right - rcClient.left, rcClient.bottom - rcClient.top };
+ InvalidateRect(hwnd, &rc, TRUE);
}
+ if (rcClient.bottom - rcClient.top < priv->oldContainerSize.cy) {
+ // height decreased
+ RECT rc = { 0, rcClient.bottom - rcClient.top - 4,
+ rcClient.right - rcClient.left, rcClient.bottom - rcClient.top };
+ InvalidateRect(hwnd, &rc, TRUE);
+ }
+ if (rcClient.right - rcClient.left > priv->oldContainerSize.cx) {
+ // width increased
+ RECT rc = { priv->oldContainerSize.cx - 4, 0,
+ rcClient.right - rcClient.left, rcClient.bottom - rcClient.top };
+ InvalidateRect(hwnd, &rc, TRUE);
+ }
+ if (rcClient.right - rcClient.left < priv->oldContainerSize.cx) {
+ // width decreased
+ RECT rc = { rcClient.right - rcClient.left - 4, 0,
+ rcClient.right - rcClient.left, rcClient.bottom - rcClient.top };
+ InvalidateRect(hwnd, &rc, TRUE);
+ }
+
+ priv->oldContainerSize.cx = rcClient.right - rcClient.left;
+ priv->oldContainerSize.cy = rcClient.bottom - rcClient.top;
}
} else if (uMsg == ALF_WM_NTBK_ADDTAB) {
- return (LRESULT)ALF_Notebook_InternalAddTab(hwnd, priv, (TCHAR *)lParam);
+ return (LRESULT)ALF_Notebook_AppendPage(priv, (TCHAR *)lParam)->hwndPanel;
} else if (uMsg == ALF_WM_NTBK_TABCOUNT) {
- return (LRESULT)ALF_Notebook_InternalTabCount(hwnd, priv->hwndTabCtrl);
+ return (LRESULT)ALF_Notebook_InternalTabCount(priv);
} else if (uMsg == ALF_WM_NTBK_GETPANEL) {
- return (LRESULT)ALF_Notebook_InternalTabPanel(hwnd, priv->hwndTabCtrl, (int)lParam);
- } else if (uMsg == ALF_WM_NTBK_GETSELINDEX) {
- return (LRESULT)ALF_Notebook_InternalSelectedIndex(hwnd, priv->hwndTabCtrl);
+ return (LRESULT)ALF_Notebook_InternalTabPanel(priv, (int)lParam);
+ } else if (uMsg == ALF_WM_NTBK_GETSELPANEL) {
+ return (LRESULT)ALF_Notebook_InternalSelectedPanel(priv);
} else if (uMsg == WM_THEMECHANGED) {
ALF_Notebook_InternalHandleThemeChange(hwnd, priv);
} else if (uMsg == WM_ERASEBKGND) {
@@ -517,34 +877,25 @@ ALF_Notebook_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
RECT r = {0, 0, 0, 0};
GetClientRect(hwnd, &r);
- ALF_Notebook_InternalPaint(hwnd, priv, (HDC)wParam, &r);
+ ALF_Notebook_ContainerPaint(priv, (HDC)wParam, &r);
return TRUE;
} else if (uMsg == WM_PAINT) {
PAINTSTRUCT ps;
HDC dc = BeginPaint(hwnd, &ps);
- ALF_Notebook_InternalPaint(hwnd, priv, dc, &ps.rcPaint);
+ ALF_Notebook_ContainerPaint(priv, dc, &ps.rcPaint);
EndPaint(hwnd, &ps);
return 0;
} else if (uMsg == ALF_WM_INVALIDATELAYOUT) {
ALF_InvalidateLayout(GetParent(hwnd));
- } else if (uMsg == ALF_WM_NTBK_GETFLAGS) {
- return (LRESULT)priv->flags;
- } else if (uMsg == ALF_WM_NTBK_SETFLAGS) {
- DWORD oldFlags = priv->flags;
- priv->flags = (DWORD)lParam;
-
- if ((oldFlags & ALF_NOTEBOOK_SOLID_TAB_BACKGROUND) != (priv->flags & ALF_NOTEBOOK_SOLID_TAB_BACKGROUND)) {
- ALF_Notebook_InternalHandleThemeChange(hwnd, priv);
- }
} else if (uMsg == ALF_WM_LYT_GETCTLFLAGS) {
- return (LRESULT)ALF_Notebook_GetControlFlags(hwnd, priv, (HWND)wParam);
+ return (LRESULT)ALF_Notebook_GetControlFlags(priv, (HWND)wParam);
} else if (uMsg == ALF_WM_LYT_SETCTLFLAGS) {
- return (LRESULT)ALF_Notebook_SetControlFlags(hwnd, priv, (HWND)wParam, (DWORD)lParam);
+ return (LRESULT)ALF_Notebook_SetControlFlags(priv, (HWND)wParam, (DWORD)lParam);
} else if (uMsg == ALF_WM_DPICHANGE) {
priv->dpi = (int)lParam;
- ALF_Notebook_PropagateDpiChange(hwnd, priv, wParam, lParam);
+ ALF_Notebook_PropagateDpiChange(priv, wParam, lParam);
return TRUE;
}
@@ -561,7 +912,7 @@ ALF_AddNotebook(HWND parent, WORD id, int x, int y)
0, 0, 100, 100,
parent,
(HMENU)(ULONG_PTR)id,
- ALF_Notebook_WindowProc,
+ ALF_Notebook_ContainerWindowProc,
NULL);
ALF_AddControl(parent, x, y, hwndNtbk, 0, 0, ALF_LAYOUT_SIZE_QUERY | ALF_LAYOUT_INHERITFONT | ALF_LAYOUT_SENDDPICHANGE);
@@ -590,31 +941,8 @@ ALF_Notebook_TabPanel(HWND notebook, int index)
return (HWND)SendMessage(notebook, ALF_WM_NTBK_GETPANEL, 0, (LPARAM)index);
}
-int
-ALF_Notebook_SelectedIndex(HWND notebook)
-{
- return (int)SendMessage(notebook, ALF_WM_NTBK_GETSELINDEX, 0, 0);
-}
-
HWND
ALF_Notebook_SelectedPanel(HWND notebook)
{
- int i = ALF_Notebook_SelectedIndex(notebook);
- if (i >= 0) {
- return ALF_Notebook_TabPanel(notebook, i);
- } else {
- return NULL;
- }
-}
-
-DWORD
-ALF_Notebook_Flags(HWND notebook)
-{
- return (DWORD)SendMessage(notebook, ALF_WM_NTBK_GETFLAGS, 0, 0);
-}
-
-void
-ALF_Notebook_SetFlags(HWND notebook, DWORD flags)
-{
- SendMessage(notebook, ALF_WM_NTBK_SETFLAGS, 0, (LPARAM)flags);
+ return (HWND)SendMessage(notebook, ALF_WM_NTBK_GETSELPANEL, 0, 0);
}