From 42d863dd9f46768edee3013bfd232a27597f8ef9 Mon Sep 17 00:00:00 2001 From: spaxio Date: Sun, 4 Sep 2022 15:12:36 +0200 Subject: [PATCH] Add setting colour ability for individual tab Fix #2271, close #12098 --- PowerEditor/installer/nativeLang/english.xml | 12 ++++ PowerEditor/src/Notepad_plus.cpp | 61 ++++++++++------- PowerEditor/src/Notepad_plus.h | 2 + PowerEditor/src/Notepad_plus.rc | 7 ++ PowerEditor/src/NppCommands.cpp | 15 +++++ PowerEditor/src/NppDarkMode.cpp | 67 +++++++++++++++++++ PowerEditor/src/NppDarkMode.h | 2 + PowerEditor/src/NppIO.cpp | 2 + PowerEditor/src/NppNotification.cpp | 15 +++++ PowerEditor/src/Parameters.cpp | 13 ++++ PowerEditor/src/Parameters.h | 1 + .../src/ScintillaComponent/DocTabView.cpp | 12 ++++ .../src/ScintillaComponent/DocTabView.h | 4 ++ PowerEditor/src/WinControls/TabBar/TabBar.cpp | 39 ++++++++--- PowerEditor/src/WinControls/TabBar/TabBar.h | 2 + PowerEditor/src/localization.cpp | 64 ++++++++++-------- PowerEditor/src/menuCmdID.h | 7 ++ 17 files changed, 265 insertions(+), 60 deletions(-) diff --git a/PowerEditor/installer/nativeLang/english.xml b/PowerEditor/installer/nativeLang/english.xml index 0a2729862..dfccdefcb 100644 --- a/PowerEditor/installer/nativeLang/english.xml +++ b/PowerEditor/installer/nativeLang/english.xml @@ -404,6 +404,12 @@ The comments are here for explanation, it's not necessary to translate them. + + + + + + @@ -649,6 +655,12 @@ The comments are here for explanation, it's not necessary to translate them. + + + + + + diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 81e68ce4b..2afce5820 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -2300,30 +2300,8 @@ void Notepad_plus::setupColorSampleBitmapsOnMainMenuItems() const Style * pStyle = NppParameters::getInstance().getMiscStylerArray().findByID(bitmapOnStyleMenuItemsInfo[j].styleIndic); if (pStyle) { + HBITMAP hNewBitmap = generateSolidColourMenuItemIcon(pStyle->_bgColor); - HDC hDC = GetDC(NULL); - const int bitmapXYsize = 16; - HBITMAP hNewBitmap = CreateCompatibleBitmap(hDC, bitmapXYsize, bitmapXYsize); - HDC hDCn = CreateCompatibleDC(hDC); - HBITMAP hOldBitmap = static_cast(SelectObject(hDCn, hNewBitmap)); - RECT rc = { 0, 0, bitmapXYsize, bitmapXYsize }; - - // paint full-size black square - HBRUSH hBlackBrush = CreateSolidBrush(RGB(0,0,0)); - FillRect(hDCn, &rc, hBlackBrush); - DeleteObject(hBlackBrush); - - // overpaint a slightly smaller colored square - rc.left = rc.top = 1; - rc.right = rc.bottom = bitmapXYsize - 1; - HBRUSH hColorBrush = CreateSolidBrush(pStyle->_bgColor); - FillRect(hDCn, &rc, hColorBrush); - DeleteObject(hColorBrush); - - // restore old bitmap so we can delete it to avoid leak - SelectObject(hDCn, hOldBitmap); - DeleteDC(hDCn); - SetMenuItemBitmaps(_mainMenuHandle, bitmapOnStyleMenuItemsInfo[j].firstOfThisColorMenuId, MF_BYCOMMAND, hNewBitmap, hNewBitmap); for (int relatedMenuId : bitmapOnStyleMenuItemsInfo[j].sameColorMenuIds) { @@ -2331,6 +2309,14 @@ void Notepad_plus::setupColorSampleBitmapsOnMainMenuItems() } } } + + // Adds tab colour icons + for (int i = 0; i < 5; ++i) + { + COLORREF colour = NppDarkMode::getIndividualTabColour(i, NppDarkMode::isDarkMenuEnabled(), true); + HBITMAP hBitmap = generateSolidColourMenuItemIcon(colour); + SetMenuItemBitmaps(_mainMenuHandle, IDM_VIEW_TAB_COLOUR_1 + i, MF_BYCOMMAND, hBitmap, hBitmap); + } } bool doCheck(HMENU mainHandle, int id) @@ -5780,6 +5766,7 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session, bool includUntitledD sessionFileInfo sfi(buf->getFullPathName(), langName, buf->getEncoding(), buf->getUserReadOnly(), buf->getPosition(editView), buf->getBackupFileName().c_str(), buf->getLastModifiedTimestamp(), buf->getMapPosition()); sfi._isMonitoring = buf->isMonitoringOn(); + sfi._individualTabColour = docTab[0]->getIndividualTabColour(static_cast(i)); _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument()); size_t maxLine = static_cast(_invisibleEditView.execute(SCI_GETLINECOUNT)); @@ -8225,3 +8212,31 @@ void Notepad_plus::updateCommandShortcuts() csc.setName(menuName.c_str(), shortcutName.c_str()); } } + +HBITMAP Notepad_plus::generateSolidColourMenuItemIcon(COLORREF colour) +{ + HDC hDC = GetDC(NULL); + const int bitmapXYsize = 16; + HBITMAP hNewBitmap = CreateCompatibleBitmap(hDC, bitmapXYsize, bitmapXYsize); + HDC hDCn = CreateCompatibleDC(hDC); + HBITMAP hOldBitmap = static_cast(SelectObject(hDCn, hNewBitmap)); + RECT rc = { 0, 0, bitmapXYsize, bitmapXYsize }; + + // paint full-size black square + HBRUSH hBlackBrush = CreateSolidBrush(RGB(0,0,0)); + FillRect(hDCn, &rc, hBlackBrush); + DeleteObject(hBlackBrush); + + // overpaint a slightly smaller colored square + rc.left = rc.top = 1; + rc.right = rc.bottom = bitmapXYsize - 1; + HBRUSH hColorBrush = CreateSolidBrush(colour); + FillRect(hDCn, &rc, hColorBrush); + DeleteObject(hColorBrush); + + // restore old bitmap so we can delete it to avoid leak + SelectObject(hDCn, hOldBitmap); + DeleteDC(hDCn); + + return hNewBitmap; +} diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 9e3c48e45..c2ee8a8ae 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -638,4 +638,6 @@ private: void monitoringStartOrStopAndUpdateUI(Buffer* pBuf, bool isStarting); void createMonitoringThread(Buffer* pBuf); void updateCommandShortcuts(); + + HBITMAP generateSolidColourMenuItemIcon(COLORREF colour); }; diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index fc8562d24..9661b9482 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -705,6 +705,13 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Move Tab Forward", IDM_VIEW_TAB_MOVEFORWARD MENUITEM "Move Tab Backward", IDM_VIEW_TAB_MOVEBACKWARD + MENUITEM SEPARATOR + MENUITEM "Apply Color 1", IDM_VIEW_TAB_COLOUR_1 + MENUITEM "Apply Color 2", IDM_VIEW_TAB_COLOUR_2 + MENUITEM "Apply Color 3", IDM_VIEW_TAB_COLOUR_3 + MENUITEM "Apply Color 4", IDM_VIEW_TAB_COLOUR_4 + MENUITEM "Apply Color 5", IDM_VIEW_TAB_COLOUR_5 + MENUITEM "Remove Color", IDM_VIEW_TAB_COLOUR_NONE END MENUITEM "Word wrap", IDM_VIEW_WRAP MENUITEM "Focus on Another View", IDM_VIEW_SWITCHTO_OTHER_VIEW diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index 9f91ed90f..d994f6b24 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -977,6 +977,21 @@ void Notepad_plus::command(int id) } break; + case IDM_VIEW_TAB_COLOUR_NONE: + case IDM_VIEW_TAB_COLOUR_1: + case IDM_VIEW_TAB_COLOUR_2: + case IDM_VIEW_TAB_COLOUR_3: + case IDM_VIEW_TAB_COLOUR_4: + case IDM_VIEW_TAB_COLOUR_5: + { + const int color_id = (id - IDM_VIEW_TAB_COLOUR_NONE) - 1; + const auto current_index = _pDocTab->getCurrentTabIndex(); + BufferID buffer_id = _pDocTab->getBufferByIndex(current_index); + _pDocTab->setIndividualTabColour(buffer_id, color_id); + ::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0); + } + break; + case IDM_VIEW_TAB1: case IDM_VIEW_TAB2: case IDM_VIEW_TAB3: diff --git a/PowerEditor/src/NppDarkMode.cpp b/PowerEditor/src/NppDarkMode.cpp index ce0d933ac..3efee2ba0 100644 --- a/PowerEditor/src/NppDarkMode.cpp +++ b/PowerEditor/src/NppDarkMode.cpp @@ -28,6 +28,8 @@ #include +#include + #ifdef __GNUC__ #include #define WINAPI_LAMBDA WINAPI @@ -2852,4 +2854,69 @@ namespace NppDarkMode } return static_cast(NppDarkMode::onCtlColor(hdc)); } + + struct HLSColour + { + WORD _hue; + WORD _lightness; + WORD _saturation; + + COLORREF toRGB() const { return ColorHLSToRGB(_hue, _lightness, _saturation); } + }; + + using IndividualTabColours = std::array; + + static constexpr IndividualTabColours individualTabHuesFor_Dark { { HLSColour{0, 40, 60}, HLSColour{70, 40, 60}, HLSColour{144, 40, 60}, HLSColour{13, 40, 60}, HLSColour{195, 40, 60} } }; + static constexpr IndividualTabColours individualTabHuesFor_DarkRed { { HLSColour{0, 60, 60}, HLSColour{70, 50, 60}, HLSColour{144, 50, 60}, HLSColour{13, 50, 60}, HLSColour{195, 50, 60} } }; + static constexpr IndividualTabColours individualTabHuesFor_DarkGreen { { HLSColour{0, 50, 60}, HLSColour{70, 50, 60}, HLSColour{144, 50, 60}, HLSColour{13, 50, 60}, HLSColour{195, 50, 60} } }; + static constexpr IndividualTabColours individualTabHuesFor_DarkBlue { { HLSColour{0, 50, 60}, HLSColour{70, 50, 60}, HLSColour{144, 50, 60}, HLSColour{13, 50, 60}, HLSColour{195, 50, 60} } }; + static constexpr IndividualTabColours individualTabHuesFor_DarkPurple{ { HLSColour{0, 50, 60}, HLSColour{70, 50, 60}, HLSColour{144, 50, 60}, HLSColour{13, 50, 60}, HLSColour{195, 60, 60} } }; + static constexpr IndividualTabColours individualTabHuesFor_DarkCyan { { HLSColour{0, 60, 60}, HLSColour{70, 60, 60}, HLSColour{144, 70, 60}, HLSColour{13, 60, 60}, HLSColour{195, 60, 60} } }; + static constexpr IndividualTabColours individualTabHuesFor_DarkOlive { { HLSColour{0, 60, 60}, HLSColour{70, 60, 60}, HLSColour{144, 60, 60}, HLSColour{13, 60, 60}, HLSColour{195, 60, 60} } }; + + static const IndividualTabColours individualTabHues { { HLSColour{0, 210, 150}, HLSColour{70, 210, 150}, HLSColour{144, 210, 150}, HLSColour{13, 210, 150}, HLSColour{195, 210, 150} } }; + + const IndividualTabColours& getIndividualThemeDependantColours() + { + switch (g_colorToneChoice) + { + case redTone: return individualTabHuesFor_DarkRed; + case greenTone: return individualTabHuesFor_DarkGreen; + case blueTone: return individualTabHuesFor_DarkBlue; + case purpleTone: return individualTabHuesFor_DarkPurple; + case cyanTone: return individualTabHuesFor_DarkCyan; + case oliveTone: return individualTabHuesFor_DarkOlive; + default: return individualTabHuesFor_Dark; + } + } + + COLORREF getIndividualTabColour(int colourIndex, bool themeDependant, bool saturated) + { + if (colourIndex < 0 || colourIndex > 4) return {}; + + HLSColour result; + if (themeDependant) + { + result = getIndividualThemeDependantColours()[colourIndex]; + + if (saturated) + { + result._lightness = 146; + result._saturation = min(240, result._saturation + 100); + } + } + else + { + result = individualTabHues[colourIndex]; + + if (saturated) + { + result._lightness = 140; + result._saturation = min(240, result._saturation + 30); + } + } + + return result.toRGB(); + } + } diff --git a/PowerEditor/src/NppDarkMode.h b/PowerEditor/src/NppDarkMode.h index 4189ba5d3..0ebb28c70 100644 --- a/PowerEditor/src/NppDarkMode.h +++ b/PowerEditor/src/NppDarkMode.h @@ -133,6 +133,8 @@ namespace NppDarkMode HPEN getHotEdgePen(); HPEN getDisabledEdgePen(); + COLORREF getIndividualTabColour(int colourIndex, bool themeDependant, bool saturated); + void setBackgroundColor(COLORREF c); void setSofterBackgroundColor(COLORREF c); void setHotBackgroundColor(COLORREF c); diff --git a/PowerEditor/src/NppIO.cpp b/PowerEditor/src/NppIO.cpp index 0702eb7dd..1e4bb20c2 100644 --- a/PowerEditor/src/NppIO.cpp +++ b/PowerEditor/src/NppIO.cpp @@ -2105,6 +2105,8 @@ bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode, bool shou if (isSnapshotMode && session._mainViewFiles[i]._backupFilePath != TEXT("") && PathFileExists(session._mainViewFiles[i]._backupFilePath.c_str())) buf->setDirty(true); + _mainDocTab.setIndividualTabColour(lastOpened, session._mainViewFiles[i]._individualTabColour); + //Force in the document so we can add the markers //Don't use default methods because of performance Document prevDoc = _mainEditView.execute(SCI_GETDOCPOINTER); diff --git a/PowerEditor/src/NppNotification.cpp b/PowerEditor/src/NppNotification.cpp index c090e76aa..514c10eed 100644 --- a/PowerEditor/src/NppNotification.cpp +++ b/PowerEditor/src/NppNotification.cpp @@ -539,6 +539,13 @@ BOOL Notepad_plus::notify(SCNotification *notification) itemUnitArray.push_back(MenuItemUnit(IDM_FILE_RELOAD, TEXT("Reload"))); itemUnitArray.push_back(MenuItemUnit(IDM_FILE_PRINT, TEXT("Print"))); itemUnitArray.push_back(MenuItemUnit(0, NULL)); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_1, TEXT("Apply Color 1"))); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_2, TEXT("Apply Color 2"))); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_3, TEXT("Apply Color 3"))); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_4, TEXT("Apply Color 4"))); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_5, TEXT("Apply Color 5"))); + itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_TAB_COLOUR_NONE, TEXT("Remove Color"))); + itemUnitArray.push_back(MenuItemUnit(0, NULL)); itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_FOLDER, TEXT("Open Containing Folder in Explorer"))); itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_CMD, TEXT("Open Containing Folder in cmd"))); itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CONTAININGFOLDERASWORKSPACE, TEXT("Open Containing Folder as Workspace"))); @@ -562,6 +569,14 @@ BOOL Notepad_plus::notify(SCNotification *notification) _nativeLangSpeaker.changeLangTabContextMenu(_tabPopupMenu.getMenuHandle()); } + // Adds colour icons + for (int i = 0; i < 5; ++i) + { + COLORREF colour = NppDarkMode::getIndividualTabColour(i, NppDarkMode::isDarkMenuEnabled(), true); + HBITMAP hBitmap = generateSolidColourMenuItemIcon(colour); + SetMenuItemBitmaps(_tabPopupMenu.getMenuHandle(), IDM_VIEW_TAB_COLOUR_1 + i, MF_BYCOMMAND, hBitmap, hBitmap); + } + bool isEnable = ((::GetMenuState(_mainMenuHandle, IDM_FILE_SAVE, MF_BYCOMMAND)&MF_DISABLED) == 0); _tabPopupMenu.enableItem(IDM_FILE_SAVE, isEnable); diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 6e53e2bdf..09acf95e4 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -321,6 +321,12 @@ static const WinMenuKeyDefinition winKeyDefs[] = { VK_NULL, IDM_VIEW_SWITCHTO_FILEBROWSER, false, false, false, TEXT("Switch to Folder as Workspace") }, { VK_NULL, IDM_VIEW_SWITCHTO_FUNC_LIST, false, false, false, TEXT("Switch to Function List") }, { VK_NULL, IDM_VIEW_SWITCHTO_DOCLIST, false, false, false, TEXT("Switch to Document List") }, + { VK_NULL, IDM_VIEW_TAB_COLOUR_NONE, false, false, false, TEXT("Remove Tab Colour") }, + { VK_NULL, IDM_VIEW_TAB_COLOUR_1, false, false, false, TEXT("Apply Tab Colour 1") }, + { VK_NULL, IDM_VIEW_TAB_COLOUR_2, false, false, false, TEXT("Apply Tab Colour 2") }, + { VK_NULL, IDM_VIEW_TAB_COLOUR_3, false, false, false, TEXT("Apply Tab Colour 3") }, + { VK_NULL, IDM_VIEW_TAB_COLOUR_4, false, false, false, TEXT("Apply Tab Colour 4") }, + { VK_NULL, IDM_VIEW_TAB_COLOUR_5, false, false, false, TEXT("Apply Tab Colour 5") }, { VK_NULL, IDM_VIEW_SYNSCROLLV, false, false, false, nullptr }, { VK_NULL, IDM_VIEW_SYNSCROLLH, false, false, false, nullptr }, { VK_R, IDM_EDIT_RTL, true, true, false, nullptr }, @@ -2280,6 +2286,12 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session& s sessionFileInfo sfi(fileName, langName, encStr ? encoding : -1, isUserReadOnly, position, backupFilePath, fileModifiedTimestamp, mapPosition); + const TCHAR* intStrTabColour = (childNode->ToElement())->Attribute(TEXT("tabColourId")); + if (intStrTabColour) + { + sfi._individualTabColour = generic_atoi(intStrTabColour); + } + for (TiXmlNode *markNode = childNode->FirstChildElement(TEXT("Mark")); markNode; markNode = markNode->NextSibling(TEXT("Mark"))) @@ -3348,6 +3360,7 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName) (fileNameNode->ToElement())->SetAttribute(TEXT("backupFilePath"), viewSessionFiles[i]._backupFilePath.c_str()); (fileNameNode->ToElement())->SetAttribute(TEXT("originalFileLastModifTimestamp"), static_cast(viewSessionFiles[i]._originalFileLastModifTimestamp.dwLowDateTime)); (fileNameNode->ToElement())->SetAttribute(TEXT("originalFileLastModifTimestampHigh"), static_cast(viewSessionFiles[i]._originalFileLastModifTimestamp.dwHighDateTime)); + (fileNameNode->ToElement())->SetAttribute(TEXT("tabColourId"), static_cast(viewSessionFiles[i]._individualTabColour)); // docMap (fileNameNode->ToElement())->SetAttribute(TEXT("mapFirstVisibleDisplayLine"), _i64tot(static_cast(viewSessionFiles[i]._mapPos._firstVisibleDisplayLine), szInt64, 10)); diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index 0a83aba76..1947cf926 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -201,6 +201,7 @@ struct sessionFileInfo : public Position int _encoding = -1; bool _isUserReadOnly = false; bool _isMonitoring = false; + int _individualTabColour = -1; generic_string _backupFilePath; FILETIME _originalFileLastModifTimestamp = {}; diff --git a/PowerEditor/src/ScintillaComponent/DocTabView.cpp b/PowerEditor/src/ScintillaComponent/DocTabView.cpp index 9979dd0f6..acc751bac 100644 --- a/PowerEditor/src/ScintillaComponent/DocTabView.cpp +++ b/PowerEditor/src/ScintillaComponent/DocTabView.cpp @@ -56,6 +56,18 @@ void DocTabView::closeBuffer(BufferID buffer) ::SendMessage(_hParent, WM_SIZE, 0, 0); } +void DocTabView::setIndividualTabColour(BufferID bufferId, int colorId) +{ + _tabIndexToColour[bufferId] = colorId; +} + +int DocTabView::getIndividualTabColour(int tabIndex) +{ + BufferID bufferId = getBufferByIndex(tabIndex); + auto it = _tabIndexToColour.find(bufferId); + if (it != _tabIndexToColour.end()) return it->second; + else return -1; +} bool DocTabView::activateBuffer(BufferID buffer) { diff --git a/PowerEditor/src/ScintillaComponent/DocTabView.h b/PowerEditor/src/ScintillaComponent/DocTabView.h index 0f95f4974..6f6920c12 100644 --- a/PowerEditor/src/ScintillaComponent/DocTabView.h +++ b/PowerEditor/src/ScintillaComponent/DocTabView.h @@ -90,10 +90,14 @@ public : return _pView; }; + void setIndividualTabColour(BufferID bufferId, int colorId); + int getIndividualTabColour(int tabIndex) override; + private : ScintillaEditView *_pView = nullptr; static bool _hideTabBarStatus; + std::map _tabIndexToColour; std::vector _pIconListVector; int _iconListIndexChoice = -1; }; diff --git a/PowerEditor/src/WinControls/TabBar/TabBar.cpp b/PowerEditor/src/WinControls/TabBar/TabBar.cpp index 70db8435e..8d1eb9e69 100644 --- a/PowerEditor/src/WinControls/TabBar/TabBar.cpp +++ b/PowerEditor/src/WinControls/TabBar/TabBar.cpp @@ -1002,7 +1002,6 @@ LRESULT TabBarPlus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPara return ::CallWindowProc(_tabBarDefaultProc, hwnd, Message, wParam, lParam); } - void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode) { RECT rect = pDrawItemStruct->rcItem; @@ -1032,7 +1031,7 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode) HBRUSH hBrush = ::CreateSolidBrush(!isDarkMode ? ::GetSysColor(COLOR_BTNFACE) : NppDarkMode::getBackgroundColor()); ::FillRect(hDC, &rect, hBrush); ::DeleteObject((HGDIOBJ)hBrush); - + // equalize drawing areas of active and inactive tabs int paddingDynamicTwoX = NppParameters::getInstance()._dpiManager.scaleX(2); int paddingDynamicTwoY = NppParameters::getInstance()._dpiManager.scaleY(2); @@ -1072,7 +1071,7 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode) rect.bottom += paddingDynamicTwoY; } } - + // the active tab's text with TCS_BUTTONS is lower than normal and gets clipped if (::GetWindowLongPtr(_hSelf, GWL_STYLE) & TCS_BUTTONS) { @@ -1086,6 +1085,8 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode) } } + const int individualColourId = getIndividualTabColour(nTab); + // draw highlights on tabs (top bar for active tab / darkened background for inactive tab) RECT barRect = rect; if (isSelected) @@ -1109,7 +1110,14 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode) } if (::SendMessage(_hParent, NPPM_INTERNAL_ISFOCUSEDTAB, 0, reinterpret_cast(_hSelf))) - hBrush = ::CreateSolidBrush(_activeTopBarFocusedColour); // #FAAA3C + { + COLORREF topBarColour = _activeTopBarFocusedColour; // #FAAA3C + if (individualColourId != -1) + { + topBarColour = NppDarkMode::getIndividualTabColour(individualColourId, isDarkMode, true); + } + hBrush = ::CreateSolidBrush(topBarColour); + } else hBrush = ::CreateSolidBrush(_activeTopBarUnfocusedColour); // #FAD296 @@ -1117,12 +1125,27 @@ void TabBarPlus::drawItem(DRAWITEMSTRUCT *pDrawItemStruct, bool isDarkMode) ::DeleteObject((HGDIOBJ)hBrush); } } - else + else // inactive tabs { - if (_drawInactiveTab) + bool draw = false; + RECT rect = _isCtrlMultiLine ? pDrawItemStruct->rcItem : barRect; + COLORREF brushColour{}; + + if (_drawInactiveTab && individualColourId == -1 && !isDarkMode) { - hBrush = ::CreateSolidBrush(!isDarkMode ? _inactiveBgColour : NppDarkMode::getBackgroundColor()); - ::FillRect(hDC, &barRect, hBrush); + brushColour = _inactiveBgColour; + draw = true; + } + else if (individualColourId != -1) + { + brushColour = NppDarkMode::getIndividualTabColour(individualColourId, isDarkMode, false); + draw = true; + } + + if (draw) + { + hBrush = ::CreateSolidBrush(brushColour); + ::FillRect(hDC, &rect, hBrush); ::DeleteObject((HGDIOBJ)hBrush); } } diff --git a/PowerEditor/src/WinControls/TabBar/TabBar.h b/PowerEditor/src/WinControls/TabBar/TabBar.h index 47db586fc..9e92dd008 100644 --- a/PowerEditor/src/WinControls/TabBar/TabBar.h +++ b/PowerEditor/src/WinControls/TabBar/TabBar.h @@ -208,6 +208,8 @@ public : static void setColour(COLORREF colour2Set, tabColourIndex i); + virtual int getIndividualTabColour(int tabIndex) = 0; + protected: // it's the boss to decide if we do the drag N drop static bool _doDragNDrop; diff --git a/PowerEditor/src/localization.cpp b/PowerEditor/src/localization.cpp index 7e5cf07a0..8dd3bb303 100644 --- a/PowerEditor/src/localization.cpp +++ b/PowerEditor/src/localization.cpp @@ -379,35 +379,41 @@ void NativeLangSpeaker::changeMenuLang(HMENU menuHandle) static const int tabContextMenuItemPos[] = { -// +-------------- The order in tab menu (NppNotification.cpp : if (!_tabPopupMenu.isCreated()) -// | -// | +------ Number in english.xml (.xml) : -// | | - 0, // 0: Close - 1, // 1: Close ALL BUT This - 5, // 2: Save - 6, // 3: Save As - 10, // 4: Print - 25, // 5: Move to Other View - 26, // 6: Clone to Other View - 21, // 7: Full File Path to Clipboard - 22, // 8: Filename to Clipboard - 23, // 9: Current Dir. Path to Clipboard - 7, // 10: Rename - 8, // 11: Move to Recycle Bin - 18, // 12: Read-Only - 19, // 13: Clear Read-Only Flag - 27, // 14: Move to New Instance - 28, // 15: Open to New Instance - 9, // 16: Reload - 2, // 17: Close ALL to the Left - 3, // 18: Close ALL to the Right - 12, // 19: Open Containing Folder in Explorer - 13, // 20: Open Containing Folder in cmd - 16, // 21: Open in Default Viewer - 4, // 22: Close ALL Unchanged - 14, // 23: Open Containing Folder as Workspace - -1 //-------End + // +-------------- The item position in tab context menu + // | + // | +------ Index order (CMDID) in of english.xml + // | | + 0, // 0: Close + 1, // 1: Close ALL BUT This + 5, // 2: Save + 6, // 3: Save As + 10, // 4: Print + 32, // 5: Move to Other View + 33, // 6: Clone to Other View + 28, // 7: Full File Path to Clipboard + 29, // 8: Filename to Clipboard + 30, // 9: Current Dir. Path to Clipboard + 7, // 10: Rename + 8, // 11: Move to Recycle Bin + 25, // 12: Read-Only + 24, // 13: Clear Read-Only Flag + 34, // 14: Move to New Instance + 35, // 15: Open to New Instance + 9, // 16: Reload + 2, // 17: Close ALL to the Left + 3, // 18: Close ALL to the Right + 19, // 19: Open Containing Folder in Explorer + 20, // 20: Open Containing Folder in cmd + 23, // 21: Open in Default Viewer + 4, // 22: Close ALL Unchanged + 21, // 23: Open Containing Folder as Workspace + 12, // 24: Apply Color + 13, // 25: Apply Color + 14, // 26: Apply Color + 15, // 27: Apply Color + 16, // 28: Apply Color + 17, // 29: Remove Color + -1 //-------End }; diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index e3fc5104d..4c5bab440 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -367,6 +367,13 @@ #define IDM_VIEW_SWITCHTO_FUNC_LIST (IDM_VIEW + 108) #define IDM_VIEW_SWITCHTO_DOCLIST (IDM_VIEW + 109) + #define IDM_VIEW_TAB_COLOUR_NONE (IDM_VIEW + 110) + #define IDM_VIEW_TAB_COLOUR_1 (IDM_VIEW + 111) + #define IDM_VIEW_TAB_COLOUR_2 (IDM_VIEW + 112) + #define IDM_VIEW_TAB_COLOUR_3 (IDM_VIEW + 113) + #define IDM_VIEW_TAB_COLOUR_4 (IDM_VIEW + 114) + #define IDM_VIEW_TAB_COLOUR_5 (IDM_VIEW + 115) + #define IDM_VIEW_GOTO_ANOTHER_VIEW 10001 #define IDM_VIEW_CLONE_TO_ANOTHER_VIEW 10002 #define IDM_VIEW_GOTO_NEW_INSTANCE 10003