Add Scroll Tab Bar with mouse wheel capacity
Closes #521, closes #522, closes #2071
This commit is contained in:
parent
9fe39017cb
commit
c76981421f
@ -441,6 +441,96 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
// ..............................................................................
|
||||
// MOUSEWHEEL:
|
||||
// will scroll the tab bar area (similar to Firefox's tab scrolling),
|
||||
// it only happens if not in multi-line mode and at least one tab is hidden
|
||||
// ..............................................................................
|
||||
// CTRL + MOUSEWHEEL:
|
||||
// will do previous/next tab WITH scroll wrapping (endless loop)
|
||||
// ..............................................................................
|
||||
// SHIFT + MOUSEWHEEL:
|
||||
// will do previous/next tab WITHOUT scroll wrapping (stops at first/last tab)
|
||||
// ..............................................................................
|
||||
// CTRL + SHIFT + MOUSEWHEEL:
|
||||
// will switch to the first/last tab
|
||||
// ..............................................................................
|
||||
|
||||
if (_isDragging)
|
||||
return TRUE;
|
||||
|
||||
const bool isForward = ((short)HIWORD(wParam)) < 0; // wheel rotation towards the user will be considered as forward direction
|
||||
const LRESULT lastTabIndex = ::SendMessage(_hSelf, TCM_GETITEMCOUNT, 0, 0) - 1;
|
||||
|
||||
if ((wParam & MK_CONTROL) && (wParam & MK_SHIFT))
|
||||
{
|
||||
::SendMessage(_hSelf, TCM_SETCURFOCUS, (isForward ? lastTabIndex : 0), 0);
|
||||
}
|
||||
else if (wParam & (MK_CONTROL | MK_SHIFT))
|
||||
{
|
||||
LRESULT tabIndex = ::SendMessage(_hSelf, TCM_GETCURSEL, 0, 0) + (isForward ? 1 : -1);
|
||||
if (tabIndex < 0)
|
||||
{
|
||||
if (wParam & MK_CONTROL)
|
||||
tabIndex = lastTabIndex; // wrap scrolling
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
else if (tabIndex > lastTabIndex)
|
||||
{
|
||||
if (wParam & MK_CONTROL)
|
||||
tabIndex = 0; // wrap scrolling
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
::SendMessage(_hSelf, TCM_SETCURFOCUS, tabIndex, 0);
|
||||
}
|
||||
else if (not _isMultiLine) // don't scroll if in multi-line mode
|
||||
{
|
||||
RECT rcTabCtrl, rcLastTab;
|
||||
::SendMessage(_hSelf, TCM_GETITEMRECT, lastTabIndex, (LPARAM)&rcLastTab);
|
||||
::GetClientRect(_hSelf, &rcTabCtrl);
|
||||
|
||||
// get index of the first visible tab
|
||||
TC_HITTESTINFO hti;
|
||||
LONG xy = NppParameters::getInstance()->_dpiManager.scaleX(12); // an arbitrary coordinate inside the first visible tab
|
||||
hti.pt = { xy, xy };
|
||||
LRESULT scrollTabIndex = ::SendMessage(_hSelf, TCM_HITTEST, 0, (LPARAM)&hti);
|
||||
|
||||
if (scrollTabIndex < 1 && (_isVertical ? rcLastTab.bottom < rcTabCtrl.bottom : rcLastTab.right < rcTabCtrl.right)) // nothing to scroll
|
||||
return TRUE;
|
||||
|
||||
// maximal width/height of the msctls_updown32 class (arrow box in the tab bar),
|
||||
// this area may hide parts of the last tab and needs to be excluded
|
||||
LONG maxLengthUpDownCtrl = NppParameters::getInstance()->_dpiManager.scaleX(44); // sufficient static value
|
||||
|
||||
// scroll forward as long as the last tab is hidden; scroll backward till the first tab
|
||||
if ((_isVertical ? ((rcTabCtrl.bottom - rcLastTab.bottom) < maxLengthUpDownCtrl) : ((rcTabCtrl.right - rcLastTab.right) < maxLengthUpDownCtrl)) || not isForward)
|
||||
{
|
||||
if (isForward)
|
||||
++scrollTabIndex;
|
||||
else
|
||||
--scrollTabIndex;
|
||||
|
||||
if (scrollTabIndex < 0 || scrollTabIndex > lastTabIndex)
|
||||
return TRUE;
|
||||
|
||||
// clear hover state of the close button,
|
||||
// WM_MOUSEMOVE won't handle this properly since the tab position will change
|
||||
if (_isCloseHover)
|
||||
{
|
||||
_isCloseHover = false;
|
||||
::InvalidateRect(_hSelf, &_currentHoverTabRect, false);
|
||||
}
|
||||
|
||||
::SendMessage(_hSelf, WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, scrollTabIndex), 0);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case WM_LBUTTONDOWN :
|
||||
{
|
||||
if (_drawTabCloseButton)
|
||||
|
Loading…
Reference in New Issue
Block a user