Add plus and arrow (drop down list of opened files) buttons on menu bar

1. Add plus and arrow buttons on menu bar beside of 'X' button:
   - plus button: for adding a new document
   - arrow button: display a drop down list for all opened files to offer users quick access of switching file
2. Enhance the most recent opened file list: Increase maximun file number to 30.

Fix #11229, close #11757
pull/11769/head
ozone10 2022-06-01 23:50:40 +02:00 committed by Don Ho
parent 33ab652395
commit 2c0134ef5a
8 changed files with 123 additions and 49 deletions

View File

@ -558,24 +558,34 @@ generic_string uintToString(unsigned int val)
}
// Build Recent File menu entries from given
generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generic_string &filename)
generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generic_string &filename, bool ordinalNumber)
{
generic_string strTemp;
if (pos < 9)
if (ordinalNumber)
{
strTemp.push_back('&');
strTemp.push_back('1' + static_cast<TCHAR>(pos));
}
else if (pos == 9)
{
strTemp.append(TEXT("1&0"));
if (pos < 9)
{
strTemp.push_back('&');
strTemp.push_back('1' + static_cast<TCHAR>(pos));
}
else if (pos == 9)
{
strTemp.append(TEXT("1&0"));
}
else
{
div_t splitDigits = div(pos + 1, 10);
strTemp.append(uintToString(splitDigits.quot));
strTemp.push_back('&');
strTemp.append(uintToString(splitDigits.rem));
}
strTemp.append(TEXT(": "));
}
else
{
strTemp.append(uintToString(pos + 1));
strTemp.push_back('&');
}
strTemp.append(TEXT(": "));
if (filenameLen > 0)
{

View File

@ -78,7 +78,7 @@ void ScreenRectToClientRect(HWND hWnd, RECT* rect);
std::wstring string2wstring(const std::string & rString, UINT codepage);
std::string wstring2string(const std::wstring & rwString, UINT codepage);
bool isInList(const TCHAR *token, const TCHAR *list);
generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generic_string &filename);
generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generic_string &filename, bool ordinalNumber = true);
std::string getFileContent(const TCHAR *file2read);
generic_string relativeFilePathToFullFilePath(const TCHAR *relativeFilePath);

View File

@ -15,6 +15,12 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// don't use resource editor it will corrupt this file,
// it will default to default ANSI code page (e.g. #pragma code_page(1252)),
// this will ignore line with #pragma code_page(65001) below,
// and change non ANSI symbol to ?
#pragma code_page(65001)
#include <windows.h>
#include "resource.h"
#include "menuCmdID.h"
@ -387,7 +393,7 @@ BEGIN
BEGIN
MENUITEM "Explorer", IDM_FILE_OPEN_FOLDER
MENUITEM "cmd", IDM_FILE_OPEN_CMD
MENUITEM SEPARATOR
MENUITEM SEPARATOR
MENUITEM "Folder as Workspace", IDM_FILE_CONTAININGFOLDERASWORKSPACE
END
MENUITEM "Open in &Default Viewer", IDM_FILE_OPEN_DEFAULT_VIEWER
@ -1165,29 +1171,29 @@ BEGIN
BEGIN
MENUITEM "&Run...", IDM_EXECUTE
END
POPUP "&Plugins"
BEGIN
MENUITEM "Open Plugins Folder...", IDM_SETTING_OPENPLUGINSDIR
END
POPUP "&Window"
BEGIN
POPUP "Sort By"
BEGIN
MENUITEM "Name A to Z", IDM_WINDOW_SORT_FN_ASC
MENUITEM "Name Z to A", IDM_WINDOW_SORT_FN_DSC
MENUITEM "Path A to Z", IDM_WINDOW_SORT_FP_ASC
MENUITEM "Path Z to A", IDM_WINDOW_SORT_FP_DSC
MENUITEM "Type A to Z", IDM_WINDOW_SORT_FT_ASC
MENUITEM "Type Z to A", IDM_WINDOW_SORT_FT_DSC
MENUITEM "Size Smaller to Larger", IDM_WINDOW_SORT_FS_ASC
MENUITEM "Size Larger to Smaller", IDM_WINDOW_SORT_FS_DSC
END
MENUITEM SEPARATOR
MENUITEM "Recent Window", IDM_WINDOW_MRU_FIRST, GRAYED
MENUITEM "&Windows...", IDM_WINDOW_WINDOWS
END
BEGIN
POPUP "Sort By"
BEGIN
MENUITEM "Name A to Z", IDM_WINDOW_SORT_FN_ASC
MENUITEM "Name Z to A", IDM_WINDOW_SORT_FN_DSC
MENUITEM "Path A to Z", IDM_WINDOW_SORT_FP_ASC
MENUITEM "Path Z to A", IDM_WINDOW_SORT_FP_DSC
MENUITEM "Type A to Z", IDM_WINDOW_SORT_FT_ASC
MENUITEM "Type Z to A", IDM_WINDOW_SORT_FT_DSC
MENUITEM "Size Smaller to Larger", IDM_WINDOW_SORT_FS_ASC
MENUITEM "Size Larger to Smaller", IDM_WINDOW_SORT_FS_DSC
END
MENUITEM "&Windows...", IDM_WINDOW_WINDOWS
MENUITEM SEPARATOR
MENUITEM "Recent Window", IDM_WINDOW_MRU_FIRST, GRAYED
END
POPUP "&?"
BEGIN
@ -1205,7 +1211,12 @@ BEGIN
MENUITEM "About Notepad++", IDM_ABOUT
END
MENUITEM "X", IDM_FILE_CLOSE, HELP
MENUITEM "", IDM_FILE_NEW, HELP
POPUP "▼"
BEGIN
MENUITEM "Recent Window", IDM_DROPLIST_LIST, GRAYED
END
MENUITEM "✕", IDM_FILE_CLOSE, HELP
END
IDR_SYSTRAYPOPUP_MENU MENU

View File

@ -3843,7 +3843,11 @@ void Notepad_plus::command(int id)
*/
else if ((id >= IDM_WINDOW_MRU_FIRST) && (id <= IDM_WINDOW_MRU_LIMIT))
{
activateDoc(id-IDM_WINDOW_MRU_FIRST);
activateDoc(id - IDM_WINDOW_MRU_FIRST);
}
else if ((id >= IDM_DROPLIST_MRU_FIRST) && (id < (IDM_DROPLIST_MRU_FIRST + static_cast<int32_t>(_pDocTab->nbItem()))))
{
activateDoc(id - IDM_DROPLIST_MRU_FIRST);
}
}

View File

@ -1121,47 +1121,89 @@ LRESULT CALLBACK WindowsDlg::listViewProc(HWND hwnd, UINT Message, WPARAM wParam
void WindowsMenu::init(HMENU hMainMenu)
{
_hMenu = ::GetSubMenu(hMainMenu, MENUINDEX_WINDOW);
_hMenuList = ::GetSubMenu(hMainMenu, MENUINDEX_LIST);
}
void WindowsMenu::initPopupMenu(HMENU hMenu, DocTabView *pTab)
void WindowsMenu::initPopupMenu(HMENU hMenu, DocTabView* pTab)
{
bool isDropListMenu = false;
UINT firstId = 0;
UINT limitId = 0;
UINT menuPosId = 0;
if (hMenu == _hMenu)
{
firstId = IDM_WINDOW_MRU_FIRST;
limitId = IDM_WINDOW_MRU_LIMIT;
menuPosId = IDM_WINDOW_WINDOWS;
}
else if (hMenu == _hMenuList)
{
isDropListMenu = true;
if (_limitPrev < pTab->nbItem())
{
_limitPrev = static_cast<UINT>(pTab->nbItem());
}
firstId = IDM_DROPLIST_MRU_FIRST;
limitId = IDM_DROPLIST_MRU_FIRST + _limitPrev - 1;
menuPosId = IDM_DROPLIST_LIST;
}
if (firstId > 0 && limitId > 0 && menuPosId > 0)
{
auto curDoc = pTab->getCurrentTabIndex();
size_t nMaxDoc = IDM_WINDOW_MRU_LIMIT - IDM_WINDOW_MRU_FIRST + 1;
size_t nMaxDoc = limitId - firstId + 1;
size_t nDoc = pTab->nbItem();
nDoc = min(nDoc, nMaxDoc);
int id;
size_t pos;
for (id = IDM_WINDOW_MRU_FIRST, pos = 0; id < IDM_WINDOW_MRU_FIRST + static_cast<int32_t>(nDoc); ++id, ++pos)
UINT id = firstId;
UINT guard = firstId + static_cast<int32_t>(nDoc);
size_t pos = 0;
for (id, pos; id < guard; ++id, ++pos)
{
BufferID bufID = pTab->getBufferByIndex(pos);
Buffer * buf = MainFileManager.getBufferByID(bufID);
Buffer* buf = MainFileManager.getBufferByID(bufID);
MENUITEMINFO mii;
memset(&mii, 0, sizeof(mii));
MENUITEMINFO mii{};
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING|MIIM_STATE|MIIM_ID;
generic_string strBuffer(BuildMenuFileName(60, static_cast<int32_t>(pos), buf->getFileName()));
// Can't make mii.dwTypeData = strBuffer.c_str() because of const cast.
// So, making temporary buffer for this.
mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID;
generic_string strBuffer(BuildMenuFileName(60, static_cast<int32_t>(pos), buf->getFileName(), !isDropListMenu));
std::vector<TCHAR> vBuffer(strBuffer.begin(), strBuffer.end());
vBuffer.push_back('\0');
mii.dwTypeData = (&vBuffer[0]);
mii.fState &= ~(MF_GRAYED|MF_DISABLED|MF_CHECKED);
if (int(pos) == curDoc)
mii.fState &= ~(MF_GRAYED | MF_DISABLED | MF_CHECKED);
if (static_cast<int32_t>(pos) == curDoc)
{
mii.fState |= MF_CHECKED;
}
mii.wID = id;
UINT state = GetMenuState(hMenu, id, MF_BYCOMMAND);
if (state == ((UINT)-1))
InsertMenuItem(hMenu, IDM_WINDOW_WINDOWS, FALSE, &mii);
if (state == static_cast<UINT>(-1))
{
InsertMenuItem(hMenu, menuPosId, TRUE, &mii);
if (isDropListMenu)
{
DeleteMenu(hMenu, menuPosId, FALSE);
}
}
else
{
SetMenuItemInfo(hMenu, id, FALSE, &mii);
}
}
for ( ; id<=IDM_WINDOW_MRU_LIMIT; ++id)
for (; id <= limitId; ++id)
{
DeleteMenu(hMenu, id, FALSE);
}
if (isDropListMenu)
{
_limitPrev = static_cast<UINT>(pTab->nbItem());
}
}
}

View File

@ -116,4 +116,6 @@ public:
private:
HMENU _hMenu = nullptr;
HMENU _hMenuList = nullptr;
UINT _limitPrev = 0;
};

View File

@ -597,6 +597,10 @@
#define IDM_WINDOW_SORT_FS_ASC (IDR_WINDOWS_MENU + 8)
#define IDM_WINDOW_SORT_FS_DSC (IDR_WINDOWS_MENU + 9)
#define IDM_WINDOW_MRU_FIRST (IDR_WINDOWS_MENU + 20)
#define IDM_WINDOW_MRU_LIMIT (IDR_WINDOWS_MENU + 29)
#define IDM_WINDOW_MRU_LIMIT (IDR_WINDOWS_MENU + 59)
#define IDM_WINDOW_COPY_NAME (IDM_WINDOW_MRU_LIMIT + 1)
#define IDM_WINDOW_COPY_PATH (IDM_WINDOW_MRU_LIMIT + 2)
#define IDR_DROPLIST_MENU 14000
#define IDM_DROPLIST_LIST (IDR_DROPLIST_MENU + 1)
#define IDM_DROPLIST_MRU_FIRST (IDR_DROPLIST_MENU + 20)

View File

@ -697,3 +697,4 @@
#define MENUINDEX_PLUGINS 10
#define MENUINDEX_WINDOW 11
#define MENUINDEX_HELP 12
#define MENUINDEX_LIST 14