summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alf/alfnotebook.cpp115
1 files changed, 111 insertions, 4 deletions
diff --git a/alf/alfnotebook.cpp b/alf/alfnotebook.cpp
index dcb0a89..e264b6e 100644
--- a/alf/alfnotebook.cpp
+++ b/alf/alfnotebook.cpp
@@ -17,6 +17,7 @@
#define ALF_NB_FLAG_TAB_RECTS_INVALID 1
#define ALF_NB_FLAG_SWITCHER_FOCUSED 2
#define ALF_NB_FLAG_SWITCHER_HIDEFOCUS 4
+#define ALF_NB_FLAG_TRACKING_MOUSE 8
typedef struct {
ALFListHeader list;
@@ -38,6 +39,7 @@ typedef struct {
int dpi;
ALFListHeader pages;
ALFNotebookPage *selectedPage;
+ ALFNotebookPage *mouseoverPage;
int totalSwitcherWidth;
HFONT font;
int fontHeight;
@@ -174,6 +176,70 @@ ALF_Notebook_InternalDoTabChange(ALFNotebookPriv *priv, ALFNotebookPage *newSele
}
static void
+ALF_Notebook_HandleTabMouseover(ALFNotebookPriv *priv, int x, int y)
+{
+ (void)y;
+
+ if (priv->mouseoverPage && x >= priv->mouseoverPage->calculatedTabRect.left && x < priv->mouseoverPage->calculatedTabRect.right)
+ return; // no change
+
+ // find new mouseover page
+ ALFNotebookPage *newMouseover = NULL;
+ if (priv->mouseoverPage && x < 0 && y < 0) {
+ // mouse left the window! keep newMouseover at NULL
+ } else if (priv->mouseoverPage && x < priv->mouseoverPage->calculatedTabRect.left) {
+ // search to the left of the current page
+ for (ALFListHeader *lh = &priv->mouseoverPage->list; lh != &priv->pages; lh = lh->prev) {
+ ALFNotebookPage *page = ALF_LIST_CONTAINER(ALFNotebookPage, list, lh);
+ if (x >= page->calculatedTabRect.left) {
+ newMouseover = page;
+ break;
+ }
+ }
+ } else if (priv->mouseoverPage && x >= priv->mouseoverPage->calculatedTabRect.right) {
+ // search to the right of the current page
+ for (ALFListHeader *lh = &priv->mouseoverPage->list; lh != &priv->pages; lh = lh->next) {
+ ALFNotebookPage *page = ALF_LIST_CONTAINER(ALFNotebookPage, list, lh);
+ if (x < page->calculatedTabRect.right) {
+ newMouseover = page;
+ break;
+ }
+ }
+ } else {
+ // search all pages from the beginning
+ ALF_FOR_LIST(ALFNotebookPage, list, &priv->pages, page) {
+ if (x >= page->calculatedTabRect.left && x < page->calculatedTabRect.right) {
+ newMouseover = page;
+ break;
+ }
+ }
+ }
+
+ ALFNotebookPage *oldMouseover = priv->mouseoverPage;
+ priv->mouseoverPage = newMouseover;
+
+ if (oldMouseover) {
+ RECT r = oldMouseover->calculatedTabRect;
+ if (priv->selectedPage && priv->selectedPage->list.next == &oldMouseover->list)
+ r.left += 2;
+ if (priv->selectedPage && priv->selectedPage->list.prev == &oldMouseover->list)
+ r.right -= 2;
+
+ InvalidateRect(priv->hwndSwitcher, &r, TRUE);
+ }
+
+ if (newMouseover) {
+ RECT r = newMouseover->calculatedTabRect;
+ if (priv->selectedPage && priv->selectedPage->list.next == &newMouseover->list)
+ r.left += 2;
+ if (priv->selectedPage && priv->selectedPage->list.prev == &newMouseover->list)
+ r.right -= 2;
+
+ InvalidateRect(priv->hwndSwitcher, &r, TRUE);
+ }
+}
+
+static void
ALF_Notebook_SetSingleTabBackground(ALFNotebookPriv *priv, HWND panel)
{
SendMessage(panel, ALF_WM_SETBGCOLOR, 0, (LPARAM)priv->tabPaneBgColor);
@@ -652,7 +718,15 @@ ALF_Notebook_SwitcherPaintUx(ALFNotebookPriv *priv, HDC dc, RECT *rcDraw)
RECT rTopSpace = { rClip.left, r.top-2, rClip.right, r.top };
FillRect(dc, &rTopSpace, hbrBtnFace);
- ALF_Compat_DrawThemeBackground(priv->hTheme, dc, part, TIS_NORMAL, &rTabDraw, &rClip);
+ int state = TIS_NORMAL;
+ if (p == priv->mouseoverPage)
+ state = TIS_HOT;
+
+ if (ALF_Compat_IsThemeBackgroundPartiallyTransparent(priv->hTheme, part, state)) {
+ FillRect(dc, &rClip, hbrBtnFace);
+ }
+
+ ALF_Compat_DrawThemeBackground(priv->hTheme, dc, part, state, &rTabDraw, &rClip);
r.left += 2;
r.right -= 2;
@@ -664,14 +738,18 @@ ALF_Notebook_SwitcherPaintUx(ALFNotebookPriv *priv, HDC dc, RECT *rcDraw)
RECT rTabDraw = { r.left, r.top, r.right, r.bottom };
+ if (ALF_Compat_IsThemeBackgroundPartiallyTransparent(priv->hTheme, part, TIS_SELECTED)) {
+ FillRect(dc, &rTabDraw, hbrBtnFace);
+ }
+
ALF_Compat_DrawThemeBackground(priv->hTheme, dc, part, TIS_SELECTED, &rTabDraw, rcDraw);
r.left += 2;
r.right -= 2;
- r.bottom -= 2;
+ r.bottom -= 4;
}
- r.top += 1;
+ r.top += 2;
SetBkMode(dc, TRANSPARENT);
SetTextColor(dc, GetSysColor(COLOR_BTNTEXT)); // FIXME! theme color
@@ -682,7 +760,7 @@ ALF_Notebook_SwitcherPaintUx(ALFNotebookPriv *priv, HDC dc, RECT *rcDraw)
RECT rcFocus = { p->calculatedTabRect.left + 1,
p->calculatedTabRect.top + 3,
p->calculatedTabRect.right - 1,
- p->calculatedTabRect.bottom - 2 };
+ p->calculatedTabRect.bottom - 3 };
DrawFocusRect(dc, &rcFocus);
}
}
@@ -857,6 +935,35 @@ ALF_Notebook_SwitcherWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}
} else if (uMsg == WM_GETDLGCODE) {
return DLGC_WANTARROWS;
+ } else if (uMsg == WM_MOUSEMOVE) {
+ if (priv->flags & ALF_NB_FLAG_TRACKING_MOUSE) {
+ ALF_Notebook_HandleTabMouseover(priv, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ } else {
+ TRACKMOUSEEVENT tme;
+ ZeroMemory(&tme, sizeof(tme));
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = priv->hwndSwitcher;
+ if (ALF_Compat_TrackMouseEvent(&tme)) {
+ priv->flags |= ALF_NB_FLAG_TRACKING_MOUSE;
+ ALF_Notebook_HandleTabMouseover(priv, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ }
+ }
+ } else if (uMsg == WM_MOUSELEAVE) {
+ ALF_Notebook_HandleTabMouseover(priv, -1, -1);
+ priv->flags &= ~(DWORD)ALF_NB_FLAG_TRACKING_MOUSE;
+ } else if (uMsg == WM_NCHITTEST) {
+ POINT p = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ ScreenToClient(hwnd, &p);
+
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+
+ if (p.y < 2 || p.y > rc.bottom - rc.top - 2) {
+ return HTTRANSPARENT;
+ } else {
+ return HTCLIENT;
+ }
} else if (uMsg == WM_DESTROY) {
SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
}