GUI Enhancement: Tabbar part 2

- use one tab icon size
- close button crop in RTL
- improve text positions
- font size adjustment

ref: https://github.com/notepad-plus-plus/notepad-plus-plus/pull/13702#issuecomment-1564296333

Fix #10349, fix #8109, close #13709
This commit is contained in:
ozone10 2023-05-26 17:07:19 +02:00 committed by Don Ho
parent e2f1662c90
commit 781709a022
10 changed files with 29 additions and 47 deletions

View File

@ -271,7 +271,7 @@ bool IsWindows11() // or later OS version
return (g_buildNumber >= 22000); return (g_buildNumber >= 22000);
} }
const DWORD GetWindowsBuildNumber() DWORD GetWindowsBuildNumber()
{ {
return g_buildNumber; return g_buildNumber;
} }

View File

@ -17,4 +17,4 @@ void InitDarkMode();
void SetDarkMode(bool useDarkMode, bool fixDarkScrollbar); void SetDarkMode(bool useDarkMode, bool fixDarkScrollbar);
bool IsWindows10(); bool IsWindows10();
bool IsWindows11(); bool IsWindows11();
const DWORD GetWindowsBuildNumber(); DWORD GetWindowsBuildNumber();

View File

@ -227,7 +227,7 @@ LRESULT Notepad_plus::init(HWND hwnd)
int tabBarStatus = nppGUI._tabStatus; int tabBarStatus = nppGUI._tabStatus;
_toReduceTabBar = ((tabBarStatus & TAB_REDUCE) != 0); _toReduceTabBar = ((tabBarStatus & TAB_REDUCE) != 0);
int iconDpiDynamicalSize = nppParam._dpiManager.scaleY(_toReduceTabBar ? g_TabIconSize : g_TabIconSizeLarge); int iconDpiDynamicalSize = nppParam._dpiManager.scaleX(g_TabIconSize);
_docTabIconList.create(iconDpiDynamicalSize, _pPublicInterface->getHinst(), docTabIconIDs, sizeof(docTabIconIDs) / sizeof(int)); _docTabIconList.create(iconDpiDynamicalSize, _pPublicInterface->getHinst(), docTabIconIDs, sizeof(docTabIconIDs) / sizeof(int));
_docTabIconListAlt.create(iconDpiDynamicalSize, _pPublicInterface->getHinst(), docTabIconIDs_alt, sizeof(docTabIconIDs_alt) / sizeof(int)); _docTabIconListAlt.create(iconDpiDynamicalSize, _pPublicInterface->getHinst(), docTabIconIDs_alt, sizeof(docTabIconIDs_alt) / sizeof(int));
_docTabIconListDarkMode.create(iconDpiDynamicalSize, _pPublicInterface->getHinst(), docTabIconIDs_darkMode, sizeof(docTabIconIDs_darkMode) / sizeof(int)); _docTabIconListDarkMode.create(iconDpiDynamicalSize, _pPublicInterface->getHinst(), docTabIconIDs_darkMode, sizeof(docTabIconIDs_darkMode) / sizeof(int));

View File

@ -2143,17 +2143,11 @@ void Notepad_plus::command(int id)
_toReduceTabBar = !_toReduceTabBar; _toReduceTabBar = !_toReduceTabBar;
auto& dpiManager = NppParameters::getInstance()._dpiManager; auto& dpiManager = NppParameters::getInstance()._dpiManager;
//Resize the icon
int iconDpiDynamicalSize = dpiManager.scaleY(_toReduceTabBar ? g_TabIconSize : g_TabIconSizeLarge);
//Resize the tab height //Resize the tab height
int tabDpiDynamicalWidth = dpiManager.scaleX(g_TabWidth); int tabDpiDynamicalWidth = dpiManager.scaleX(g_TabWidth);
int tabDpiDynamicalHeight = dpiManager.scaleY(_toReduceTabBar ? g_TabHeight : g_TabHeightLarge); int tabDpiDynamicalHeight = dpiManager.scaleY(_toReduceTabBar ? g_TabHeight : g_TabHeightLarge);
TabCtrl_SetItemSize(_mainDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); TabCtrl_SetItemSize(_mainDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight);
TabCtrl_SetItemSize(_subDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); TabCtrl_SetItemSize(_subDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight);
_docTabIconList.addIcons(iconDpiDynamicalSize);
_docTabIconListAlt.addIcons(iconDpiDynamicalSize);
_docTabIconListDarkMode.addIcons(iconDpiDynamicalSize);
//change the font //change the font
const auto& hf = _mainDocTab.getFont(_toReduceTabBar); const auto& hf = _mainDocTab.getFont(_toReduceTabBar);

View File

@ -553,7 +553,7 @@ namespace NppDarkMode
return IsWindows11(); return IsWindows11();
} }
const DWORD getWindowsBuildNumber() DWORD getWindowsBuildNumber()
{ {
return GetWindowsBuildNumber(); return GetWindowsBuildNumber();
} }

View File

@ -119,7 +119,7 @@ namespace NppDarkMode
bool isWindows10(); bool isWindows10();
bool isWindows11(); bool isWindows11();
const DWORD getWindowsBuildNumber(); DWORD getWindowsBuildNumber();
COLORREF invertLightness(COLORREF c); COLORREF invertLightness(COLORREF c);
COLORREF invertLightnessSofter(COLORREF c); COLORREF invertLightnessSofter(COLORREF c);

View File

@ -68,14 +68,6 @@ bool IconList::changeIcon(size_t index, const TCHAR *iconLocation) const
return (i == index); return (i == index);
} }
// used by tabbar only
void IconList::addIcons(int size) const
{
ImageList_SetIconSize(_hImglst, size, size);
for (int i = 0 ; i < _iconIDArraySize ; ++i)
addIcon(_pIconIDArray[i]);
}
void ToolBarIcons::init(ToolBarButtonUnit *buttonUnitArray, int arraySize, std::vector<DynamicCmdIcoBmp> moreCmds) void ToolBarIcons::init(ToolBarButtonUnit *buttonUnitArray, int arraySize, std::vector<DynamicCmdIcoBmp> moreCmds)
{ {
for (int i = 0 ; i < arraySize ; ++i) for (int i = 0 ; i < arraySize ; ++i)

View File

@ -43,8 +43,6 @@ public :
void addIcon(HICON hIcon) const; void addIcon(HICON hIcon) const;
bool changeIcon(size_t index, const TCHAR *iconLocation) const; bool changeIcon(size_t index, const TCHAR *iconLocation) const;
void addIcons(int size) const;
private : private :
HIMAGELIST _hImglst = nullptr; HIMAGELIST _hImglst = nullptr;

View File

@ -343,7 +343,7 @@ void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMult
LOGFONT lfVer{ lf }; LOGFONT lfVer{ lf };
_hFont = ::CreateFontIndirect(&lf); _hFont = ::CreateFontIndirect(&lf);
lf.lfWeight = FW_HEAVY; lf.lfWeight = FW_HEAVY;
lf.lfHeight = -dpiManager.pointsToPixels(12); lf.lfHeight = -(dpiManager.pointsToPixels(10));
_hLargeFont = ::CreateFontIndirect(&lf); _hLargeFont = ::CreateFontIndirect(&lf);
lfVer.lfEscapement = 900; lfVer.lfEscapement = 900;
@ -372,7 +372,7 @@ void TabBarPlus::doOwnerDrawTab()
::InvalidateRect(_hwndArray[i], NULL, TRUE); ::InvalidateRect(_hwndArray[i], NULL, TRUE);
const int paddingSizeDynamicW = NppParameters::getInstance()._dpiManager.scaleX(6); const int paddingSizeDynamicW = NppParameters::getInstance()._dpiManager.scaleX(6);
const int paddingSizePlusClosebuttonDynamicW = NppParameters::getInstance()._dpiManager.scaleX(9); const int paddingSizePlusClosebuttonDynamicW = NppParameters::getInstance()._dpiManager.scaleX(10);
::SendMessage(_hwndArray[i], TCM_SETPADDING, 0, MAKELPARAM(_drawTabCloseButton ? paddingSizePlusClosebuttonDynamicW : paddingSizeDynamicW, 0)); ::SendMessage(_hwndArray[i], TCM_SETPADDING, 0, MAKELPARAM(_drawTabCloseButton ? paddingSizePlusClosebuttonDynamicW : paddingSizeDynamicW, 0));
} }
} }
@ -1148,11 +1148,11 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
{ {
if (_isVertical) if (_isVertical)
{ {
rect.left -= isDarkMode ? paddingDynamicTwoX : 2; rect.left -= paddingDynamicTwoX;
} }
else else
{ {
rect.top -= isDarkMode ? paddingDynamicTwoY : 2; rect.top -= paddingDynamicTwoY;
} }
} }
@ -1243,13 +1243,16 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
BITMAP bmp{}; BITMAP bmp{};
::GetObject(hBmp, sizeof(bmp), &bmp); ::GetObject(hBmp, sizeof(bmp), &bmp);
int bmDpiDynamicalWidth = dpiManager.scaleX(bmp.bmWidth); _closeButtonZone._width = dpiManager.scaleX(bmp.bmWidth);
int bmDpiDynamicalHeight = dpiManager.scaleY(bmp.bmHeight); _closeButtonZone._height = dpiManager.scaleY(bmp.bmHeight);
RECT buttonRect = _closeButtonZone.getButtonRectFrom(rect, _isVertical); RECT buttonRect = _closeButtonZone.getButtonRectFrom(rect, _isVertical);
// StretchBlt will crop image in RTL if there is no stretching, thus move image by -1
const bool isRTL = (::GetWindowLongPtr(::GetParent(_hSelf), GWL_EXSTYLE) & WS_EX_LAYOUTRTL) == WS_EX_LAYOUTRTL;
const int offset = isRTL && (_closeButtonZone._width == bmp.bmWidth) ? -1 : 0;
::SelectObject(hdcMemory, hBmp); ::SelectObject(hdcMemory, hBmp);
::StretchBlt(hDC, buttonRect.left, buttonRect.top, bmDpiDynamicalWidth, bmDpiDynamicalHeight, hdcMemory, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); ::StretchBlt(hDC, buttonRect.left + offset, buttonRect.top, _closeButtonZone._width, _closeButtonZone._height, hdcMemory, offset, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
::DeleteDC(hdcMemory); ::DeleteDC(hdcMemory);
::DeleteObject(hBmp); ::DeleteObject(hBmp);
} }
@ -1344,22 +1347,17 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode)
{ {
// center text vertically // center text vertically
Flags |= DT_LEFT; Flags |= DT_LEFT;
Flags |= isStandardSize || (!hasMultipleLines && !isDarkMode) ? DT_VCENTER : DT_TOP; Flags |= DT_TOP;
// ignoring the descent when centering (text elements below the base line) is more pleasing to the eye const int paddingText = ((pDrawItemStruct->rcItem.bottom - pDrawItemStruct->rcItem.top) - (textHeight + textDescent)) / 2;
if (!isDarkMode && !isStandardSize) const int paddingDescent = !hasMultipleLines ? ((textDescent + ((isDarkMode || !isSelected) ? 1 : 0)) / 2) : 0;
rect.top = pDrawItemStruct->rcItem.top + paddingText + paddingDescent;
rect.bottom = pDrawItemStruct->rcItem.bottom - paddingText + paddingDescent;
if (isDarkMode || !isSelected || _drawTopBar)
{ {
rect.top = pDrawItemStruct->rcItem.top; rect.top += paddingDynamicTwoY;
if (hasMultipleLines && isSelected)
{
rect.top -= _drawTopBar ? 0 : paddingDynamicTwoY;
}
} }
else
{
rect.top += textDescent / 2;
}
rect.bottom += textDescent / 2;
// 1 space distance to save icon // 1 space distance to save icon
rect.left += spaceUnit; rect.left += spaceUnit;
@ -1492,8 +1490,8 @@ void TabBarPlus::exchangeItemData(POINT point)
CloseButtonZone::CloseButtonZone() CloseButtonZone::CloseButtonZone()
{ {
// TODO: get width/height of close button dynamically // TODO: get width/height of close button dynamically
_width = NppParameters::getInstance()._dpiManager.scaleX(11); _width = NppParameters::getInstance()._dpiManager.scaleX(g_TabCloseBtnSize);
_height = NppParameters::getInstance()._dpiManager.scaleY(11); _height = _width;
} }
bool CloseButtonZone::isHit(int x, int y, const RECT & tabRect, bool isVertical) const bool CloseButtonZone::isHit(int x, int y, const RECT & tabRect, bool isVertical) const
@ -1510,7 +1508,7 @@ RECT CloseButtonZone::getButtonRectFrom(const RECT & tabRect, bool isVertical) c
{ {
RECT buttonRect{}; RECT buttonRect{};
int fromBorder; int fromBorder = 0;
if (isVertical) if (isVertical)
{ {
fromBorder = (tabRect.right - tabRect.left - _width + 1) / 2; fromBorder = (tabRect.right - tabRect.left - _width + 1) / 2;

View File

@ -46,12 +46,12 @@ const TCHAR TABBAR_ACTIVEUNFOCUSEDINDCATOR[64] = TEXT("Active tab unfocused indi
const TCHAR TABBAR_ACTIVETEXT[64] = TEXT("Active tab text"); const TCHAR TABBAR_ACTIVETEXT[64] = TEXT("Active tab text");
const TCHAR TABBAR_INACTIVETEXT[64] = TEXT("Inactive tabs"); const TCHAR TABBAR_INACTIVETEXT[64] = TEXT("Inactive tabs");
constexpr int g_TabIconSize = 13; constexpr int g_TabIconSize = 16;
constexpr int g_TabIconSizeLarge = 20;
constexpr int g_TabHeight = 22; constexpr int g_TabHeight = 22;
constexpr int g_TabHeightLarge = 25; constexpr int g_TabHeightLarge = 25;
constexpr int g_TabWidth = 45; constexpr int g_TabWidth = 45;
constexpr int g_TabWidthCloseBtn = 60; constexpr int g_TabWidthCloseBtn = 60;
constexpr int g_TabCloseBtnSize = 11;
struct TBHDR struct TBHDR
{ {