diff options
| -rw-r--r-- | alf/alfnotebook.cpp | 115 |
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); } |
