Apply tab colors to document list items
and add groups to document list. Fix #12155, fix #12689, cllose #13080
This commit is contained in:
parent
0c704fd66b
commit
37963ea21a
|
@ -1429,6 +1429,7 @@ Do you want to save your changes before switching themes?"/> <!-- HowToReproduce
|
|||
<ColumnName name="Name"/>
|
||||
<ColumnExt name="Ext."/>
|
||||
<ColumnPath name="Path"/>
|
||||
<ListGroups name="Group by View"/>
|
||||
</DocList>
|
||||
<WindowsDlg>
|
||||
<ColumnName name="Name"/>
|
||||
|
|
|
@ -4618,6 +4618,12 @@ void Notepad_plus::docGotoAnotherEditView(FileTransferMode mode)
|
|||
{
|
||||
command(IDM_VIEW_MONITORING);
|
||||
}
|
||||
|
||||
if (_pDocumentListPanel != nullptr)
|
||||
{
|
||||
Buffer* buf = MainFileManager.getBufferByID(current);
|
||||
_pDocumentListPanel->setItemColor(buf);
|
||||
}
|
||||
}
|
||||
|
||||
bool Notepad_plus::activateBuffer(BufferID id, int whichOne, bool forceApplyHilite)
|
||||
|
@ -5379,14 +5385,14 @@ void Notepad_plus::getTaskListInfo(TaskListInfo *tli)
|
|||
BufferID bufID = _pDocTab->getBufferByIndex(i);
|
||||
Buffer * b = MainFileManager.getBufferByID(bufID);
|
||||
int status = b->isMonitoringOn()?tb_monitored:(b->isReadOnly()?tb_ro:(b->isDirty()?tb_unsaved:tb_saved));
|
||||
tli->_tlfsLst.push_back(TaskLstFnStatus(currentView(), i, b->getFullPathName(), status, (void *)bufID));
|
||||
tli->_tlfsLst.push_back(TaskLstFnStatus(currentView(), i, b->getFullPathName(), status, (void *)bufID, b->getDocColorId()));
|
||||
}
|
||||
for (int i = 0 ; i < nonCurrentNbDoc ; ++i)
|
||||
{
|
||||
BufferID bufID = _pNonDocTab->getBufferByIndex(i);
|
||||
Buffer * b = MainFileManager.getBufferByID(bufID);
|
||||
int status = b->isMonitoringOn()?tb_monitored:(b->isReadOnly()?tb_ro:(b->isDirty()?tb_unsaved:tb_saved));
|
||||
tli->_tlfsLst.push_back(TaskLstFnStatus(otherView(), i, b->getFullPathName(), status, (void *)bufID));
|
||||
tli->_tlfsLst.push_back(TaskLstFnStatus(otherView(), i, b->getFullPathName(), status, (void *)bufID, b->getDocColorId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5972,7 +5978,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<int>(i));
|
||||
sfi._individualTabColour = docTab[k]->getIndividualTabColour(static_cast<int>(i));
|
||||
|
||||
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument());
|
||||
size_t maxLine = static_cast<size_t>(_invisibleEditView.execute(SCI_GETLINECOUNT));
|
||||
|
|
|
@ -999,7 +999,12 @@ void Notepad_plus::command(int id)
|
|||
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);
|
||||
_pDocTab->redraw();
|
||||
|
||||
if (_pDocumentListPanel != nullptr)
|
||||
{
|
||||
_pDocumentListPanel->setItemColor(buffer_id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -3112,11 +3117,13 @@ void Notepad_plus::command(int id)
|
|||
case IDM_VIEW_GOTO_ANOTHER_VIEW:
|
||||
docGotoAnotherEditView(TransferMove);
|
||||
checkSyncState();
|
||||
::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0);
|
||||
break;
|
||||
|
||||
case IDM_VIEW_CLONE_TO_ANOTHER_VIEW:
|
||||
docGotoAnotherEditView(TransferClone);
|
||||
checkSyncState();
|
||||
::SendMessage(_pPublicInterface->getHSelf(), WM_SIZE, 0, 0);
|
||||
break;
|
||||
|
||||
case IDM_VIEW_GOTO_NEW_INSTANCE :
|
||||
|
|
|
@ -2288,6 +2288,8 @@ bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode, bool shou
|
|||
if (isSnapshotMode && session._subViewFiles[k]._backupFilePath != TEXT("") && PathFileExists(session._subViewFiles[k]._backupFilePath.c_str()))
|
||||
buf->setDirty(true);
|
||||
|
||||
_subDocTab.setIndividualTabColour(lastOpened, session._subViewFiles[k]._individualTabColour);
|
||||
|
||||
//Force in the document so we can add the markers
|
||||
//Don't use default methods because of performance
|
||||
Document prevDoc = _subEditView.execute(SCI_GETDOCPOINTER);
|
||||
|
|
|
@ -4514,6 +4514,18 @@ void NppParameters::feedGUIParameters(TiXmlNode *node)
|
|||
if (nullptr == nm)
|
||||
continue;
|
||||
|
||||
auto parseYesNoBoolAttribute = [&element](const TCHAR* name, bool defaultValue = false) -> bool {
|
||||
const TCHAR* val = element->Attribute(name);
|
||||
if (val != nullptr)
|
||||
{
|
||||
if (!lstrcmp(val, TEXT("yes")))
|
||||
return true;
|
||||
else if (!lstrcmp(val, TEXT("no")))
|
||||
return false;
|
||||
}
|
||||
return defaultValue;
|
||||
};
|
||||
|
||||
if (!lstrcmp(nm, TEXT("ToolBar")))
|
||||
{
|
||||
const TCHAR* val = element->Attribute(TEXT("visible"));
|
||||
|
@ -5765,18 +5777,6 @@ void NppParameters::feedGUIParameters(TiXmlNode *node)
|
|||
val = 0;
|
||||
_nppGUI._multiInstSetting = (MultiInstSetting)val;
|
||||
|
||||
auto parseYesNoBoolAttribute = [&element](const TCHAR* name, bool defaultValue = false) -> bool {
|
||||
const TCHAR* val = element->Attribute(name);
|
||||
if (val != nullptr)
|
||||
{
|
||||
if (!lstrcmp(val, TEXT("yes")))
|
||||
return true;
|
||||
else if (!lstrcmp(val, TEXT("no")))
|
||||
return false;
|
||||
}
|
||||
return defaultValue;
|
||||
};
|
||||
|
||||
_nppGUI._clipboardHistoryPanelKeepState = parseYesNoBoolAttribute(TEXT("clipboardHistory"));
|
||||
_nppGUI._docListKeepState = parseYesNoBoolAttribute(TEXT("documentList"));
|
||||
_nppGUI._charPanelKeepState = parseYesNoBoolAttribute(TEXT("characterPanel"));
|
||||
|
@ -5847,6 +5847,8 @@ void NppParameters::feedGUIParameters(TiXmlNode *node)
|
|||
if (element->Attribute(TEXT("fileSwitcherPathWidth"), &i))
|
||||
_nppGUI._fileSwitcherPathWidth = i;
|
||||
|
||||
_nppGUI._fileSwitcherDisableListViewGroups = parseYesNoBoolAttribute(TEXT("fileSwitcherNoGroups"));
|
||||
|
||||
const TCHAR * optNameBackSlashEscape = element->Attribute(TEXT("backSlashIsEscapeCharacterForSql"));
|
||||
if (optNameBackSlashEscape && !lstrcmp(optNameBackSlashEscape, TEXT("no")))
|
||||
_nppGUI._backSlashIsEscapeCharacterForSql = false;
|
||||
|
@ -7167,10 +7169,16 @@ void NppParameters::createXmlTreeFromGUIParams()
|
|||
TiXmlElement *GUIConfigElement = (newGUIRoot->InsertEndChild(TiXmlElement(TEXT("GUIConfig"))))->ToElement();
|
||||
GUIConfigElement->SetAttribute(TEXT("name"), TEXT("MISC"));
|
||||
|
||||
auto setYesNoBoolAttribute = [&GUIConfigElement](const TCHAR* name, bool value) -> void {
|
||||
const TCHAR* pStr = value ? TEXT("yes") : TEXT("no");
|
||||
GUIConfigElement->SetAttribute(name, pStr);
|
||||
};
|
||||
|
||||
GUIConfigElement->SetAttribute(TEXT("fileSwitcherWithoutExtColumn"), _nppGUI._fileSwitcherWithoutExtColumn ? TEXT("yes") : TEXT("no"));
|
||||
GUIConfigElement->SetAttribute(TEXT("fileSwitcherExtWidth"), _nppGUI._fileSwitcherExtWidth);
|
||||
GUIConfigElement->SetAttribute(TEXT("fileSwitcherWithoutPathColumn"), _nppGUI._fileSwitcherWithoutPathColumn ? TEXT("yes") : TEXT("no"));
|
||||
GUIConfigElement->SetAttribute(TEXT("fileSwitcherPathWidth"), _nppGUI._fileSwitcherPathWidth);
|
||||
setYesNoBoolAttribute(TEXT("fileSwitcherNoGroups"), _nppGUI._fileSwitcherDisableListViewGroups);
|
||||
GUIConfigElement->SetAttribute(TEXT("backSlashIsEscapeCharacterForSql"), _nppGUI._backSlashIsEscapeCharacterForSql ? TEXT("yes") : TEXT("no"));
|
||||
GUIConfigElement->SetAttribute(TEXT("writeTechnologyEngine"), _nppGUI._writeTechnologyEngine);
|
||||
GUIConfigElement->SetAttribute(TEXT("isFolderDroppedOpenFiles"), _nppGUI._isFolderDroppedOpenFiles ? TEXT("yes") : TEXT("no"));
|
||||
|
|
|
@ -894,10 +894,11 @@ struct NppGUI final
|
|||
bool _docMapKeepState = false;
|
||||
bool _funcListKeepState = false;
|
||||
bool _pluginPanelKeepState = false;
|
||||
bool _fileSwitcherWithoutExtColumn = true;
|
||||
bool _fileSwitcherWithoutExtColumn = false;
|
||||
int _fileSwitcherExtWidth = 50;
|
||||
bool _fileSwitcherWithoutPathColumn = true;
|
||||
int _fileSwitcherPathWidth = 50;
|
||||
bool _fileSwitcherDisableListViewGroups = false;
|
||||
bool isSnapshotMode() const {return _isSnapshotMode && _rememberLastSession && !_isCmdlineNosessionActivated;};
|
||||
bool _isSnapshotMode = true;
|
||||
size_t _snapshotBackupTiming = 7000;
|
||||
|
|
|
@ -320,6 +320,14 @@ public:
|
|||
bool allowSmartHilite() const;
|
||||
bool allowClickableLink() const;
|
||||
|
||||
void setDocColorId(int idx) {
|
||||
_docColorId = idx;
|
||||
};
|
||||
|
||||
int getDocColorId() {
|
||||
return _docColorId;
|
||||
};
|
||||
|
||||
private:
|
||||
int indexOfReference(const ScintillaEditView * identifier) const;
|
||||
|
||||
|
@ -369,6 +377,8 @@ private:
|
|||
long _recentTag = -1;
|
||||
static long _recentTagCtr;
|
||||
|
||||
int _docColorId = -1;
|
||||
|
||||
// For backup system
|
||||
generic_string _backupFileName;
|
||||
bool _isModified = false;
|
||||
|
|
|
@ -33,7 +33,7 @@ void DocTabView::addBuffer(BufferID buffer)
|
|||
if (getIndexByBuffer(buffer) != -1) //no duplicates
|
||||
return;
|
||||
Buffer * buf = MainFileManager.getBufferByID(buffer);
|
||||
TCITEM tie;
|
||||
TCITEM tie{};
|
||||
tie.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_PARAM;
|
||||
|
||||
int index = -1;
|
||||
|
@ -58,15 +58,13 @@ void DocTabView::closeBuffer(BufferID buffer)
|
|||
|
||||
void DocTabView::setIndividualTabColour(BufferID bufferId, int colorId)
|
||||
{
|
||||
_tabIndexToColour[bufferId] = colorId;
|
||||
bufferId->setDocColorId(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;
|
||||
return bufferId->getDocColorId();
|
||||
}
|
||||
|
||||
bool DocTabView::activateBuffer(BufferID buffer)
|
||||
|
@ -89,7 +87,7 @@ BufferID DocTabView::activeBuffer()
|
|||
|
||||
BufferID DocTabView::findBufferByName(const TCHAR * fullfilename) //-1 if not found, something else otherwise
|
||||
{
|
||||
TCITEM tie;
|
||||
TCITEM tie{};
|
||||
tie.lParam = -1;
|
||||
tie.mask = TCIF_PARAM;
|
||||
for (size_t i = 0; i < _nbItem; ++i)
|
||||
|
@ -108,7 +106,7 @@ BufferID DocTabView::findBufferByName(const TCHAR * fullfilename) //-1 if not fo
|
|||
|
||||
int DocTabView::getIndexByBuffer(BufferID id)
|
||||
{
|
||||
TCITEM tie;
|
||||
TCITEM tie{};
|
||||
tie.lParam = -1;
|
||||
tie.mask = TCIF_PARAM;
|
||||
for (size_t i = 0; i < _nbItem; ++i)
|
||||
|
@ -123,7 +121,7 @@ int DocTabView::getIndexByBuffer(BufferID id)
|
|||
|
||||
BufferID DocTabView::getBufferByIndex(size_t index)
|
||||
{
|
||||
TCITEM tie;
|
||||
TCITEM tie{};
|
||||
tie.lParam = -1;
|
||||
tie.mask = TCIF_PARAM;
|
||||
::SendMessage(_hSelf, TCM_GETITEM, index, reinterpret_cast<LPARAM>(&tie));
|
||||
|
@ -138,7 +136,7 @@ void DocTabView::bufferUpdated(Buffer * buffer, int mask)
|
|||
if (index == -1)
|
||||
return;
|
||||
|
||||
TCITEM tie;
|
||||
TCITEM tie{};
|
||||
tie.lParam = -1;
|
||||
tie.mask = 0;
|
||||
|
||||
|
@ -157,7 +155,7 @@ void DocTabView::bufferUpdated(Buffer * buffer, int mask)
|
|||
}
|
||||
|
||||
//We must make space for the added ampersand characters.
|
||||
TCHAR encodedLabel[2 * MAX_PATH];
|
||||
TCHAR encodedLabel[2 * MAX_PATH] = { '\0' };
|
||||
|
||||
if (mask & BufferChangeFilename)
|
||||
{
|
||||
|
@ -200,7 +198,7 @@ void DocTabView::setBuffer(size_t index, BufferID id)
|
|||
if (index < 0 || index >= _nbItem)
|
||||
return;
|
||||
|
||||
TCITEM tie;
|
||||
TCITEM tie{};
|
||||
tie.lParam = reinterpret_cast<LPARAM>(id);
|
||||
tie.mask = TCIF_PARAM;
|
||||
::SendMessage(_hSelf, TCM_SETITEM, index, reinterpret_cast<LPARAM>(&tie));
|
||||
|
|
|
@ -97,7 +97,6 @@ private :
|
|||
ScintillaEditView *_pView = nullptr;
|
||||
static bool _hideTabBarStatus;
|
||||
|
||||
std::map<BufferID, int> _tabIndexToColour;
|
||||
std::vector<IconList *> _pIconListVector;
|
||||
int _iconListIndexChoice = -1;
|
||||
};
|
||||
|
|
|
@ -32,9 +32,10 @@ struct TaskLstFnStatus {
|
|||
generic_string _fn;
|
||||
int _status = 0;
|
||||
void *_bufID = nullptr;
|
||||
int _docColor = -1;
|
||||
TaskLstFnStatus(const generic_string& str, int status) : _fn(str), _status(status){};
|
||||
TaskLstFnStatus(int iView, int docIndex, generic_string str, int status, void *bufID) :
|
||||
_iView(iView), _docIndex(docIndex), _fn(str), _status(status), _bufID(bufID) {};
|
||||
TaskLstFnStatus(int iView, int docIndex, generic_string str, int status, void *bufID, int docColor) :
|
||||
_iView(iView), _docIndex(docIndex), _fn(str), _status(status), _bufID(bufID), _docColor(docColor) {};
|
||||
};
|
||||
|
||||
struct TaskListInfo {
|
||||
|
|
|
@ -27,6 +27,10 @@
|
|||
|
||||
#define CLMNEXT_ID 1
|
||||
#define CLMNPATH_ID 2
|
||||
#define SEP_POS 3
|
||||
#define LVGROUPS_ID 4
|
||||
|
||||
COLORREF VerticalFileSwitcher::_bgColor = 0xFFFFFF;
|
||||
|
||||
int CALLBACK ListViewCompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
|
||||
{
|
||||
|
@ -83,6 +87,180 @@ void VerticalFileSwitcher::startColumnSort()
|
|||
updateHeaderArrow();
|
||||
}
|
||||
|
||||
LRESULT VerticalFileSwitcher::listViewNotifyCustomDraw(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
auto lplvcd = reinterpret_cast<LPNMLVCUSTOMDRAW>(lParam);
|
||||
|
||||
switch (lplvcd->nmcd.dwDrawStage)
|
||||
{
|
||||
case CDDS_PREPAINT:
|
||||
{
|
||||
if ((lplvcd->dwItemType == LVCDI_GROUP) && NppDarkMode::isThemeDark())
|
||||
{
|
||||
RECT rcHeader{};
|
||||
ListView_GetGroupRect(lplvcd->nmcd.hdr.hwndFrom, lplvcd->nmcd.dwItemSpec, LVGGR_HEADER, &rcHeader);
|
||||
|
||||
HBRUSH hBrush = ::CreateSolidBrush(VerticalFileSwitcher::_bgColor);
|
||||
::FillRect(lplvcd->nmcd.hdc, &rcHeader, hBrush);
|
||||
::DeleteObject(hBrush);
|
||||
hBrush = nullptr;
|
||||
}
|
||||
return CDRF_NOTIFYITEMDRAW;
|
||||
}
|
||||
|
||||
case CDDS_ITEMPREPAINT:
|
||||
{
|
||||
const RECT& rcRow = lplvcd->nmcd.rc;
|
||||
|
||||
const bool isThemeDark = NppDarkMode::isThemeDark();
|
||||
|
||||
const auto hHeader = ListView_GetHeader(lplvcd->nmcd.hdr.hwndFrom);
|
||||
const auto colCount = Header_GetItemCount(hHeader);
|
||||
|
||||
const LONG paddingLeft = isThemeDark ? 1 : 0;
|
||||
const LONG paddingRight = isThemeDark ? 2 : 1;
|
||||
|
||||
RECT rcSubItem{ rcRow };
|
||||
RECT rcSubItem2{};
|
||||
RECT rcSubItem3{};
|
||||
|
||||
rcSubItem.right -= paddingRight;
|
||||
|
||||
auto setRectForSubItem = [hHeader, paddingLeft, paddingRight](RECT& first, RECT& second, int idxSecond) -> void {
|
||||
Header_GetItemRect(hHeader, idxSecond, &second);
|
||||
first.right = second.left - paddingRight;
|
||||
|
||||
second.left -= paddingLeft;
|
||||
second.right -= paddingRight;
|
||||
second.top = first.top;
|
||||
second.bottom = first.bottom;
|
||||
};
|
||||
|
||||
if (colCount >= 2)
|
||||
{
|
||||
setRectForSubItem(rcSubItem, rcSubItem2, 1);
|
||||
}
|
||||
|
||||
if (colCount == 3)
|
||||
{
|
||||
setRectForSubItem(rcSubItem2, rcSubItem3, 2);
|
||||
}
|
||||
|
||||
const auto isSelected = ListView_GetItemState(lplvcd->nmcd.hdr.hwndFrom, lplvcd->nmcd.dwItemSpec, LVIS_SELECTED) == LVIS_SELECTED;
|
||||
const bool isHot = (lplvcd->nmcd.uItemState & CDIS_HOT) == CDIS_HOT;
|
||||
const int colorID = reinterpret_cast<TaskLstFnStatus*>(lplvcd->nmcd.lItemlParam)->_docColor;
|
||||
|
||||
COLORREF bgColor{0xFFFFFF};
|
||||
bool applyColor = false;
|
||||
|
||||
if (colorID != -1)
|
||||
{
|
||||
bgColor = NppDarkMode::getIndividualTabColour(colorID, isThemeDark, false);
|
||||
applyColor = true;
|
||||
}
|
||||
else if (isThemeDark)
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
bgColor = NppDarkMode::getSofterBackgroundColor();
|
||||
applyColor = true;
|
||||
}
|
||||
else if (isHot)
|
||||
{
|
||||
bgColor = NppDarkMode::getHotBackgroundColor();
|
||||
applyColor = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (applyColor)
|
||||
{
|
||||
if (isThemeDark)
|
||||
{
|
||||
lplvcd->clrText = NppDarkMode::getTextColor();
|
||||
}
|
||||
|
||||
lplvcd->clrTextBk = bgColor;
|
||||
|
||||
HBRUSH hBrush = ::CreateSolidBrush(bgColor);
|
||||
|
||||
::FillRect(lplvcd->nmcd.hdc, &rcSubItem, hBrush);
|
||||
if (colCount >= 2)
|
||||
{
|
||||
::FillRect(lplvcd->nmcd.hdc, &rcSubItem2, hBrush);
|
||||
}
|
||||
if (colCount == 3)
|
||||
{
|
||||
::FillRect(lplvcd->nmcd.hdc, &rcSubItem3, hBrush);
|
||||
}
|
||||
|
||||
::DeleteObject(hBrush);
|
||||
hBrush = nullptr;
|
||||
}
|
||||
|
||||
if (isSelected)
|
||||
{
|
||||
::DrawFocusRect(lplvcd->nmcd.hdc, &rcRow);
|
||||
}
|
||||
else if (isHot)
|
||||
{
|
||||
::FrameRect(lplvcd->nmcd.hdc, &rcRow, isThemeDark ? NppDarkMode::getHotEdgeBrush() : ::GetSysColorBrush(COLOR_WINDOWTEXT));
|
||||
}
|
||||
|
||||
return CDRF_NEWFONT;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ::DefSubclassProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK VerticalFileSwitcher::FileSwitcherNotifySubclass(
|
||||
HWND hWnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
UINT_PTR uIdSubclass,
|
||||
DWORD_PTR /*dwRefData*/
|
||||
)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_NCDESTROY:
|
||||
{
|
||||
::RemoveWindowSubclass(hWnd, VerticalFileSwitcher::FileSwitcherNotifySubclass, uIdSubclass);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
auto nmhdr = reinterpret_cast<LPNMHDR>(lParam);
|
||||
switch (nmhdr->code)
|
||||
{
|
||||
case NM_CUSTOMDRAW:
|
||||
{
|
||||
constexpr size_t classNameLen = 16;
|
||||
wchar_t className[classNameLen]{};
|
||||
GetClassName(nmhdr->hwndFrom, className, classNameLen);
|
||||
|
||||
if (wcscmp(className, WC_LISTVIEW) == 0)
|
||||
{
|
||||
return VerticalFileSwitcher::listViewNotifyCustomDraw(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
void VerticalFileSwitcher::autoSubclassWindowNotify(HWND hParent)
|
||||
{
|
||||
::SetWindowSubclass(hParent, VerticalFileSwitcher::FileSwitcherNotifySubclass, _fileSwitcherNotifySubclassID, 0);
|
||||
}
|
||||
|
||||
intptr_t CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
|
@ -99,7 +277,7 @@ intptr_t CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam,
|
|||
_defaultListViewProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(_fileListView.getHSelf(), GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(listViewStaticProc)));
|
||||
|
||||
NppDarkMode::autoSubclassAndThemeChildControls(_hSelf);
|
||||
NppDarkMode::autoSubclassAndThemeWindowNotify(_hSelf);
|
||||
VerticalFileSwitcher::autoSubclassWindowNotify(_hSelf);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -222,7 +400,7 @@ intptr_t CALLBACK VerticalFileSwitcher::run_dlgProc(UINT message, WPARAM wParam,
|
|||
{
|
||||
// Redirect NM_RCLICK message to Notepad_plus handle
|
||||
NMHDR nmhdr{};
|
||||
nmhdr.code = NM_RCLICK;
|
||||
nmhdr.code = reinterpret_cast<LPNMHDR>(lParam)->code; //NM_RCLICK
|
||||
nmhdr.hwndFrom = _hSelf;
|
||||
nmhdr.idFrom = ::GetDlgCtrlID(nmhdr.hwndFrom);
|
||||
::SendMessage(_hParent, WM_NOTIFY, nmhdr.idFrom, reinterpret_cast<LPARAM>(&nmhdr));
|
||||
|
@ -357,15 +535,20 @@ void VerticalFileSwitcher::initPopupMenus()
|
|||
|
||||
generic_string extStr = pNativeSpeaker->getAttrNameStr(TEXT("Ext."), FS_ROOTNODE, FS_CLMNEXT);
|
||||
generic_string pathStr = pNativeSpeaker->getAttrNameStr(TEXT("Path"), FS_ROOTNODE, FS_CLMNPATH);
|
||||
generic_string groupStr = pNativeSpeaker->getAttrNameStr(TEXT("Group by View"), FS_ROOTNODE, FS_LVGROUPS);
|
||||
|
||||
_hGlobalMenu = ::CreatePopupMenu();
|
||||
::InsertMenu(_hGlobalMenu, 0, MF_BYCOMMAND, CLMNEXT_ID, extStr.c_str());
|
||||
::InsertMenu(_hGlobalMenu, 0, MF_BYCOMMAND, CLMNPATH_ID, pathStr.c_str());
|
||||
::InsertMenu(_hGlobalMenu, CLMNEXT_ID, MF_BYCOMMAND | MF_STRING, CLMNEXT_ID, extStr.c_str());
|
||||
::InsertMenu(_hGlobalMenu, CLMNPATH_ID, MF_BYCOMMAND | MF_STRING, CLMNPATH_ID, pathStr.c_str());
|
||||
::InsertMenu(_hGlobalMenu, SEP_POS, MF_BYCOMMAND | MF_SEPARATOR, 0, nullptr);
|
||||
::InsertMenu(_hGlobalMenu, LVGROUPS_ID, MF_BYCOMMAND | MF_STRING, LVGROUPS_ID, groupStr.c_str());
|
||||
|
||||
bool isExtColumn = nppGUI._fileSwitcherWithoutExtColumn;
|
||||
::CheckMenuItem(_hGlobalMenu, CLMNEXT_ID, MF_BYCOMMAND | (isExtColumn ? MF_UNCHECKED : MF_CHECKED));
|
||||
bool isPathColumn = nppGUI._fileSwitcherWithoutPathColumn;
|
||||
::CheckMenuItem(_hGlobalMenu, CLMNPATH_ID, MF_BYCOMMAND | (isPathColumn ? MF_UNCHECKED : MF_CHECKED));
|
||||
bool isListViewGroups = nppGUI._fileSwitcherDisableListViewGroups;
|
||||
::CheckMenuItem(_hGlobalMenu, LVGROUPS_ID, MF_BYCOMMAND | (isListViewGroups ? MF_UNCHECKED : MF_CHECKED));
|
||||
}
|
||||
|
||||
void VerticalFileSwitcher::popupMenuCmd(int cmdID)
|
||||
|
@ -388,6 +571,14 @@ void VerticalFileSwitcher::popupMenuCmd(int cmdID)
|
|||
reload();
|
||||
}
|
||||
break;
|
||||
case LVGROUPS_ID:
|
||||
{
|
||||
bool& isListViewGroups = NppParameters::getInstance().getNppGUI()._fileSwitcherDisableListViewGroups;
|
||||
isListViewGroups = !isListViewGroups;
|
||||
::CheckMenuItem(_hGlobalMenu, LVGROUPS_ID, MF_BYCOMMAND | (isListViewGroups ? MF_UNCHECKED : MF_CHECKED));
|
||||
reload();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,10 @@ public:
|
|||
_fileListView.setItemIconStatus(bufferID) ;
|
||||
};
|
||||
|
||||
void setItemColor(BufferID bufferID) {
|
||||
_fileListView.setItemColor(bufferID);
|
||||
};
|
||||
|
||||
generic_string getFullFilePath(size_t i) const {
|
||||
return _fileListView.getFullFilePath(i);
|
||||
};
|
||||
|
@ -97,7 +101,33 @@ public:
|
|||
|
||||
virtual void setBackgroundColor(COLORREF bgColour) {
|
||||
_fileListView.setBackgroundColor(bgColour);
|
||||
};
|
||||
|
||||
auto r = GetRValue(bgColour);
|
||||
auto g = GetGValue(bgColour);
|
||||
auto b = GetBValue(bgColour);
|
||||
|
||||
constexpr int luminenceIncrementBy = 333; // 33.3 %
|
||||
|
||||
// main color is blue
|
||||
// but difference must be high
|
||||
// can have similar blue color as header
|
||||
constexpr int difference = 12;
|
||||
const auto bAdjusted = static_cast<BYTE>(std::max<int>(0, static_cast<int>(b) - difference));
|
||||
if (bAdjusted > r && bAdjusted > g)
|
||||
{
|
||||
// using values from NppDarkMode.cpp
|
||||
// from double calculatePerceivedLighness(COLORREF c)
|
||||
// double luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
// values multiplied by 1024 and then shift result by 10 - "fake" divide by 1024
|
||||
// for performance
|
||||
const auto grayscale = static_cast<BYTE>((r * 218 + g * 732 + b * 74) >> 10);
|
||||
_bgColor = ::ColorAdjustLuma(RGB(grayscale, grayscale, grayscale), luminenceIncrementBy, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_bgColor = ::ColorAdjustLuma(bgColour, luminenceIncrementBy, TRUE);
|
||||
}
|
||||
};
|
||||
|
||||
virtual void setForegroundColor(COLORREF fgColour) {
|
||||
_fileListView.setForegroundColor(fgColour);
|
||||
|
@ -108,8 +138,6 @@ protected:
|
|||
void initPopupMenus();
|
||||
void popupMenuCmd(int cmdID);
|
||||
|
||||
|
||||
|
||||
static LRESULT CALLBACK listViewStaticProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
const auto dlg = (VerticalFileSwitcher*)(::GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||
return (run_listViewProc(dlg->_defaultListViewProc, hwnd, message, wParam, lParam));
|
||||
|
@ -121,4 +149,10 @@ private:
|
|||
VerticalFileSwitcherListView _fileListView;
|
||||
HIMAGELIST _hImaLst = nullptr;
|
||||
WNDPROC _defaultListViewProc = nullptr;
|
||||
|
||||
static COLORREF _bgColor;
|
||||
static const UINT_PTR _fileSwitcherNotifySubclassID = 42;
|
||||
static LRESULT listViewNotifyCustomDraw(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
static LRESULT CALLBACK FileSwitcherNotifySubclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
|
||||
void autoSubclassWindowNotify(HWND hParent);
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@ void VerticalFileSwitcherListView::init(HINSTANCE hInst, HWND parent, HIMAGELIST
|
|||
|
||||
// Create the list-view window in report view with label editing enabled.
|
||||
int listViewStyles = LVS_REPORT /*| LVS_SINGLESEL*/ | LVS_AUTOARRANGE\
|
||||
| LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS;
|
||||
| LVS_SHAREIMAGELISTS | LVS_SHOWSELALWAYS | LVS_ALIGNTOP;
|
||||
|
||||
_hSelf = ::CreateWindow(WC_LISTVIEW,
|
||||
TEXT(""),
|
||||
|
@ -54,6 +54,22 @@ void VerticalFileSwitcherListView::init(HINSTANCE hInst, HWND parent, HIMAGELIST
|
|||
ListView_SetExtendedListViewStyle(_hSelf, LVS_EX_FULLROWSELECT | LVS_EX_BORDERSELECT | LVS_EX_INFOTIP | LVS_EX_DOUBLEBUFFER);
|
||||
ListView_SetItemCountEx(_hSelf, 50, LVSICF_NOSCROLL);
|
||||
ListView_SetImageList(_hSelf, _hImaLst, LVSIL_SMALL);
|
||||
|
||||
LVGROUP group{};
|
||||
constexpr size_t headerLen = 1;
|
||||
wchar_t header[headerLen] = L"";
|
||||
group.cbSize = sizeof(LVGROUP);
|
||||
group.mask = LVGF_HEADER | LVGF_GROUPID | LVGF_STATE;
|
||||
group.pszHeader = header;
|
||||
group.cchHeader = headerLen;
|
||||
group.iGroupId = _groupID;
|
||||
group.state = LVGS_COLLAPSIBLE;
|
||||
|
||||
LVGROUP group2 = group;
|
||||
group2.iGroupId = _group2ID;
|
||||
|
||||
ListView_InsertGroup(_hSelf, -1, &group);
|
||||
ListView_InsertGroup(_hSelf, -1, &group2);
|
||||
}
|
||||
|
||||
void VerticalFileSwitcherListView::destroy()
|
||||
|
@ -77,6 +93,9 @@ void VerticalFileSwitcherListView::initList()
|
|||
NppParameters& nppParams = NppParameters::getInstance();
|
||||
NativeLangSpeaker *pNativeSpeaker = nppParams.getNativeLangSpeaker();
|
||||
|
||||
const bool isListViewGroups = !nppParams.getNppGUI()._fileSwitcherDisableListViewGroups;
|
||||
ListView_EnableGroupView(_hSelf, isListViewGroups ? TRUE : FALSE);
|
||||
|
||||
bool isExtColumn = !nppParams.getNppGUI()._fileSwitcherWithoutExtColumn;
|
||||
bool isPathColumn = !nppParams.getNppGUI()._fileSwitcherWithoutPathColumn;
|
||||
|
||||
|
@ -111,7 +130,7 @@ void VerticalFileSwitcherListView::initList()
|
|||
{
|
||||
TaskLstFnStatus & fileNameStatus = taskListInfo._tlfsLst[i];
|
||||
|
||||
TaskLstFnStatus *tl = new TaskLstFnStatus(fileNameStatus._iView, fileNameStatus._docIndex, fileNameStatus._fn, fileNameStatus._status, (void *)fileNameStatus._bufID);
|
||||
TaskLstFnStatus *tl = new TaskLstFnStatus(fileNameStatus);
|
||||
|
||||
TCHAR fn[MAX_PATH] = { '\0' };
|
||||
wcscpy_s(fn, ::PathFindFileName(fileNameStatus._fn.c_str()));
|
||||
|
@ -121,13 +140,14 @@ void VerticalFileSwitcherListView::initList()
|
|||
::PathRemoveExtension(fn);
|
||||
}
|
||||
LVITEM item{};
|
||||
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
||||
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_GROUPID;
|
||||
|
||||
item.pszText = fn;
|
||||
item.iItem = static_cast<int32_t>(i);
|
||||
item.iSubItem = 0;
|
||||
item.iImage = fileNameStatus._status;
|
||||
item.lParam = reinterpret_cast<LPARAM>(tl);
|
||||
item.iGroupId = (fileNameStatus._iView == MAIN_VIEW) ? _groupID : _group2ID;
|
||||
ListView_InsertItem(_hSelf, &item);
|
||||
int colIndex = 0;
|
||||
if (isExtColumn)
|
||||
|
@ -229,6 +249,30 @@ void VerticalFileSwitcherListView::setItemIconStatus(BufferID bufferID)
|
|||
}
|
||||
}
|
||||
|
||||
void VerticalFileSwitcherListView::setItemColor(BufferID bufferID)
|
||||
{
|
||||
Buffer* buf = static_cast<Buffer*>(bufferID);
|
||||
|
||||
LVITEM item{};
|
||||
item.mask = LVIF_PARAM;
|
||||
|
||||
int nbItem = ListView_GetItemCount(_hSelf);
|
||||
|
||||
for (int i = 0; i < nbItem; ++i)
|
||||
{
|
||||
item.iItem = i;
|
||||
ListView_GetItem(_hSelf, &item);
|
||||
TaskLstFnStatus* tlfs = reinterpret_cast<TaskLstFnStatus*>(item.lParam);
|
||||
if (tlfs->_bufID == bufferID)
|
||||
{
|
||||
tlfs->_docColor = buf->getDocColorId();
|
||||
ListView_SetItem(_hSelf, &item);
|
||||
}
|
||||
}
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
generic_string VerticalFileSwitcherListView::getFullFilePath(size_t i) const
|
||||
{
|
||||
size_t nbItem = ListView_GetItemCount(_hSelf);
|
||||
|
@ -270,7 +314,7 @@ int VerticalFileSwitcherListView::add(BufferID bufferID, int iView)
|
|||
Buffer *buf = static_cast<Buffer *>(bufferID);
|
||||
const TCHAR *fileName = buf->getFileName();
|
||||
NppGUI& nppGUI = NppParameters::getInstance().getNppGUI();
|
||||
TaskLstFnStatus *tl = new TaskLstFnStatus(iView, 0, buf->getFullPathName(), 0, (void *)bufferID);
|
||||
TaskLstFnStatus *tl = new TaskLstFnStatus(iView, 0, buf->getFullPathName(), 0, (void *)bufferID, -1);
|
||||
|
||||
TCHAR fn[MAX_PATH] = { '\0' };
|
||||
wcscpy_s(fn, ::PathFindFileName(fileName));
|
||||
|
@ -281,13 +325,14 @@ int VerticalFileSwitcherListView::add(BufferID bufferID, int iView)
|
|||
::PathRemoveExtension(fn);
|
||||
}
|
||||
LVITEM item{};
|
||||
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
|
||||
item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_GROUPID;
|
||||
|
||||
item.pszText = fn;
|
||||
item.iItem = _currentIndex;
|
||||
item.iSubItem = 0;
|
||||
item.iImage = buf->isMonitoringOn()?3:(buf->isReadOnly()?2:(buf->isDirty()?1:0));
|
||||
item.lParam = reinterpret_cast<LPARAM>(tl);
|
||||
item.iGroupId = (iView == MAIN_VIEW) ? _groupID : _group2ID;
|
||||
ListView_InsertItem(_hSelf, &item);
|
||||
int colIndex = 0;
|
||||
if (isExtColumn)
|
||||
|
|
|
@ -31,6 +31,7 @@ typedef Buffer * BufferID; //each buffer has unique ID by which it can be retrie
|
|||
#define FS_CLMNNAME "ColumnName"
|
||||
#define FS_CLMNEXT "ColumnExt"
|
||||
#define FS_CLMNPATH "ColumnPath"
|
||||
#define FS_LVGROUPS "ListGroups"
|
||||
|
||||
struct SwitcherFileInfo {
|
||||
BufferID _bufID = 0;
|
||||
|
@ -58,6 +59,7 @@ public:
|
|||
void activateItem(BufferID bufferID, int iView);
|
||||
void setItemIconStatus(BufferID bufferID);
|
||||
generic_string getFullFilePath(size_t i) const;
|
||||
void setItemColor(BufferID bufferID);
|
||||
|
||||
void insertColumn(const TCHAR *name, int width, int index);
|
||||
void resizeColumns(int totalWidth);
|
||||
|
@ -90,6 +92,9 @@ protected:
|
|||
|
||||
int _currentIndex = 0;
|
||||
|
||||
static const int _groupID = 1;
|
||||
static const int _group2ID = 2;
|
||||
|
||||
int find(BufferID bufferID, int iView) const;
|
||||
int add(BufferID bufferID, int iView);
|
||||
void remove(int index);
|
||||
|
|
Loading…
Reference in New Issue