From b88456764b6d136dd2ace689a076fb43846afd4b Mon Sep 17 00:00:00 2001 From: ozone10 Date: Wed, 24 May 2023 21:22:38 +0200 Subject: [PATCH] GUI Enhancement: Tabbar - prefer SystemParametersInfo fonts over DEFAULT_GUI_FONT - fix inconsistent tab bar size values - add initializer - fix override warnings Fix #13701, close #13702 --- PowerEditor/src/Notepad_plus.cpp | 24 ++++--- PowerEditor/src/NppCommands.cpp | 22 ++++--- PowerEditor/src/Parameters.cpp | 56 ++++++++++++++++ PowerEditor/src/Parameters.h | 2 + PowerEditor/src/WinControls/TabBar/TabBar.cpp | 65 ++++++++++++------- PowerEditor/src/WinControls/TabBar/TabBar.h | 30 ++++++--- 6 files changed, 143 insertions(+), 56 deletions(-) diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 6019a6429..14483ccfa 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -227,7 +227,7 @@ LRESULT Notepad_plus::init(HWND hwnd) int tabBarStatus = nppGUI._tabStatus; _toReduceTabBar = ((tabBarStatus & TAB_REDUCE) != 0); - int iconDpiDynamicalSize = nppParam._dpiManager.scaleY(_toReduceTabBar ? 13 : 20); + int iconDpiDynamicalSize = nppParam._dpiManager.scaleY(_toReduceTabBar ? g_TabIconSize : g_TabIconSizeLarge); _docTabIconList.create(iconDpiDynamicalSize, _pPublicInterface->getHinst(), docTabIconIDs, sizeof(docTabIconIDs) / 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)); @@ -375,20 +375,18 @@ LRESULT Notepad_plus::init(HWND hwnd) TabBarPlus::doDragNDrop(true); - if (_toReduceTabBar) + const auto& hf = _mainDocTab.getFont(_toReduceTabBar); + if (hf) { - HFONT hf = static_cast(::GetStockObject(DEFAULT_GUI_FONT)); - - if (hf) - { - ::SendMessage(_mainDocTab.getHSelf(), WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); - ::SendMessage(_subDocTab.getHSelf(), WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); - } - int tabDpiDynamicalHeight = nppParam._dpiManager.scaleY(22); - int tabDpiDynamicalWidth = nppParam._dpiManager.scaleX(45); - TabCtrl_SetItemSize(_mainDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); - TabCtrl_SetItemSize(_subDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); + ::SendMessage(_mainDocTab.getHSelf(), WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); + ::SendMessage(_subDocTab.getHSelf(), WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); } + + int tabDpiDynamicalHeight = nppParam._dpiManager.scaleY(_toReduceTabBar ? g_TabHeight : g_TabHeightLarge); + int tabDpiDynamicalWidth = nppParam._dpiManager.scaleX(g_TabWidth); + TabCtrl_SetItemSize(_mainDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); + TabCtrl_SetItemSize(_subDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); + _mainDocTab.display(); diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index e3f25d6be..ad67f9535 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -2138,24 +2138,25 @@ void Notepad_plus::command(int id) } break; - case IDM_VIEW_REDUCETABBAR : + case IDM_VIEW_REDUCETABBAR: { _toReduceTabBar = !_toReduceTabBar; + auto& dpiManager = NppParameters::getInstance()._dpiManager; //Resize the icon - int iconDpiDynamicalSize = NppParameters::getInstance()._dpiManager.scaleY(_toReduceTabBar?12:18); + int iconDpiDynamicalSize = dpiManager.scaleY(_toReduceTabBar ? g_TabIconSize : g_TabIconSizeLarge); //Resize the tab height - int tabDpiDynamicalWidth = NppParameters::getInstance()._dpiManager.scaleX(45); - int tabDpiDynamicalHeight = NppParameters::getInstance()._dpiManager.scaleY(_toReduceTabBar?22:25); + int tabDpiDynamicalWidth = dpiManager.scaleX(g_TabWidth); + int tabDpiDynamicalHeight = dpiManager.scaleY(_toReduceTabBar ? g_TabHeight : g_TabHeightLarge); TabCtrl_SetItemSize(_mainDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); TabCtrl_SetItemSize(_subDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); _docTabIconList.addIcons(iconDpiDynamicalSize); + _docTabIconListAlt.addIcons(iconDpiDynamicalSize); + _docTabIconListDarkMode.addIcons(iconDpiDynamicalSize); //change the font - int stockedFont = _toReduceTabBar?DEFAULT_GUI_FONT:SYSTEM_FONT; - HFONT hf = (HFONT)::GetStockObject(stockedFont); - + const auto& hf = _mainDocTab.getFont(_toReduceTabBar); if (hf) { ::SendMessage(_mainDocTab.getHSelf(), WM_SETFONT, reinterpret_cast(hf), MAKELPARAM(TRUE, 0)); @@ -2190,13 +2191,14 @@ void Notepad_plus::command(int id) break; } - case IDM_VIEW_DRAWTABBAR_CLOSEBOTTUN : + case IDM_VIEW_DRAWTABBAR_CLOSEBOTTUN: { TabBarPlus::setDrawTabCloseButton(!TabBarPlus::drawTabCloseButton()); + auto& dpiManager = NppParameters::getInstance()._dpiManager; // This part is just for updating (redraw) the tabs - int tabDpiDynamicalHeight = NppParameters::getInstance()._dpiManager.scaleY(22); - int tabDpiDynamicalWidth = NppParameters::getInstance()._dpiManager.scaleX(TabBarPlus::drawTabCloseButton() ? 60 : 45); + int tabDpiDynamicalHeight = dpiManager.scaleY(_toReduceTabBar ? g_TabHeight : g_TabHeightLarge); + int tabDpiDynamicalWidth = dpiManager.scaleX(TabBarPlus::drawTabCloseButton() ? g_TabWidthCloseBtn : g_TabWidth); TabCtrl_SetItemSize(_mainDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); TabCtrl_SetItemSize(_subDocTab.getHSelf(), tabDpiDynamicalWidth, tabDpiDynamicalHeight); diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 59330de22..8b14d8f42 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -1821,6 +1821,62 @@ HFONT NppParameters::getDefaultUIFont() return g_defaultMessageFont; } +LOGFONT NppParameters::getDefaultGUIFont(DefaultFontType type) +{ + LOGFONT lf{}; + NONCLIENTMETRICS ncm{}; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + if (::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0) != FALSE) + { + switch (type) + { + case DefaultFontType::menu: + { + lf = ncm.lfMenuFont; + break; + } + + case DefaultFontType::status: + { + lf = ncm.lfStatusFont; + break; + } + + case DefaultFontType::message: + { + lf = ncm.lfMessageFont; + break; + } + + case DefaultFontType::caption: + { + lf = ncm.lfCaptionFont; + break; + } + + case DefaultFontType::smcaption: + { + lf = ncm.lfSmCaptionFont; + break; + } + + // case DefaultFontType::none + default: + { + auto hf = static_cast(::GetStockObject(DEFAULT_GUI_FONT)); + ::GetObject(hf, sizeof(LOGFONT), &lf); + break; + } + } + } + else + { + auto hf = static_cast(::GetStockObject(DEFAULT_GUI_FONT)); + ::GetObject(hf, sizeof(LOGFONT), &lf); + } + return lf; +} + void NppParameters::getLangKeywordsFromXmlTree() { TiXmlNode *root = diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index 65bbcaeba..213b587e6 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -1526,6 +1526,8 @@ public: const std::vector& getFontList() const { return _fontlist; } HFONT getDefaultUIFont(); + enum class DefaultFontType { none, menu, status, message, caption, smcaption }; + static LOGFONT getDefaultGUIFont(DefaultFontType type = DefaultFontType::message); int getNbUserLang() const {return _nbUserLang;} UserLangContainer & getULCFromIndex(size_t i) {return *_userLangArray[i];}; diff --git a/PowerEditor/src/WinControls/TabBar/TabBar.cpp b/PowerEditor/src/WinControls/TabBar/TabBar.cpp index 8e3b0f71d..d369de6d7 100644 --- a/PowerEditor/src/WinControls/TabBar/TabBar.cpp +++ b/PowerEditor/src/WinControls/TabBar/TabBar.cpp @@ -79,19 +79,31 @@ void TabBar::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMultiLin void TabBar::destroy() { if (_hFont) - DeleteObject(_hFont); + { + ::DeleteObject(_hFont); + _hFont = nullptr; + } if (_hLargeFont) - DeleteObject(_hLargeFont); + { + ::DeleteObject(_hLargeFont); + _hLargeFont = nullptr; + } if (_hVerticalFont) - DeleteObject(_hVerticalFont); + { + ::DeleteObject(_hVerticalFont); + _hVerticalFont = nullptr; + } if (_hVerticalLargeFont) - DeleteObject(_hVerticalLargeFont); + { + ::DeleteObject(_hVerticalLargeFont); + _hVerticalLargeFont = nullptr; + } ::DestroyWindow(_hSelf); - _hSelf = NULL; + _hSelf = nullptr; } @@ -325,25 +337,21 @@ void TabBarPlus::init(HINSTANCE hInst, HWND parent, bool isVertical, bool isMult ::SetWindowLongPtr(_hSelf, GWLP_USERDATA, reinterpret_cast(this)); _tabBarDefaultProc = reinterpret_cast(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast(TabBarPlus_Proc))); - LOGFONT LogFont{}; + auto& dpiManager = NppParameters::getInstance()._dpiManager; - _hFont = (HFONT)::SendMessage(_hSelf, WM_GETFONT, 0, 0); + LOGFONT lf{ NppParameters::getDefaultGUIFont() }; + LOGFONT lfVer{ lf }; + _hFont = ::CreateFontIndirect(&lf); + lf.lfWeight = FW_HEAVY; + lf.lfHeight = -dpiManager.pointsToPixels(12); + _hLargeFont = ::CreateFontIndirect(&lf); - if (_hFont == NULL) - _hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); + lfVer.lfEscapement = 900; + lfVer.lfOrientation = 900; + _hVerticalFont = CreateFontIndirect(&lfVer); - if (_hLargeFont == NULL) - _hLargeFont = (HFONT)::GetStockObject(SYSTEM_FONT); - - if (::GetObject(_hFont, sizeof(LOGFONT), &LogFont) != 0) - { - LogFont.lfEscapement = 900; - LogFont.lfOrientation = 900; - _hVerticalFont = CreateFontIndirect(&LogFont); - - LogFont.lfWeight = 900; - _hVerticalLargeFont = CreateFontIndirect(&LogFont); - } + lfVer.lfWeight = FW_HEAVY; + _hVerticalLargeFont = CreateFontIndirect(&lfVer); } @@ -1336,10 +1344,21 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode) { // center text vertically Flags |= DT_LEFT; - Flags |= DT_VCENTER; + Flags |= isStandardSize || (!hasMultipleLines && !isDarkMode) ? DT_VCENTER : DT_TOP; // ignoring the descent when centering (text elements below the base line) is more pleasing to the eye - rect.top += textDescent / 2; + if (!isDarkMode && !isStandardSize) + { + rect.top = pDrawItemStruct->rcItem.top; + if (hasMultipleLines && isSelected) + { + rect.top -= _drawTopBar ? 0 : paddingDynamicTwoY; + } + } + else + { + rect.top += textDescent / 2; + } rect.bottom += textDescent / 2; // 1 space distance to save icon diff --git a/PowerEditor/src/WinControls/TabBar/TabBar.h b/PowerEditor/src/WinControls/TabBar/TabBar.h index 9e92dd008..8eaa247f9 100644 --- a/PowerEditor/src/WinControls/TabBar/TabBar.h +++ b/PowerEditor/src/WinControls/TabBar/TabBar.h @@ -46,10 +46,17 @@ const TCHAR TABBAR_ACTIVEUNFOCUSEDINDCATOR[64] = TEXT("Active tab unfocused indi const TCHAR TABBAR_ACTIVETEXT[64] = TEXT("Active tab text"); const TCHAR TABBAR_INACTIVETEXT[64] = TEXT("Inactive tabs"); +constexpr int g_TabIconSize = 13; +constexpr int g_TabIconSizeLarge = 20; +constexpr int g_TabHeight = 22; +constexpr int g_TabHeightLarge = 25; +constexpr int g_TabWidth = 45; +constexpr int g_TabWidthCloseBtn = 60; + struct TBHDR { - NMHDR _hdr; - int _tabOrigin; + NMHDR _hdr{}; + int _tabOrigin = 0; }; @@ -59,9 +66,9 @@ class TabBar : public Window public: TabBar() = default; virtual ~TabBar() = default; - virtual void destroy(); + void destroy() override; virtual void init(HINSTANCE hInst, HWND hwnd, bool isVertical = false, bool isMultiLine = false); - virtual void reSizeTo(RECT & rc2Ajust); + void reSizeTo(RECT& rc2Ajust) override; int insertAtEnd(const TCHAR *subTabName); void activateAt(int index) const; void getCurrentTitle(TCHAR *title, int titleLen); @@ -97,6 +104,9 @@ public: _isMultiLine = b; }; + HFONT& getFont(bool isReduced = true) { + return isReduced ? _hFont : _hLargeFont; + } protected: size_t _nbItem = 0; @@ -141,9 +151,9 @@ public : _doDragNDrop = justDoIt; }; - virtual void init(HINSTANCE hInst, HWND hwnd, bool isVertical = false, bool isMultiLine = false); + void init(HINSTANCE hInst, HWND hwnd, bool isVertical = false, bool isMultiLine = false) override; - virtual void destroy(); + void destroy() override; static bool doDragNDropOrNot() { return _doDragNDrop; @@ -221,10 +231,10 @@ protected: int _nSrcTab = -1; int _nTabDragged = -1; int _previousTabSwapped = -1; - POINT _draggingPoint = {}; // coordinate of Screen + POINT _draggingPoint{}; // coordinate of Screen WNDPROC _tabBarDefaultProc = nullptr; - RECT _currentHoverTabRect; + RECT _currentHoverTabRect{}; int _currentHoverTabItem = -1; // -1 : no mouse on any tab CloseButtonZone _closeButtonZone; @@ -270,7 +280,7 @@ protected: int32_t getTabIndexAt(int x, int y) { - TCHITTESTINFO hitInfo; + TCHITTESTINFO hitInfo{}; hitInfo.pt.x = x; hitInfo.pt.y = y; return static_cast(::SendMessage(_hSelf, TCM_HITTEST, 0, reinterpret_cast(&hitInfo))); @@ -278,7 +288,7 @@ protected: bool isPointInParentZone(POINT screenPoint) const { - RECT parentZone; + RECT parentZone{}; ::GetWindowRect(_hParent, &parentZone); return (((screenPoint.x >= parentZone.left) && (screenPoint.x <= parentZone.right)) && (screenPoint.y >= parentZone.top) && (screenPoint.y <= parentZone.bottom));