Align edge with tab (dark mode)
1. Draw frame around tabs in multi-line state (dark mode). 2. Adjust padding for hiDPI. 3. Add initializers. Fix #12737, close #12738
This commit is contained in:
parent
c63c0035f3
commit
3da880b4f8
|
@ -532,12 +532,12 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
|
||||||
}
|
}
|
||||||
else if (!_isMultiLine) // don't scroll if in multi-line mode
|
else if (!_isMultiLine) // don't scroll if in multi-line mode
|
||||||
{
|
{
|
||||||
RECT rcTabCtrl, rcLastTab;
|
RECT rcTabCtrl{}, rcLastTab{};
|
||||||
::SendMessage(_hSelf, TCM_GETITEMRECT, lastTabIndex, reinterpret_cast<LPARAM>(&rcLastTab));
|
::SendMessage(_hSelf, TCM_GETITEMRECT, lastTabIndex, reinterpret_cast<LPARAM>(&rcLastTab));
|
||||||
::GetClientRect(_hSelf, &rcTabCtrl);
|
::GetClientRect(_hSelf, &rcTabCtrl);
|
||||||
|
|
||||||
// get index of the first visible tab
|
// get index of the first visible tab
|
||||||
TC_HITTESTINFO hti;
|
TC_HITTESTINFO hti{};
|
||||||
LONG xy = NppParameters::getInstance()._dpiManager.scaleX(12); // an arbitrary coordinate inside the first visible tab
|
LONG xy = NppParameters::getInstance()._dpiManager.scaleX(12); // an arbitrary coordinate inside the first visible tab
|
||||||
hti.pt = { xy, xy };
|
hti.pt = { xy, xy };
|
||||||
int scrollTabIndex = static_cast<int32_t>(::SendMessage(_hSelf, TCM_HITTEST, 0, reinterpret_cast<LPARAM>(&hti)));
|
int scrollTabIndex = static_cast<int32_t>(::SendMessage(_hSelf, TCM_HITTEST, 0, reinterpret_cast<LPARAM>(&hti)));
|
||||||
|
@ -659,7 +659,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
POINT p;
|
POINT p{};
|
||||||
p.x = LOWORD(lParam);
|
p.x = LOWORD(lParam);
|
||||||
p.y = HIWORD(lParam);
|
p.y = HIWORD(lParam);
|
||||||
|
|
||||||
|
@ -864,7 +864,7 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
RECT rc = {};
|
RECT rc{};
|
||||||
GetClientRect(hwnd, &rc);
|
GetClientRect(hwnd, &rc);
|
||||||
FillRect((HDC)wParam, &rc, NppDarkMode::getDarkerBackgroundBrush());
|
FillRect((HDC)wParam, &rc, NppDarkMode::getDarkerBackgroundBrush());
|
||||||
|
|
||||||
|
@ -884,7 +884,9 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PAINTSTRUCT ps;
|
const bool hasMultipleLines = ((dwStyle & TCS_BUTTONS) == TCS_BUTTONS);
|
||||||
|
|
||||||
|
PAINTSTRUCT ps{};
|
||||||
HDC hdc = BeginPaint(hwnd, &ps);
|
HDC hdc = BeginPaint(hwnd, &ps);
|
||||||
FillRect(hdc, &ps.rcPaint, NppDarkMode::getDarkerBackgroundBrush());
|
FillRect(hdc, &ps.rcPaint, NppDarkMode::getDarkerBackgroundBrush());
|
||||||
|
|
||||||
|
@ -899,7 +901,9 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
|
||||||
holdClip = nullptr;
|
holdClip = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int topBarHeight = NppParameters::getInstance()._dpiManager.scaleX(4);
|
auto& dpiManager = NppParameters::getInstance()._dpiManager;
|
||||||
|
int paddingDynamicTwoX = dpiManager.scaleX(2);
|
||||||
|
int paddingDynamicTwoY = dpiManager.scaleY(2);
|
||||||
|
|
||||||
int nTabs = TabCtrl_GetItemCount(hwnd);
|
int nTabs = TabCtrl_GetItemCount(hwnd);
|
||||||
int nFocusTab = TabCtrl_GetCurFocus(hwnd);
|
int nFocusTab = TabCtrl_GetCurFocus(hwnd);
|
||||||
|
@ -920,41 +924,48 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
|
||||||
|
|
||||||
dis.itemState |= ODS_NOFOCUSRECT; // maybe, does it handle it already?
|
dis.itemState |= ODS_NOFOCUSRECT; // maybe, does it handle it already?
|
||||||
|
|
||||||
RECT rcIntersect = {};
|
RECT rcIntersect{};
|
||||||
if (IntersectRect(&rcIntersect, &ps.rcPaint, &dis.rcItem))
|
if (IntersectRect(&rcIntersect, &ps.rcPaint, &dis.rcItem))
|
||||||
{
|
{
|
||||||
if (dwStyle & TCS_VERTICAL)
|
if (!hasMultipleLines)
|
||||||
{
|
{
|
||||||
POINT edges[] = {
|
if (_isVertical)
|
||||||
{dis.rcItem.left, dis.rcItem.bottom - 1},
|
|
||||||
{dis.rcItem.right, dis.rcItem.bottom - 1}
|
|
||||||
};
|
|
||||||
if (i != nSelTab && (i != nSelTab - 1))
|
|
||||||
{
|
{
|
||||||
edges[0].x += topBarHeight;
|
POINT edges[] = {
|
||||||
|
{dis.rcItem.left, dis.rcItem.bottom - 1},
|
||||||
|
{dis.rcItem.right, dis.rcItem.bottom - 1}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (i != nSelTab && (i != nSelTab - 1))
|
||||||
|
{
|
||||||
|
edges[0].x += paddingDynamicTwoX;
|
||||||
|
}
|
||||||
|
|
||||||
|
::Polyline(hdc, edges, _countof(edges));
|
||||||
|
dis.rcItem.bottom -= 1;
|
||||||
}
|
}
|
||||||
Polyline(hdc, edges, _countof(edges));
|
else
|
||||||
dis.rcItem.bottom -= 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
POINT edges[] = {
|
|
||||||
{dis.rcItem.right - 1, dis.rcItem.top},
|
|
||||||
{dis.rcItem.right - 1, dis.rcItem.bottom}
|
|
||||||
};
|
|
||||||
if (i != nSelTab && (i != nSelTab - 1))
|
|
||||||
{
|
{
|
||||||
edges[0].y += topBarHeight;
|
POINT edges[] = {
|
||||||
|
{dis.rcItem.right - 1, dis.rcItem.top},
|
||||||
|
{dis.rcItem.right - 1, dis.rcItem.bottom}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (i != nSelTab && (i != nSelTab - 1))
|
||||||
|
{
|
||||||
|
edges[0].y += paddingDynamicTwoY;
|
||||||
|
}
|
||||||
|
|
||||||
|
::Polyline(hdc, edges, _countof(edges));
|
||||||
|
dis.rcItem.right -= 1;
|
||||||
}
|
}
|
||||||
Polyline(hdc, edges, _countof(edges));
|
|
||||||
dis.rcItem.right -= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRGN hClip = CreateRectRgnIndirect(&dis.rcItem);
|
HRGN hClip = CreateRectRgnIndirect(&dis.rcItem);
|
||||||
|
|
||||||
SelectClipRgn(hdc, hClip);
|
SelectClipRgn(hdc, hClip);
|
||||||
|
|
||||||
drawItem(&dis, true);
|
drawItem(&dis, NppDarkMode::isEnabled());
|
||||||
|
|
||||||
DeleteObject(hClip);
|
DeleteObject(hClip);
|
||||||
|
|
||||||
|
@ -962,6 +973,41 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasMultipleLines)
|
||||||
|
{
|
||||||
|
RECT rcFirstTab{};
|
||||||
|
TabCtrl_GetItemRect(hwnd, 0, &rcFirstTab);
|
||||||
|
|
||||||
|
if (_isVertical)
|
||||||
|
{
|
||||||
|
POINT edges[] = {
|
||||||
|
{rcFirstTab.left, rcFirstTab.top},
|
||||||
|
{rcFirstTab.right, rcFirstTab.top}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (nSelTab != 0)
|
||||||
|
{
|
||||||
|
edges[0].x += paddingDynamicTwoX;
|
||||||
|
}
|
||||||
|
|
||||||
|
::Polyline(hdc, edges, _countof(edges));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
POINT edges[] = {
|
||||||
|
{rcFirstTab.left, rcFirstTab.top},
|
||||||
|
{rcFirstTab.left, rcFirstTab.bottom}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (nSelTab != 0)
|
||||||
|
{
|
||||||
|
edges[0].y += paddingDynamicTwoY;
|
||||||
|
}
|
||||||
|
|
||||||
|
::Polyline(hdc, edges, _countof(edges));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SelectClipRgn(hdc, holdClip);
|
SelectClipRgn(hdc, holdClip);
|
||||||
if (holdClip)
|
if (holdClip)
|
||||||
{
|
{
|
||||||
|
@ -1048,8 +1094,9 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
|
||||||
::DeleteObject((HGDIOBJ)hBrush);
|
::DeleteObject((HGDIOBJ)hBrush);
|
||||||
|
|
||||||
// equalize drawing areas of active and inactive tabs
|
// equalize drawing areas of active and inactive tabs
|
||||||
int paddingDynamicTwoX = NppParameters::getInstance()._dpiManager.scaleX(2);
|
auto& dpiManager = NppParameters::getInstance()._dpiManager;
|
||||||
int paddingDynamicTwoY = NppParameters::getInstance()._dpiManager.scaleY(2);
|
int paddingDynamicTwoX = dpiManager.scaleX(2);
|
||||||
|
int paddingDynamicTwoY = dpiManager.scaleY(2);
|
||||||
if (isSelected && !isDarkMode)
|
if (isSelected && !isDarkMode)
|
||||||
{
|
{
|
||||||
// the drawing area of the active tab extends on all borders by default
|
// the drawing area of the active tab extends on all borders by default
|
||||||
|
@ -1088,15 +1135,16 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// the active tab's text with TCS_BUTTONS is lower than normal and gets clipped
|
// the active tab's text with TCS_BUTTONS is lower than normal and gets clipped
|
||||||
if (::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS)
|
const bool hasMultipleLines = ((::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS) == TCS_BUTTONS);
|
||||||
|
if (hasMultipleLines)
|
||||||
{
|
{
|
||||||
if (_isVertical)
|
if (_isVertical)
|
||||||
{
|
{
|
||||||
rect.left -= 2;
|
rect.left -= isDarkMode ? paddingDynamicTwoX : 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rect.top -= 2;
|
rect.top -= isDarkMode ? paddingDynamicTwoY : 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1112,15 +1160,15 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
|
||||||
|
|
||||||
if (_drawTopBar)
|
if (_drawTopBar)
|
||||||
{
|
{
|
||||||
int topBarHeight = NppParameters::getInstance()._dpiManager.scaleX(4);
|
int topBarHeight = dpiManager.scaleX(4);
|
||||||
if (_isVertical)
|
if (_isVertical)
|
||||||
{
|
{
|
||||||
barRect.left -= NppParameters::getInstance()._dpiManager.scaleX(2);
|
barRect.left -= (hasMultipleLines && isDarkMode) ? 0 : paddingDynamicTwoX;
|
||||||
barRect.right = barRect.left + topBarHeight;
|
barRect.right = barRect.left + topBarHeight;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
barRect.top -= NppParameters::getInstance()._dpiManager.scaleY(2);
|
barRect.top -= (hasMultipleLines && isDarkMode) ? 0 : paddingDynamicTwoY;
|
||||||
barRect.bottom = barRect.top + topBarHeight;
|
barRect.bottom = barRect.top + topBarHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,7 +1190,7 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
|
||||||
}
|
}
|
||||||
else // inactive tabs
|
else // inactive tabs
|
||||||
{
|
{
|
||||||
RECT rect = _isCtrlMultiLine ? pDrawItemStruct->rcItem : barRect;
|
RECT rect = hasMultipleLines ? pDrawItemStruct->rcItem : barRect;
|
||||||
COLORREF brushColour{};
|
COLORREF brushColour{};
|
||||||
|
|
||||||
if (_drawInactiveTab && individualColourId == -1)
|
if (_drawInactiveTab && individualColourId == -1)
|
||||||
|
@ -1163,6 +1211,11 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
|
||||||
::DeleteObject((HGDIOBJ)hBrush);
|
::DeleteObject((HGDIOBJ)hBrush);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDarkMode && hasMultipleLines)
|
||||||
|
{
|
||||||
|
::FrameRect(hDC, &pDrawItemStruct->rcItem, NppDarkMode::getEdgeBrush());
|
||||||
|
}
|
||||||
|
|
||||||
// draw close button
|
// draw close button
|
||||||
if (_drawTabCloseButton)
|
if (_drawTabCloseButton)
|
||||||
{
|
{
|
||||||
|
@ -1182,8 +1235,8 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
|
||||||
BITMAP bmp{};
|
BITMAP bmp{};
|
||||||
::GetObject(hBmp, sizeof(bmp), &bmp);
|
::GetObject(hBmp, sizeof(bmp), &bmp);
|
||||||
|
|
||||||
int bmDpiDynamicalWidth = NppParameters::getInstance()._dpiManager.scaleX(bmp.bmWidth);
|
int bmDpiDynamicalWidth = dpiManager.scaleX(bmp.bmWidth);
|
||||||
int bmDpiDynamicalHeight = NppParameters::getInstance()._dpiManager.scaleY(bmp.bmHeight);
|
int bmDpiDynamicalHeight = dpiManager.scaleY(bmp.bmHeight);
|
||||||
|
|
||||||
RECT buttonRect = _closeButtonZone.getButtonRectFrom(rect, _isVertical);
|
RECT buttonRect = _closeButtonZone.getButtonRectFrom(rect, _isVertical);
|
||||||
|
|
||||||
|
@ -1309,7 +1362,7 @@ void TabBarPlus::draggingCursor(POINT screenPoint)
|
||||||
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
|
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TCHAR className[256];
|
TCHAR className[256] = { '\0' };
|
||||||
::GetClassName(hWin, className, 256);
|
::GetClassName(hWin, className, 256);
|
||||||
if ((!lstrcmp(className, TEXT("Scintilla"))) || (!lstrcmp(className, WC_TABCONTROL)))
|
if ((!lstrcmp(className, TEXT("Scintilla"))) || (!lstrcmp(className, WC_TABCONTROL)))
|
||||||
{
|
{
|
||||||
|
@ -1341,11 +1394,11 @@ void TabBarPlus::setActiveTab(int tabIndex)
|
||||||
void TabBarPlus::exchangeTabItemData(int oldTab, int newTab)
|
void TabBarPlus::exchangeTabItemData(int oldTab, int newTab)
|
||||||
{
|
{
|
||||||
//1. shift their data, and insert the source
|
//1. shift their data, and insert the source
|
||||||
TCITEM itemData_nDraggedTab, itemData_shift;
|
TCITEM itemData_nDraggedTab{}, itemData_shift{};
|
||||||
itemData_nDraggedTab.mask = itemData_shift.mask = TCIF_IMAGE | TCIF_TEXT | TCIF_PARAM;
|
itemData_nDraggedTab.mask = itemData_shift.mask = TCIF_IMAGE | TCIF_TEXT | TCIF_PARAM;
|
||||||
const int stringSize = 256;
|
const int stringSize = 256;
|
||||||
TCHAR str1[stringSize];
|
TCHAR str1[stringSize] = { '\0' };
|
||||||
TCHAR str2[stringSize];
|
TCHAR str2[stringSize] = { '\0' };
|
||||||
|
|
||||||
itemData_nDraggedTab.pszText = str1;
|
itemData_nDraggedTab.pszText = str1;
|
||||||
itemData_nDraggedTab.cchTextMax = (stringSize);
|
itemData_nDraggedTab.cchTextMax = (stringSize);
|
||||||
|
@ -1436,7 +1489,7 @@ bool CloseButtonZone::isHit(int x, int y, const RECT & tabRect, bool isVertical)
|
||||||
|
|
||||||
RECT CloseButtonZone::getButtonRectFrom(const RECT & tabRect, bool isVertical) const
|
RECT CloseButtonZone::getButtonRectFrom(const RECT & tabRect, bool isVertical) const
|
||||||
{
|
{
|
||||||
RECT buttonRect;
|
RECT buttonRect{};
|
||||||
|
|
||||||
int fromBorder;
|
int fromBorder;
|
||||||
if (isVertical)
|
if (isVertical)
|
||||||
|
|
Loading…
Reference in New Issue