Fix toolbar pressed button visual glitch in dark mode

Use custom draw for main toolbar in dark mode.

Fix #15225, close #15226
pull/15230/head
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);
scintillaContextmenu.create(hwnd, tmp, _mainMenuHandle, copyLink);
POINT p;
POINT p{};
p.x = GET_X_LPARAM(lParam);
p.y = GET_Y_LPARAM(lParam);
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:
{
const NMHDR* nmhdr = reinterpret_cast<NMHDR*>(lParam);
if (nmhdr->code == NM_CUSTOMDRAW && (nmhdr->hwndFrom == _toolBar.getHSelf()))
const auto lpnmhdr = reinterpret_cast<LPNMHDR>(lParam);
if (lpnmhdr->hwndFrom == _toolBar.getHSelf())
{
NMTBCUSTOMDRAW* nmtbcd = reinterpret_cast<NMTBCUSTOMDRAW*>(lParam);
if (nmtbcd->nmcd.dwDrawStage == CDDS_PREERASE)
switch (lpnmhdr->code)
{
case NM_CUSTOMDRAW:
{
auto nmtbcd = reinterpret_cast<LPNMTBCUSTOMDRAW>(lParam);
static int roundCornerValue = 0;
switch (nmtbcd->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
{
LRESULT lr = CDRF_DODEFAULT;
if (NppDarkMode::isEnabled())
{
FillRect(nmtbcd->nmcd.hdc, &nmtbcd->nmcd.rc, NppDarkMode::getDarkerBackgroundBrush());
nmtbcd->clrText = NppDarkMode::getTextColor();
SetTextColor(nmtbcd->nmcd.hdc, NppDarkMode::getTextColor());
return CDRF_SKIPDEFAULT;
}
else
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;
}
default:
return FALSE;
}
}

View File

@ -2590,9 +2590,7 @@ namespace NppDarkMode
{
if (NppDarkMode::isWindows11())
{
const auto nmhdr = reinterpret_cast<LPNMHDR>(lParam);
const auto dpi = DPIManagerV2::getDpiForParent(nmhdr->hwndFrom);
roundCornerValue = DPIManagerV2::scale(5, dpi);
roundCornerValue = 5;
}
::FillRect(nmtbcd->nmcd.hdc, &nmtbcd->nmcd.rc, NppDarkMode::getDarkerBackgroundBrush());
@ -2609,7 +2607,9 @@ namespace NppDarkMode
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();
@ -2618,7 +2618,17 @@ namespace NppDarkMode
nmtbcd->nStringBkMode = 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 holdPen = ::SelectObject(nmtbcd->nmcd.hdc, NppDarkMode::getEdgePen());
@ -2629,7 +2639,12 @@ namespace NppDarkMode
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)
{
lr |= ::DefSubclassProc(hWnd, uMsg, wParam, lParam);
@ -2638,34 +2653,6 @@ namespace NppDarkMode
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:
break;
}

View File

@ -22,7 +22,7 @@
#include "FindReplaceDlg_rc.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
{
@ -145,9 +145,10 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
_pTBB = new TBBUTTON[_nbTotalButtons]; //add one for the extra separator
int cmd = 0;
int bmpIndex = -1, style;
int bmpIndex = -1;
BYTE style = 0;
size_t i = 0;
for (; i < _nbButtons ; ++i)
for (; i < _nbButtons && i < _nbTotalButtons; ++i)
{
cmd = buttonUnitArray[i]._cmdID;
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].idCommand = cmd;
_pTBB[i].fsState = TBSTATE_ENABLED;
_pTBB[i].fsStyle = (BYTE)style;
_pTBB[i].fsStyle = style;
_pTBB[i].dwData = 0;
_pTBB[i].iString = 0;
}
@ -317,7 +318,7 @@ void ToolBar::reset(bool create)
// Send the TB_BUTTONSTRUCTSIZE message, which is required for
// backward compatibility.
::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();
}
@ -342,11 +343,6 @@ void ToolBar::reset(bool create)
{
setDefaultImageListDM();
setDisableImageListDM();
if (NppDarkMode::isWindows11())
{
setHoveredImageListDM();
}
}
else
{
@ -360,11 +356,6 @@ void ToolBar::reset(bool create)
{
setDefaultImageListDM2();
setDisableImageListDM2();
if (NppDarkMode::isWindows11())
{
setHoveredImageListDM2();
}
}
else
{

View File

@ -153,14 +153,6 @@ private :
::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 setState(toolBarStatusType state) {
_state = state;