Skip to content

Commit

Permalink
Add "Show All Character" context menu on toolbar button
Browse files Browse the repository at this point in the history
  • Loading branch information
ozone10 authored and donho committed Jun 6, 2024
1 parent 7a401cf commit e7e88a3
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 14 deletions.
114 changes: 113 additions & 1 deletion PowerEditor/src/Notepad_plus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,21 @@ ToolBarButtonUnit toolBarIcons[] = {
{IDM_VIEW_WRAP, IDI_VIEW_WRAP_ICON, IDI_VIEW_WRAP_ICON, IDI_VIEW_WRAP_ICON2, IDI_VIEW_WRAP_ICON2, IDI_VIEW_WRAP_ICON_DM, IDI_VIEW_WRAP_ICON_DM, IDI_VIEW_WRAP_ICON_DM2, IDI_VIEW_WRAP_ICON_DM2, IDR_WRAP},
{IDM_VIEW_ALL_CHARACTERS, IDI_VIEW_ALL_CHAR_ICON, IDI_VIEW_ALL_CHAR_ICON, IDI_VIEW_ALL_CHAR_ICON2, IDI_VIEW_ALL_CHAR_ICON2, IDI_VIEW_ALL_CHAR_ICON_DM, IDI_VIEW_ALL_CHAR_ICON_DM, IDI_VIEW_ALL_CHAR_ICON_DM2, IDI_VIEW_ALL_CHAR_ICON_DM2, IDR_INVISIBLECHAR},
{IDM_VIEW_INDENT_GUIDE, IDI_VIEW_INDENT_ICON, IDI_VIEW_INDENT_ICON, IDI_VIEW_INDENT_ICON2, IDI_VIEW_INDENT_ICON2, IDI_VIEW_INDENT_ICON_DM, IDI_VIEW_INDENT_ICON_DM, IDI_VIEW_INDENT_ICON_DM2, IDI_VIEW_INDENT_ICON_DM2, IDR_INDENTGUIDE},

//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//
{0, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON},
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

{IDM_LANG_USER_DLG, IDI_VIEW_UD_DLG_ICON, IDI_VIEW_UD_DLG_ICON, IDI_VIEW_UD_DLG_ICON2, IDI_VIEW_UD_DLG_ICON2, IDI_VIEW_UD_DLG_ICON_DM, IDI_VIEW_UD_DLG_ICON_DM, IDI_VIEW_UD_DLG_ICON_DM2, IDI_VIEW_UD_DLG_ICON_DM2, IDR_SHOWPANNEL},
{IDM_VIEW_DOC_MAP, IDI_VIEW_DOC_MAP_ICON, IDI_VIEW_DOC_MAP_ICON, IDI_VIEW_DOC_MAP_ICON2, IDI_VIEW_DOC_MAP_ICON2, IDI_VIEW_DOC_MAP_ICON_DM, IDI_VIEW_DOC_MAP_ICON_DM, IDI_VIEW_DOC_MAP_ICON_DM2, IDI_VIEW_DOC_MAP_ICON_DM2, IDR_DOCMAP},
{IDM_VIEW_DOCLIST, IDI_VIEW_DOCLIST_ICON, IDI_VIEW_DOCLIST_ICON, IDI_VIEW_DOCLIST_ICON2, IDI_VIEW_DOCLIST_ICON2, IDI_VIEW_DOCLIST_ICON_DM, IDI_VIEW_DOCLIST_ICON_DM, IDI_VIEW_DOCLIST_ICON_DM2, IDI_VIEW_DOCLIST_ICON_DM2, IDR_DOCLIST},
{IDM_VIEW_FUNC_LIST, IDI_VIEW_FUNCLIST_ICON, IDI_VIEW_FUNCLIST_ICON, IDI_VIEW_FUNCLIST_ICON2, IDI_VIEW_FUNCLIST_ICON2, IDI_VIEW_FUNCLIST_ICON_DM, IDI_VIEW_FUNCLIST_ICON_DM, IDI_VIEW_FUNCLIST_ICON_DM2, IDI_VIEW_FUNCLIST_ICON_DM2, IDR_FUNC_LIST},
{IDM_VIEW_FILEBROWSER, IDI_VIEW_FILEBROWSER_ICON, IDI_VIEW_FILEBROWSER_ICON, IDI_VIEW_FILEBROWSER_ICON2, IDI_VIEW_FILEBROWSER_ICON2, IDI_VIEW_FILEBROWSER_ICON_DM, IDI_VIEW_FILEBROWSER_ICON_DM, IDI_VIEW_FILEBROWSER_ICON_DM2, IDI_VIEW_FILEBROWSER_ICON_DM2, IDR_FILEBROWSER},

//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//
{0, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON, IDI_SEPARATOR_ICON},
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

{IDM_VIEW_MONITORING, IDI_VIEW_MONITORING_ICON, IDI_VIEW_MONITORING_DIS_ICON, IDI_VIEW_MONITORING_ICON2, IDI_VIEW_MONITORING_DIS_ICON2, IDI_VIEW_MONITORING_ICON_DM, IDI_VIEW_MONITORING_DIS_ICON_DM, IDI_VIEW_MONITORING_ICON_DM2, IDI_VIEW_MONITORING_DIS_ICON_DM2, IDR_FILEMONITORING},

//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//
Expand Down Expand Up @@ -8964,4 +8974,106 @@ void Notepad_plus::changedHistoryGoTo(int idGoTo)
if (!isSilent)
::MessageBeep(MB_ICONEXCLAMATION);
}
}
}

HMENU Notepad_plus::createMenuFromMenu(HMENU hSourceMenu, std::vector<int>& commandIds)
{
HMENU hNewMenu = ::CreatePopupMenu();
for (const auto& cmdID : commandIds)
{
if (cmdID == 0)
{
::AppendMenu(hNewMenu, MF_SEPARATOR, 0, nullptr);
}
else
{
MENUITEMINFO mii{};
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STRING | MIIM_STATE;
mii.dwTypeData = nullptr;

if (::GetMenuItemInfo(hSourceMenu, cmdID, FALSE, &mii) == TRUE)
{
++mii.cch;
wchar_t* szString = new wchar_t[mii.cch];
mii.dwTypeData = szString;

if (::GetMenuItemInfo(hSourceMenu, cmdID, FALSE, &mii) == TRUE)
{
::AppendMenu(hNewMenu, MF_STRING | mii.fState, cmdID, mii.dwTypeData);
delete[] szString;
}
else
{
delete[] szString;
::DestroyMenu(hNewMenu);
return nullptr;
}
}
else
{
::DestroyMenu(hNewMenu);
return nullptr;
}
}
}
return hNewMenu;
}

BOOL Notepad_plus::notifyTBShowMenu(LPNMTOOLBARW lpnmtb, const char* menuPosId)
{
RECT rcItem{};
::SendMessage(lpnmtb->hdr.hwndFrom, TB_GETRECT, static_cast<WPARAM>(lpnmtb->iItem), reinterpret_cast<LPARAM>(&rcItem));
::MapWindowPoints(lpnmtb->hdr.hwndFrom, HWND_DESKTOP, reinterpret_cast<LPPOINT>(&rcItem), 2);

const MenuPosition& menuPos = getMenuPosition(menuPosId);
HMENU hSubMenuView = ::GetSubMenu(_mainMenuHandle, menuPos._x);
if (hSubMenuView != nullptr)
{
HMENU hPopupMenu = ::GetSubMenu(hSubMenuView, menuPos._y);
if (hPopupMenu != nullptr)
{
TPMPARAMS tpm{};
tpm.cbSize = sizeof(TPMPARAMS);
tpm.rcExclude = rcItem;

const UINT flags = _nativeLangSpeaker.isRTL() ? (TPM_RIGHTALIGN | TPM_RIGHTBUTTON | TPM_LAYOUTRTL) : (TPM_LEFTALIGN | TPM_LEFTBUTTON);

::TrackPopupMenuEx(hPopupMenu,
flags | TPM_VERTICAL,
rcItem.left, rcItem.bottom, _pPublicInterface->getHSelf(), &tpm);

return TRUE;
}
}
return FALSE;
}

BOOL Notepad_plus::notifyTBShowMenu(LPNMTOOLBARW lpnmtb, const char* menuPosId, std::vector<int> cmdIDs)
{
if (cmdIDs.empty())
return notifyTBShowMenu(lpnmtb, menuPosId);

RECT rcItem{};
::SendMessage(lpnmtb->hdr.hwndFrom, TB_GETRECT, static_cast<WPARAM>(lpnmtb->iItem), reinterpret_cast<LPARAM>(&rcItem));
::MapWindowPoints(lpnmtb->hdr.hwndFrom, HWND_DESKTOP, reinterpret_cast<LPPOINT>(&rcItem), 2);

HMENU hPopupMenu = createMenuFromMenu(_mainMenuHandle, cmdIDs);
if (hPopupMenu != nullptr)
{
TPMPARAMS tpm{};
tpm.cbSize = sizeof(TPMPARAMS);
tpm.rcExclude = rcItem;

const UINT flags = _nativeLangSpeaker.isRTL() ? (TPM_RIGHTALIGN | TPM_RIGHTBUTTON | TPM_LAYOUTRTL) : (TPM_LEFTALIGN | TPM_LEFTBUTTON);

::TrackPopupMenuEx(hPopupMenu,
flags | TPM_VERTICAL,
rcItem.left, rcItem.bottom, _pPublicInterface->getHSelf(), &tpm);

::DestroyMenu(hPopupMenu);

return TRUE;
}
return FALSE;
}
4 changes: 4 additions & 0 deletions PowerEditor/src/Notepad_plus.h
Original file line number Diff line number Diff line change
Expand Up @@ -653,4 +653,8 @@ friend class FileManager;

void clearChangesHistory();
void changedHistoryGoTo(int idGoTo);

HMENU createMenuFromMenu(HMENU hSourceMenu, std::vector<int>& commandIds);
BOOL notifyTBShowMenu(LPNMTOOLBARW lpnmtb, const char* menuPosId);
BOOL notifyTBShowMenu(LPNMTOOLBARW lpnmtb, const char* menuPosId, std::vector<int> cmdIDs);
};
101 changes: 98 additions & 3 deletions PowerEditor/src/NppBigSwitch.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This file is part of Notepad++ project
// This file is part of Notepad++ project
// Copyright (C)2021 Don HO <[email protected]>

// This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -2013,11 +2013,34 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
nmtbcd->nStringBkMode = TRANSPARENT;
nmtbcd->nHLStringBkMode = TRANSPARENT;

RECT rcItem{ nmtbcd->nmcd.rc };
RECT rcDrop{};

TBBUTTONINFO tbi{};
tbi.cbSize = sizeof(TBBUTTONINFO);
tbi.dwMask = TBIF_STYLE;
::SendMessage(lpnmhdr->hwndFrom, TB_GETBUTTONINFO, nmtbcd->nmcd.dwItemSpec, reinterpret_cast<LPARAM>(&tbi));
const bool isDropDown = (tbi.fsStyle & BTNS_DROPDOWN) == BTNS_DROPDOWN;
if (isDropDown)
{
WPARAM idx = ::SendMessage(lpnmhdr->hwndFrom, TB_COMMANDTOINDEX, nmtbcd->nmcd.dwItemSpec, 0);
::SendMessage(lpnmhdr->hwndFrom, TB_GETITEMDROPDOWNRECT, idx, reinterpret_cast<LPARAM>(&rcDrop));

rcItem.right = rcDrop.left;
}

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);

::RoundRect(nmtbcd->nmcd.hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom, roundCornerValue, roundCornerValue);

if (isDropDown)
{
::RoundRect(nmtbcd->nmcd.hdc, rcDrop.left, rcDrop.top, rcDrop.right, rcDrop.bottom, roundCornerValue, roundCornerValue);
}

::SelectObject(nmtbcd->nmcd.hdc, holdBrush);
::SelectObject(nmtbcd->nmcd.hdc, holdPen);

Expand All @@ -2027,7 +2050,14 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
{
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);

::RoundRect(nmtbcd->nmcd.hdc, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom, roundCornerValue, roundCornerValue);

if (isDropDown)
{
::RoundRect(nmtbcd->nmcd.hdc, rcDrop.left, rcDrop.top, rcDrop.right, rcDrop.bottom, roundCornerValue, roundCornerValue);
}

::SelectObject(nmtbcd->nmcd.hdc, holdBrush);
::SelectObject(nmtbcd->nmcd.hdc, holdPen);

Expand All @@ -2040,16 +2070,81 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
lr |= TBCDRF_NOBACKGROUND;
}

if (isDropDown)
{
lr |= CDRF_NOTIFYPOSTPAINT;
}

return lr;
}

case CDDS_ITEMPOSTPAINT:
{

const UINT dpi = DPIManagerV2::getDpiForWindow(hwnd);
LOGFONT lf{ DPIManagerV2::getDefaultGUIFontForDpi(dpi) };
HFONT hFont = CreateFontIndirect(&lf);
auto holdFont = static_cast<HFONT>(::SelectObject(nmtbcd->nmcd.hdc, hFont));

RECT rcArrow{};
WPARAM idx = ::SendMessage(lpnmhdr->hwndFrom, TB_COMMANDTOINDEX, nmtbcd->nmcd.dwItemSpec, 0);
::SendMessage(lpnmhdr->hwndFrom, TB_GETITEMDROPDOWNRECT, idx, reinterpret_cast<LPARAM>(&rcArrow));
rcArrow.left += DPIManagerV2::scale(1, dpi);
rcArrow.bottom -= DPIManagerV2::scale(3, dpi);

COLORREF clrArrow = NppDarkMode::getTextColor();

::SetBkMode(nmtbcd->nmcd.hdc, TRANSPARENT);
::SetTextColor(nmtbcd->nmcd.hdc, clrArrow);
::DrawText(nmtbcd->nmcd.hdc, L"", -1, &rcArrow, DT_NOPREFIX | DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOCLIP);
::SelectObject(nmtbcd->nmcd.hdc, holdFont);
::DeleteObject(hFont);

return CDRF_DODEFAULT;
}


default:
break;
}

return CDRF_DODEFAULT;
}

case TBN_DROPDOWN:
{
auto lpnmtb = reinterpret_cast<LPNMTOOLBARW>(lParam);
switch (lpnmtb->iItem)
{
case IDM_VIEW_ALL_CHARACTERS:
{
auto cmdIDs = { IDM_VIEW_TAB_SPACE, IDM_VIEW_EOL, IDM_VIEW_NPC, IDM_VIEW_NPC_CCUNIEOL, 0, IDM_VIEW_ALL_CHARACTERS };
notifyTBShowMenu(lpnmtb, "view-showSymbol", cmdIDs);
return TBDDRET_DEFAULT;
}

default:
break;
}
return TBDDRET_NODEFAULT;
}

case NM_RCLICK:
{
auto lpnmtb = reinterpret_cast<LPNMTOOLBARW>(lParam);
switch (lpnmtb->iItem)
{
case IDM_VIEW_ALL_CHARACTERS:
{
return notifyTBShowMenu(lpnmtb, "view-showSymbol");
}

default:
break;
}
return FALSE;
}

default:
return FALSE;
}
Expand Down
33 changes: 23 additions & 10 deletions PowerEditor/src/WinControls/ToolBar/ToolBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,27 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
for (; i < _nbButtons && i < _nbTotalButtons; ++i)
{
cmd = buttonUnitArray[i]._cmdID;
if (cmd != 0)
switch (cmd)
{
++bmpIndex;
style = BTNS_BUTTON;
}
else
{
style = BTNS_SEP;
case 0:
{
style = BTNS_SEP;
break;
}

case IDM_VIEW_ALL_CHARACTERS:
{
++bmpIndex;
style = BTNS_DROPDOWN;
break;
}

default:
{
++bmpIndex;
style = BTNS_BUTTON;
break;
}
}

_pTBB[i].iBitmap = (cmd != 0 ? bmpIndex : 0);
Expand All @@ -169,7 +182,7 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
_pTBB[i].iString = 0;
}

if (_nbDynButtons > 0)
if (_nbDynButtons > 0 && i < _nbTotalButtons)
{
//add separator
_pTBB[i].iBitmap = 0;
Expand All @@ -181,7 +194,7 @@ bool ToolBar::init( HINSTANCE hInst, HWND hPere, toolBarStatusType type, ToolBar
++i;

//add plugin buttons
for (size_t j = 0; j < _nbDynButtons ; ++j, ++i)
for (size_t j = 0; j < _nbDynButtons && i < _nbTotalButtons; ++j, ++i)
{
cmd = _vDynBtnReg[j]._message;
++bmpIndex;
Expand Down Expand Up @@ -318,7 +331,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 | TBSTYLE_EX_DOUBLEBUFFER);
::SendMessage(_hSelf, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS | TBSTYLE_EX_HIDECLIPPEDBUTTONS | TBSTYLE_EX_DOUBLEBUFFER);

change2CustomIconsIfAny();
}
Expand Down

0 comments on commit e7e88a3

Please sign in to comment.