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
pull/13710/head
ozone10 2023-05-24 21:22:38 +02:00 committed by Don Ho
parent 1806b8994b
commit b88456764b
6 changed files with 143 additions and 56 deletions

View File

@ -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<HFONT>(::GetStockObject(DEFAULT_GUI_FONT));
if (hf)
{
::SendMessage(_mainDocTab.getHSelf(), WM_SETFONT, reinterpret_cast<WPARAM>(hf), MAKELPARAM(TRUE, 0));
::SendMessage(_subDocTab.getHSelf(), WM_SETFONT, reinterpret_cast<WPARAM>(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<WPARAM>(hf), MAKELPARAM(TRUE, 0));
::SendMessage(_subDocTab.getHSelf(), WM_SETFONT, reinterpret_cast<WPARAM>(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();

View File

@ -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<WPARAM>(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);

View File

@ -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<HFONT>(::GetStockObject(DEFAULT_GUI_FONT));
::GetObject(hf, sizeof(LOGFONT), &lf);
break;
}
}
}
else
{
auto hf = static_cast<HFONT>(::GetStockObject(DEFAULT_GUI_FONT));
::GetObject(hf, sizeof(LOGFONT), &lf);
}
return lf;
}
void NppParameters::getLangKeywordsFromXmlTree()
{
TiXmlNode *root =

View File

@ -1526,6 +1526,8 @@ public:
const std::vector<generic_string>& 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];};

View File

@ -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<LONG_PTR>(this));
_tabBarDefaultProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(_hSelf, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(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

View File

@ -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<int32_t>(::SendMessage(_hSelf, TCM_HITTEST, 0, reinterpret_cast<LPARAM>(&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));