Fix toolbar pressed button visual glitch in dark mode

Use custom draw for main toolbar in dark mode.

Fix #15225, close #15226
This commit is contained in:
ozone10 2024-05-31 17:05:09 +02:00 committed by Don Ho
parent cfcb0d73cf
commit fedaabf0f8
4 changed files with 103 additions and 69 deletions

View File

@ -1949,7 +1949,7 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
bool copyLink = (_pEditView->getSelectedTextCount() == 0) && _pEditView->getIndicatorRange(URL_INDIC); bool copyLink = (_pEditView->getSelectedTextCount() == 0) && _pEditView->getIndicatorRange(URL_INDIC);
scintillaContextmenu.create(hwnd, tmp, _mainMenuHandle, copyLink); scintillaContextmenu.create(hwnd, tmp, _mainMenuHandle, copyLink);
POINT p; POINT p{};
p.x = GET_X_LPARAM(lParam); p.x = GET_X_LPARAM(lParam);
p.y = GET_Y_LPARAM(lParam); p.y = GET_Y_LPARAM(lParam);
if ((p.x == -1) && (p.y == -1)) if ((p.x == -1) && (p.y == -1))
@ -1971,23 +1971,87 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
case WM_NOTIFY: case WM_NOTIFY:
{ {
const NMHDR* nmhdr = reinterpret_cast<NMHDR*>(lParam); const auto lpnmhdr = reinterpret_cast<LPNMHDR>(lParam);
if (nmhdr->code == NM_CUSTOMDRAW && (nmhdr->hwndFrom == _toolBar.getHSelf())) if (lpnmhdr->hwndFrom == _toolBar.getHSelf())
{ {
NMTBCUSTOMDRAW* nmtbcd = reinterpret_cast<NMTBCUSTOMDRAW*>(lParam); switch (lpnmhdr->code)
if (nmtbcd->nmcd.dwDrawStage == CDDS_PREERASE)
{ {
if (NppDarkMode::isEnabled()) case NM_CUSTOMDRAW:
{
FillRect(nmtbcd->nmcd.hdc, &nmtbcd->nmcd.rc, NppDarkMode::getDarkerBackgroundBrush());
nmtbcd->clrText = NppDarkMode::getTextColor();
SetTextColor(nmtbcd->nmcd.hdc, NppDarkMode::getTextColor());
return CDRF_SKIPDEFAULT;
}
else
{ {
auto nmtbcd = reinterpret_cast<LPNMTBCUSTOMDRAW>(lParam);
static int roundCornerValue = 0;
switch (nmtbcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
{
LRESULT lr = CDRF_DODEFAULT;
if (NppDarkMode::isEnabled())
{
if (NppDarkMode::isWindows11())
{
roundCornerValue = 5;
}
::FillRect(nmtbcd->nmcd.hdc, &nmtbcd->nmcd.rc, NppDarkMode::getDarkerBackgroundBrush());
lr |= CDRF_NOTIFYITEMDRAW;
}
return lr;
}
case CDDS_ITEMPREPAINT:
{
nmtbcd->hbrMonoDither = NppDarkMode::getBackgroundBrush();
nmtbcd->hbrLines = NppDarkMode::getEdgeBrush();
nmtbcd->hpenLines = NppDarkMode::getEdgePen();
nmtbcd->clrText = NppDarkMode::getTextColor();
nmtbcd->clrTextHighlight = NppDarkMode::getTextColor();
nmtbcd->clrBtnFace = NppDarkMode::getBackgroundColor();
nmtbcd->clrBtnHighlight = NppDarkMode::getSofterBackgroundColor();
nmtbcd->clrHighlightHotTrack = NppDarkMode::getHotBackgroundColor();
nmtbcd->nStringBkMode = TRANSPARENT;
nmtbcd->nHLStringBkMode = TRANSPARENT;
if ((nmtbcd->nmcd.uItemState & CDIS_HOT) == CDIS_HOT)
{
auto holdBrush = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getHotBackgroundBrush());
auto holdPen = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getHotEdgePen());
::RoundRect(nmtbcd->nmcd.hdc, nmtbcd->nmcd.rc.left, nmtbcd->nmcd.rc.top, nmtbcd->nmcd.rc.right, nmtbcd->nmcd.rc.bottom, roundCornerValue, roundCornerValue);
::SelectObject(nmtbcd->nmcd.hdc, holdBrush);
::SelectObject(nmtbcd->nmcd.hdc, holdPen);
nmtbcd->nmcd.uItemState &= ~(CDIS_CHECKED | CDIS_HOT);
}
else if ((nmtbcd->nmcd.uItemState & CDIS_CHECKED) == CDIS_CHECKED)
{
auto holdBrush = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getSofterBackgroundBrush());
auto holdPen = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getEdgePen());
::RoundRect(nmtbcd->nmcd.hdc, nmtbcd->nmcd.rc.left, nmtbcd->nmcd.rc.top, nmtbcd->nmcd.rc.right, nmtbcd->nmcd.rc.bottom, roundCornerValue, roundCornerValue);
::SelectObject(nmtbcd->nmcd.hdc, holdBrush);
::SelectObject(nmtbcd->nmcd.hdc, holdPen);
nmtbcd->nmcd.uItemState &= ~CDIS_CHECKED;
}
LRESULT lr = TBCDRF_USECDCOLORS;
if ((nmtbcd->nmcd.uItemState & CDIS_SELECTED) == CDIS_SELECTED)
{
lr |= TBCDRF_NOBACKGROUND;
}
return lr;
}
default:
break;
}
return CDRF_DODEFAULT; return CDRF_DODEFAULT;
} }
default:
return FALSE;
} }
} }

View File

@ -2590,9 +2590,7 @@ namespace NppDarkMode
{ {
if (NppDarkMode::isWindows11()) if (NppDarkMode::isWindows11())
{ {
const auto nmhdr = reinterpret_cast<LPNMHDR>(lParam); roundCornerValue = 5;
const auto dpi = DPIManagerV2::getDpiForParent(nmhdr->hwndFrom);
roundCornerValue = DPIManagerV2::scale(5, dpi);
} }
::FillRect(nmtbcd->nmcd.hdc, &nmtbcd->nmcd.rc, NppDarkMode::getDarkerBackgroundBrush()); ::FillRect(nmtbcd->nmcd.hdc, &nmtbcd->nmcd.rc, NppDarkMode::getDarkerBackgroundBrush());
@ -2609,7 +2607,9 @@ namespace NppDarkMode
case CDDS_ITEMPREPAINT: case CDDS_ITEMPREPAINT:
{ {
nmtbcd->hbrMonoDither = NppDarkMode::getBackgroundBrush();
nmtbcd->hbrLines = NppDarkMode::getEdgeBrush(); nmtbcd->hbrLines = NppDarkMode::getEdgeBrush();
nmtbcd->hpenLines = NppDarkMode::getEdgePen();
nmtbcd->clrText = NppDarkMode::getTextColor(); nmtbcd->clrText = NppDarkMode::getTextColor();
nmtbcd->clrTextHighlight = NppDarkMode::getTextColor(); nmtbcd->clrTextHighlight = NppDarkMode::getTextColor();
nmtbcd->clrBtnFace = NppDarkMode::getBackgroundColor(); nmtbcd->clrBtnFace = NppDarkMode::getBackgroundColor();
@ -2618,7 +2618,17 @@ namespace NppDarkMode
nmtbcd->nStringBkMode = TRANSPARENT; nmtbcd->nStringBkMode = TRANSPARENT;
nmtbcd->nHLStringBkMode = TRANSPARENT; nmtbcd->nHLStringBkMode = TRANSPARENT;
if ((nmtbcd->nmcd.uItemState & CDIS_CHECKED) == CDIS_CHECKED) if ((nmtbcd->nmcd.uItemState & CDIS_HOT) == CDIS_HOT)
{
auto holdBrush = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getHotBackgroundBrush());
auto holdPen = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getHotEdgePen());
::RoundRect(nmtbcd->nmcd.hdc, nmtbcd->nmcd.rc.left, nmtbcd->nmcd.rc.top, nmtbcd->nmcd.rc.right, nmtbcd->nmcd.rc.bottom, roundCornerValue, roundCornerValue);
::SelectObject(nmtbcd->nmcd.hdc, holdBrush);
::SelectObject(nmtbcd->nmcd.hdc, holdPen);
nmtbcd->nmcd.uItemState &= ~(CDIS_CHECKED | CDIS_HOT);
}
else if ((nmtbcd->nmcd.uItemState & CDIS_CHECKED) == CDIS_CHECKED)
{ {
auto holdBrush = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getSofterBackgroundBrush()); auto holdBrush = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getSofterBackgroundBrush());
auto holdPen = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getEdgePen()); auto holdPen = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getEdgePen());
@ -2629,7 +2639,12 @@ namespace NppDarkMode
nmtbcd->nmcd.uItemState &= ~CDIS_CHECKED; nmtbcd->nmcd.uItemState &= ~CDIS_CHECKED;
} }
LRESULT lr = TBCDRF_HILITEHOTTRACK | TBCDRF_USECDCOLORS | CDRF_NOTIFYPOSTPAINT; LRESULT lr = TBCDRF_USECDCOLORS;
if ((nmtbcd->nmcd.uItemState & CDIS_SELECTED) == CDIS_SELECTED)
{
lr |= TBCDRF_NOBACKGROUND;
}
if (isPlugin) if (isPlugin)
{ {
lr |= ::DefSubclassProc(hWnd, uMsg, wParam, lParam); lr |= ::DefSubclassProc(hWnd, uMsg, wParam, lParam);
@ -2638,34 +2653,6 @@ namespace NppDarkMode
return lr; return lr;
} }
case CDDS_ITEMPOSTPAINT:
{
bool isDropDown = false;
auto exStyle = ::SendMessage(nmtbcd->nmcd.hdr.hwndFrom, TB_GETEXTENDEDSTYLE, 0, 0);
if ((exStyle & TBSTYLE_EX_DRAWDDARROWS) == TBSTYLE_EX_DRAWDDARROWS)
{
TBBUTTONINFO tbButtonInfo{};
tbButtonInfo.cbSize = sizeof(TBBUTTONINFO);
tbButtonInfo.dwMask = TBIF_STYLE;
::SendMessage(nmtbcd->nmcd.hdr.hwndFrom, TB_GETBUTTONINFO, nmtbcd->nmcd.dwItemSpec, reinterpret_cast<LPARAM>(&tbButtonInfo));
isDropDown = (tbButtonInfo.fsStyle & BTNS_DROPDOWN) == BTNS_DROPDOWN;
}
if ( !isDropDown && (nmtbcd->nmcd.uItemState & CDIS_HOT) == CDIS_HOT)
{
NppDarkMode::paintRoundFrameRect(nmtbcd->nmcd.hdc, nmtbcd->nmcd.rc, NppDarkMode::getHotEdgePen(), roundCornerValue, roundCornerValue);
}
if (isPlugin)
{
break;
}
return CDRF_DODEFAULT;
}
default: default:
break; break;
} }

View File

@ -22,7 +22,7 @@
#include "FindReplaceDlg_rc.h" #include "FindReplaceDlg_rc.h"
#include "NppDarkMode.h" #include "NppDarkMode.h"
const int WS_TOOLBARSTYLE = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS |TBSTYLE_FLAT | CCS_TOP | BTNS_AUTOSIZE | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_NODIVIDER; constexpr DWORD WS_TOOLBARSTYLE = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | CCS_TOP | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_NODIVIDER;
struct ToolbarIconIdUnit struct ToolbarIconIdUnit
{ {
@ -145,9 +145,10 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
_pTBB = new TBBUTTON[_nbTotalButtons]; //add one for the extra separator _pTBB = new TBBUTTON[_nbTotalButtons]; //add one for the extra separator
int cmd = 0; int cmd = 0;
int bmpIndex = -1, style; int bmpIndex = -1;
BYTE style = 0;
size_t i = 0; size_t i = 0;
for (; i < _nbButtons ; ++i) for (; i < _nbButtons && i < _nbTotalButtons; ++i)
{ {
cmd = buttonUnitArray[i]._cmdID; cmd = buttonUnitArray[i]._cmdID;
if (cmd != 0) if (cmd != 0)
@ -163,7 +164,7 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
_pTBB[i].iBitmap = (cmd != 0 ? bmpIndex : 0); _pTBB[i].iBitmap = (cmd != 0 ? bmpIndex : 0);
_pTBB[i].idCommand = cmd; _pTBB[i].idCommand = cmd;
_pTBB[i].fsState = TBSTATE_ENABLED; _pTBB[i].fsState = TBSTATE_ENABLED;
_pTBB[i].fsStyle = (BYTE)style; _pTBB[i].fsStyle = style;
_pTBB[i].dwData = 0; _pTBB[i].dwData = 0;
_pTBB[i].iString = 0; _pTBB[i].iString = 0;
} }
@ -317,7 +318,7 @@ void ToolBar::reset(bool create)
// Send the TB_BUTTONSTRUCTSIZE message, which is required for // Send the TB_BUTTONSTRUCTSIZE message, which is required for
// backward compatibility. // backward compatibility.
::SendMessage(_hSelf, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); ::SendMessage(_hSelf, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
::SendMessage(_hSelf, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS); ::SendMessage(_hSelf, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_HIDECLIPPEDBUTTONS | TBSTYLE_EX_DOUBLEBUFFER);
change2CustomIconsIfAny(); change2CustomIconsIfAny();
} }
@ -342,11 +343,6 @@ void ToolBar::reset(bool create)
{ {
setDefaultImageListDM(); setDefaultImageListDM();
setDisableImageListDM(); setDisableImageListDM();
if (NppDarkMode::isWindows11())
{
setHoveredImageListDM();
}
} }
else else
{ {
@ -360,11 +356,6 @@ void ToolBar::reset(bool create)
{ {
setDefaultImageListDM2(); setDefaultImageListDM2();
setDisableImageListDM2(); setDisableImageListDM2();
if (NppDarkMode::isWindows11())
{
setHoveredImageListDM2();
}
} }
else else
{ {

View File

@ -152,14 +152,6 @@ private :
void setDisableImageListDM2() { void setDisableImageListDM2() {
::SendMessage(_hSelf, TB_SETDISABLEDIMAGELIST, 0, reinterpret_cast<LPARAM>(_toolBarIcons.getDisableLstSetDM2())); ::SendMessage(_hSelf, TB_SETDISABLEDIMAGELIST, 0, reinterpret_cast<LPARAM>(_toolBarIcons.getDisableLstSetDM2()));
}; };
void setHoveredImageListDM() {
::SendMessage(_hSelf, TB_SETHOTIMAGELIST, 0, reinterpret_cast<LPARAM>(_toolBarIcons.getDefaultLst()));
};
void setHoveredImageListDM2() {
::SendMessage(_hSelf, TB_SETHOTIMAGELIST, 0, reinterpret_cast<LPARAM>(_toolBarIcons.getDefaultLstSet2()));
};
void reset(bool create = false); void reset(bool create = false);
void setState(toolBarStatusType state) { void setState(toolBarStatusType state) {