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,10 +558,12 @@ generic_string uintToString(unsigned int val)
} }
// Build Recent File menu entries from given // 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; generic_string strTemp;
if (ordinalNumber)
{
if (pos < 9) if (pos < 9)
{ {
strTemp.push_back('&'); strTemp.push_back('&');
@ -573,9 +575,17 @@ generic_string BuildMenuFileName(int filenameLen, unsigned int pos, const generi
} }
else else
{ {
strTemp.append(uintToString(pos + 1)); div_t splitDigits = div(pos + 1, 10);
strTemp.append(uintToString(splitDigits.quot));
strTemp.push_back('&');
strTemp.append(uintToString(splitDigits.rem));
} }
strTemp.append(TEXT(": ")); strTemp.append(TEXT(": "));
}
else
{
strTemp.push_back('&');
}
if (filenameLen > 0) 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::wstring string2wstring(const std::string & rString, UINT codepage);
std::string wstring2string(const std::wstring & rwString, UINT codepage); std::string wstring2string(const std::wstring & rwString, UINT codepage);
bool isInList(const TCHAR *token, const TCHAR *list); 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); std::string getFileContent(const TCHAR *file2read);
generic_string relativeFilePathToFullFilePath(const TCHAR *relativeFilePath); generic_string relativeFilePathToFullFilePath(const TCHAR *relativeFilePath);

View File

@ -15,6 +15,12 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // 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 <windows.h>
#include "resource.h" #include "resource.h"
#include "menuCmdID.h" #include "menuCmdID.h"
@ -1184,9 +1190,9 @@ BEGIN
MENUITEM "Size Smaller to Larger", IDM_WINDOW_SORT_FS_ASC MENUITEM "Size Smaller to Larger", IDM_WINDOW_SORT_FS_ASC
MENUITEM "Size Larger to Smaller", IDM_WINDOW_SORT_FS_DSC MENUITEM "Size Larger to Smaller", IDM_WINDOW_SORT_FS_DSC
END END
MENUITEM "&Windows...", IDM_WINDOW_WINDOWS
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "Recent Window", IDM_WINDOW_MRU_FIRST, GRAYED MENUITEM "Recent Window", IDM_WINDOW_MRU_FIRST, GRAYED
MENUITEM "&Windows...", IDM_WINDOW_WINDOWS
END END
POPUP "&?" POPUP "&?"
@ -1205,7 +1211,12 @@ BEGIN
MENUITEM "About Notepad++", IDM_ABOUT MENUITEM "About Notepad++", IDM_ABOUT
END 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 END
IDR_SYSTRAYPOPUP_MENU MENU 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)) 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) void WindowsMenu::init(HMENU hMainMenu)
{ {
_hMenu = ::GetSubMenu(hMainMenu, MENUINDEX_WINDOW); _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) 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(); 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(); size_t nDoc = pTab->nbItem();
nDoc = min(nDoc, nMaxDoc); nDoc = min(nDoc, nMaxDoc);
int id; UINT id = firstId;
size_t pos; UINT guard = firstId + static_cast<int32_t>(nDoc);
for (id = IDM_WINDOW_MRU_FIRST, pos = 0; id < IDM_WINDOW_MRU_FIRST + static_cast<int32_t>(nDoc); ++id, ++pos) size_t pos = 0;
for (id, pos; id < guard; ++id, ++pos)
{ {
BufferID bufID = pTab->getBufferByIndex(pos); BufferID bufID = pTab->getBufferByIndex(pos);
Buffer * buf = MainFileManager.getBufferByID(bufID); Buffer* buf = MainFileManager.getBufferByID(bufID);
MENUITEMINFO mii; MENUITEMINFO mii{};
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii); mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING|MIIM_STATE|MIIM_ID; 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. generic_string strBuffer(BuildMenuFileName(60, static_cast<int32_t>(pos), buf->getFileName(), !isDropListMenu));
// So, making temporary buffer for this.
std::vector<TCHAR> vBuffer(strBuffer.begin(), strBuffer.end()); std::vector<TCHAR> vBuffer(strBuffer.begin(), strBuffer.end());
vBuffer.push_back('\0'); vBuffer.push_back('\0');
mii.dwTypeData = (&vBuffer[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.fState |= MF_CHECKED;
}
mii.wID = id; mii.wID = id;
UINT state = GetMenuState(hMenu, id, MF_BYCOMMAND); UINT state = GetMenuState(hMenu, id, MF_BYCOMMAND);
if (state == ((UINT)-1)) if (state == static_cast<UINT>(-1))
InsertMenuItem(hMenu, IDM_WINDOW_WINDOWS, FALSE, &mii); {
InsertMenuItem(hMenu, menuPosId, TRUE, &mii);
if (isDropListMenu)
{
DeleteMenu(hMenu, menuPosId, FALSE);
}
}
else else
{
SetMenuItemInfo(hMenu, id, FALSE, &mii); SetMenuItemInfo(hMenu, id, FALSE, &mii);
} }
for ( ; id<=IDM_WINDOW_MRU_LIMIT; ++id) }
for (; id <= limitId; ++id)
{ {
DeleteMenu(hMenu, id, FALSE); DeleteMenu(hMenu, id, FALSE);
} }
if (isDropListMenu)
{
_limitPrev = static_cast<UINT>(pTab->nbItem());
}
} }
} }

View File

@ -116,4 +116,6 @@ public:
private: private:
HMENU _hMenu = nullptr; 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_ASC (IDR_WINDOWS_MENU + 8)
#define IDM_WINDOW_SORT_FS_DSC (IDR_WINDOWS_MENU + 9) #define IDM_WINDOW_SORT_FS_DSC (IDR_WINDOWS_MENU + 9)
#define IDM_WINDOW_MRU_FIRST (IDR_WINDOWS_MENU + 20) #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_NAME (IDM_WINDOW_MRU_LIMIT + 1)
#define IDM_WINDOW_COPY_PATH (IDM_WINDOW_MRU_LIMIT + 2) #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_PLUGINS 10
#define MENUINDEX_WINDOW 11 #define MENUINDEX_WINDOW 11
#define MENUINDEX_HELP 12 #define MENUINDEX_HELP 12
#define MENUINDEX_LIST 14