diff options
-rw-r--r-- | bin10/lib/mir_core.lib | bin | 329110 -> 332978 bytes | |||
-rw-r--r-- | bin10/lib/mir_core64.lib | bin | 330886 -> 334850 bytes | |||
-rw-r--r-- | bin12/lib/mir_core.lib | bin | 329110 -> 332978 bytes | |||
-rw-r--r-- | bin12/lib/mir_core64.lib | bin | 330886 -> 334850 bytes | |||
-rw-r--r-- | include/m_gui.h | 21 | ||||
-rw-r--r-- | src/mir_core/src/mir_core.def | 11 | ||||
-rw-r--r-- | src/mir_core/src/mir_core64.def | 11 | ||||
-rw-r--r-- | src/mir_core/src/ui_utils.cpp | 286 |
8 files changed, 269 insertions, 60 deletions
diff --git a/bin10/lib/mir_core.lib b/bin10/lib/mir_core.lib Binary files differindex d9e8ea1ccc..bdba1abafd 100644 --- a/bin10/lib/mir_core.lib +++ b/bin10/lib/mir_core.lib diff --git a/bin10/lib/mir_core64.lib b/bin10/lib/mir_core64.lib Binary files differindex f1c6d9b262..999d4f4d8a 100644 --- a/bin10/lib/mir_core64.lib +++ b/bin10/lib/mir_core64.lib diff --git a/bin12/lib/mir_core.lib b/bin12/lib/mir_core.lib Binary files differindex 5be659bc2f..b8da425695 100644 --- a/bin12/lib/mir_core.lib +++ b/bin12/lib/mir_core.lib diff --git a/bin12/lib/mir_core64.lib b/bin12/lib/mir_core64.lib Binary files differindex 1b693720d2..999d4f4d8a 100644 --- a/bin12/lib/mir_core64.lib +++ b/bin12/lib/mir_core64.lib diff --git a/include/m_gui.h b/include/m_gui.h index 89393d0be7..e86bf71acc 100644 --- a/include/m_gui.h +++ b/include/m_gui.h @@ -851,8 +851,9 @@ protected: #undef GetNextSibling
#undef GetPrevSibling
-#define MTREE_CHECKBOX 0x0001
-#define MTREE_DND 0x0002
+#define MTREE_CHECKBOX 0x0001
+#define MTREE_DND 0x0002
+#define MTREE_MULTISELECT 0x0004
class MIR_CORE_EXPORT CCtrlTreeView : public CCtrlBase
{
@@ -931,6 +932,21 @@ public: void GetItem(HTREEITEM hItem, TVITEMEX *tvi, TCHAR *szText, int iTextLength);
void InvertCheck(HTREEITEM hItem);
+ bool IsSelected(HTREEITEM hItem);
+ int GetNumSelected();
+ void GetSelected(LIST<_TREEITEM> &selected);
+
+ void Select(HTREEITEM hItem);
+ void Select(LIST<_TREEITEM> &selected);
+ void SelectAll();
+ void SelectRange(HTREEITEM hStart, HTREEITEM hEnd);
+
+ void Unselect(HTREEITEM hItem);
+ void UnselectAll();
+
+ void DropHilite(HTREEITEM hItem);
+ void DropUnhilite(HTREEITEM hItem);
+
// Events
struct TEventInfo {
CCtrlTreeView *treeviewctrl;
@@ -970,6 +986,7 @@ protected: bool m_bDndEnabled : 1;
bool m_bDragging : 1;
bool m_bCheckBox : 1;
+ bool m_bMultiSelect : 1;
};
};
HTREEITEM m_hDragItem; // valid if m_bDragging == true
diff --git a/src/mir_core/src/mir_core.def b/src/mir_core/src/mir_core.def index 058d980505..d59ce8407b 100644 --- a/src/mir_core/src/mir_core.def +++ b/src/mir_core/src/mir_core.def @@ -1079,3 +1079,14 @@ Proto_RegisterModule @1074 NONAME ?SetFlags@CCtrlTreeView@@QAEXI@Z @1080 NONAME
?CustomWndProc@CCtrlTreeView@@MAEJIIJ@Z @1081 NONAME
?OnInit@CCtrlTreeView@@MAEXXZ @1082 NONAME
+?DropHilite@CCtrlTreeView@@QAEXPAU_TREEITEM@@@Z @1083 NONAME
+?DropUnhilite@CCtrlTreeView@@QAEXPAU_TREEITEM@@@Z @1084 NONAME
+?GetNumSelected@CCtrlTreeView@@QAEHXZ @1085 NONAME
+?GetSelected@CCtrlTreeView@@QAEXAAU?$LIST@U_TREEITEM@@@@@Z @1086 NONAME
+?IsSelected@CCtrlTreeView@@QAE_NPAU_TREEITEM@@@Z @1087 NONAME
+?Select@CCtrlTreeView@@QAEXAAU?$LIST@U_TREEITEM@@@@@Z @1088 NONAME
+?Select@CCtrlTreeView@@QAEXPAU_TREEITEM@@@Z @1089 NONAME
+?SelectAll@CCtrlTreeView@@QAEXXZ @1090 NONAME
+?SelectRange@CCtrlTreeView@@QAEXPAU_TREEITEM@@0@Z @1091 NONAME
+?Unselect@CCtrlTreeView@@QAEXPAU_TREEITEM@@@Z @1092 NONAME
+?UnselectAll@CCtrlTreeView@@QAEXXZ @1093 NONAME
diff --git a/src/mir_core/src/mir_core64.def b/src/mir_core/src/mir_core64.def index 0efcff15f5..67bbf17e90 100644 --- a/src/mir_core/src/mir_core64.def +++ b/src/mir_core/src/mir_core64.def @@ -1079,3 +1079,14 @@ Proto_RegisterModule @1074 NONAME ?SetFlags@CCtrlTreeView@@QEAAXI@Z @1080 NONAME
?CustomWndProc@CCtrlTreeView@@MEAA_JI_K_J@Z @1081 NONAME
?OnInit@CCtrlTreeView@@MEAAXXZ @1082 NONAME
+?DropHilite@CCtrlTreeView@@QEAAXPEAU_TREEITEM@@@Z @1083 NONAME
+?DropUnhilite@CCtrlTreeView@@QEAAXPEAU_TREEITEM@@@Z @1084 NONAME
+?GetNumSelected@CCtrlTreeView@@QEAAHXZ @1085 NONAME
+?GetSelected@CCtrlTreeView@@QEAAXAEAU?$LIST@U_TREEITEM@@@@@Z @1086 NONAME
+?IsSelected@CCtrlTreeView@@QEAA_NPEAU_TREEITEM@@@Z @1087 NONAME
+?Select@CCtrlTreeView@@QEAAXAEAU?$LIST@U_TREEITEM@@@@@Z @1088 NONAME
+?Select@CCtrlTreeView@@QEAAXPEAU_TREEITEM@@@Z @1089 NONAME
+?SelectAll@CCtrlTreeView@@QEAAXXZ @1090 NONAME
+?SelectRange@CCtrlTreeView@@QEAAXPEAU_TREEITEM@@0@Z @1091 NONAME
+?Unselect@CCtrlTreeView@@QEAAXPEAU_TREEITEM@@@Z @1092 NONAME
+?UnselectAll@CCtrlTreeView@@QEAAXXZ @1093 NONAME
diff --git a/src/mir_core/src/ui_utils.cpp b/src/mir_core/src/ui_utils.cpp index 99124df0d0..d045182de1 100644 --- a/src/mir_core/src/ui_utils.cpp +++ b/src/mir_core/src/ui_utils.cpp @@ -1375,6 +1375,9 @@ void CCtrlTreeView::SetFlags(uint32_t dwFlags) if (dwFlags & MTREE_CHECKBOX)
m_bCheckBox = true;
+ if (dwFlags & MTREE_MULTISELECT)
+ m_bMultiSelect = true;
+
if (dwFlags & MTREE_DND) {
m_bDndEnabled = true;
m_bDragging = false;
@@ -1396,76 +1399,132 @@ LRESULT CCtrlTreeView::CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) {
case WM_MOUSEMOVE:
- if (!m_bDragging)
- break;
-
- hti.pt.x = (short)LOWORD(lParam);
- hti.pt.y = (short)HIWORD(lParam);
- HitTest(&hti);
- if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) {
- HTREEITEM it = hti.hItem;
- hti.pt.y -= GetItemHeight() / 2;
+ if (m_bDragging) {
+ hti.pt.x = (short)LOWORD(lParam);
+ hti.pt.y = (short)HIWORD(lParam);
HitTest(&hti);
- if (!(hti.flags & TVHT_ABOVE))
- SetInsertMark(hti.hItem, 1);
- else
- SetInsertMark(it, 0);
+ if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) {
+ HTREEITEM it = hti.hItem;
+ hti.pt.y -= GetItemHeight() / 2;
+ HitTest(&hti);
+ if (!(hti.flags & TVHT_ABOVE))
+ SetInsertMark(hti.hItem, 1);
+ else
+ SetInsertMark(it, 0);
+ }
+ else {
+ if (hti.flags & TVHT_ABOVE) SendMsg(WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0);
+ if (hti.flags & TVHT_BELOW) SendMsg(WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0);
+ SetInsertMark(NULL, 0);
+ }
}
- else {
- if (hti.flags & TVHT_ABOVE) SendMsg(WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0);
- if (hti.flags & TVHT_BELOW) SendMsg(WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0);
+ break;
+
+ case WM_LBUTTONUP:
+ if (m_bDragging) {
SetInsertMark(NULL, 0);
+ m_bDragging = 0;
+ ReleaseCapture();
+
+ hti.pt.x = (short)LOWORD(lParam);
+ hti.pt.y = (short)HIWORD(lParam) - GetItemHeight() / 2;
+ HitTest(&hti);
+ if (m_hDragItem == hti.hItem)
+ break;
+
+ if (hti.flags & TVHT_ABOVE)
+ hti.hItem = TVI_FIRST;
+ else if (hti.flags & TVHT_BELOW)
+ hti.hItem = TVI_LAST;
+
+ TVITEMEX tvi;
+ tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_IMAGE;
+ tvi.hItem = m_hDragItem;
+ GetItem(&tvi);
+ if ((hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) || hti.hItem == TVI_FIRST) {
+ TCHAR name[128];
+ TVINSERTSTRUCT tvis = { 0 };
+ tvis.itemex.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ tvis.itemex.stateMask = 0xFFFFFFFF;
+ tvis.itemex.pszText = name;
+ tvis.itemex.cchTextMax = SIZEOF(name);
+ tvis.itemex.hItem = m_hDragItem;
+ tvis.itemex.iImage = tvis.itemex.iSelectedImage = tvi.iImage;
+ GetItem(&tvis.itemex);
+
+ // the pointed lParam will be freed inside TVN_DELETEITEM
+ // so lets substitute it with 0
+ LPARAM saveOldData = tvis.itemex.lParam;
+ tvis.itemex.lParam = 0;
+ SetItem(&tvis.itemex);
+
+ // now current item contain lParam = 0 we can delete it. the memory will be kept.
+ tvis.itemex.lParam = saveOldData;
+ DeleteItem(m_hDragItem);
+
+ tvis.hParent = NULL;
+ tvis.hInsertAfter = hti.hItem;
+ SelectItem(InsertItem(&tvis));
+
+ NotifyChange();
+ }
}
break;
- case WM_LBUTTONUP:
- if (!m_bDragging)
+ case WM_LBUTTONDOWN:
+ if (!m_bMultiSelect)
break;
- SetInsertMark(NULL, 0);
- m_bDragging = 0;
- ReleaseCapture();
-
hti.pt.x = (short)LOWORD(lParam);
- hti.pt.y = (short)HIWORD(lParam) - GetItemHeight() / 2;
- HitTest(&hti);
- if (m_hDragItem == hti.hItem)
+ hti.pt.y = (short)HIWORD(lParam);
+ if (!TreeView_HitTest(m_hwnd, &hti)) {
+ UnselectAll();
break;
- if (hti.flags & TVHT_ABOVE)
- hti.hItem = TVI_FIRST;
+ }
- TVITEMEX tvi;
- tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_IMAGE;
- tvi.hItem = m_hDragItem;
- GetItem(&tvi);
- if ((hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) || hti.hItem == TVI_FIRST) {
- TCHAR name[128];
- TVINSERTSTRUCT tvis = { 0 };
- tvis.itemex.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
- tvis.itemex.stateMask = 0xFFFFFFFF;
- tvis.itemex.pszText = name;
- tvis.itemex.cchTextMax = SIZEOF(name);
- tvis.itemex.hItem = m_hDragItem;
- tvis.itemex.iImage = tvis.itemex.iSelectedImage = tvi.iImage;
- GetItem(&tvis.itemex);
-
- // the pointed lParam will be freed inside TVN_DELETEITEM
- // so lets substitute it with 0
- LPARAM saveOldData = tvis.itemex.lParam;
- tvis.itemex.lParam = 0;
- SetItem(&tvis.itemex);
-
- // now current item contain lParam = 0 we can delete it. the memory will be kept.
- tvis.itemex.lParam = saveOldData;
- DeleteItem(m_hDragItem);
-
- tvis.hParent = NULL;
- tvis.hInsertAfter = hti.hItem;
- SelectItem(InsertItem(&tvis));
-
- NotifyChange();
+ if (!(wParam & (MK_CONTROL | MK_SHIFT)) || !(hti.flags & (TVHT_ONITEMICON | TVHT_ONITEMLABEL | TVHT_ONITEMRIGHT))) {
+ UnselectAll();
+ TreeView_SelectItem(m_hwnd, hti.hItem);
+ break;
}
- break;
+
+ if (wParam & MK_CONTROL) {
+ LIST<_TREEITEM> selected(1);
+ GetSelected(selected);
+
+ // Check if have to deselect it
+ for (int i = 0; i < selected.getCount(); i++) {
+ if (selected[i] == hti.hItem) {
+ // Deselect it
+ UnselectAll();
+ selected.remove(i);
+
+ if (i > 0)
+ hti.hItem = selected[0];
+ else if (i < selected.getCount())
+ hti.hItem = selected[i];
+ else
+ hti.hItem = NULL;
+ break;
+ }
+ }
+
+ TreeView_SelectItem(m_hwnd, hti.hItem);
+ Select(selected);
+ }
+ else if (wParam & MK_SHIFT) {
+ HTREEITEM hItem = TreeView_GetSelection(m_hwnd);
+ if (hItem == NULL)
+ break;
+
+ LIST<_TREEITEM> selected(1);
+ GetSelected(selected);
+
+ TreeView_SelectItem(m_hwnd, hti.hItem);
+ Select(selected);
+ SelectRange(hItem, hti.hItem);
+ }
+ return 0;
}
return CSuper::CustomWndProc(msg, wParam, lParam);
@@ -1615,6 +1674,117 @@ void CCtrlTreeView::GetItem(HTREEITEM hItem, TVITEMEX *tvi, TCHAR *szText, int i GetItem(tvi);
}
+bool CCtrlTreeView::IsSelected(HTREEITEM hItem)
+{
+ return (TVIS_SELECTED & TreeView_GetItemState(m_hwnd, hItem, TVIS_SELECTED)) == TVIS_SELECTED;
+}
+
+void CCtrlTreeView::Select(HTREEITEM hItem)
+{
+ TreeView_SetItemState(m_hwnd, hItem, TVIS_SELECTED, TVIS_SELECTED);
+}
+
+void CCtrlTreeView::Unselect(HTREEITEM hItem)
+{
+ TreeView_SetItemState(m_hwnd, hItem, 0, TVIS_SELECTED);
+}
+
+void CCtrlTreeView::DropHilite(HTREEITEM hItem)
+{
+ TreeView_SetItemState(m_hwnd, hItem, TVIS_DROPHILITED, TVIS_DROPHILITED);
+}
+
+void CCtrlTreeView::DropUnhilite(HTREEITEM hItem)
+{
+ TreeView_SetItemState(m_hwnd, hItem, 0, TVIS_DROPHILITED);
+}
+
+void CCtrlTreeView::SelectAll()
+{
+ TreeView_SelectItem(m_hwnd, NULL);
+
+ HTREEITEM hItem = TreeView_GetRoot(m_hwnd);
+ while (hItem) {
+ Select(hItem);
+ hItem = TreeView_GetNextSibling(m_hwnd, hItem);
+ }
+}
+
+void CCtrlTreeView::UnselectAll()
+{
+ TreeView_SelectItem(m_hwnd, NULL);
+
+ HTREEITEM hItem = TreeView_GetRoot(m_hwnd);
+ while (hItem) {
+ Unselect(hItem);
+ hItem = TreeView_GetNextSibling(m_hwnd, hItem);
+ }
+}
+
+void CCtrlTreeView::SelectRange(HTREEITEM hStart, HTREEITEM hEnd)
+{
+ int start = 0;
+ int end = 0;
+ int i = 0;
+ HTREEITEM hItem = TreeView_GetRoot(m_hwnd);
+ while (hItem) {
+ if (hItem == hStart)
+ start = i;
+ if (hItem == hEnd)
+ end = i;
+
+ i++;
+ hItem = TreeView_GetNextSibling(m_hwnd, hItem);
+ }
+
+ if (end < start) {
+ int tmp = start;
+ start = end;
+ end = tmp;
+ }
+
+ i = 0;
+ hItem = TreeView_GetRoot(m_hwnd);
+ while (hItem) {
+ if (i >= start)
+ Select(hItem);
+ if (i == end)
+ break;
+
+ i++;
+ hItem = TreeView_GetNextSibling(m_hwnd, hItem);
+ }
+}
+
+int CCtrlTreeView::GetNumSelected()
+{
+ int ret = 0;
+ for (HTREEITEM hItem = TreeView_GetRoot(m_hwnd); hItem; hItem = TreeView_GetNextSibling(m_hwnd, hItem))
+ if (IsSelected(hItem))
+ ret++;
+
+ return ret;
+}
+
+void CCtrlTreeView::GetSelected(LIST<_TREEITEM> &selected)
+{
+ HTREEITEM hItem = TreeView_GetRoot(m_hwnd);
+ while (hItem) {
+ if (IsSelected(hItem))
+ selected.insert(hItem);
+ hItem = TreeView_GetNextSibling(m_hwnd, hItem);
+ }
+}
+
+void CCtrlTreeView::Select(LIST<_TREEITEM> &selected)
+{
+ for (int i = 0; i < selected.getCount(); i++)
+ if (selected[i] != NULL)
+ Select(selected[i]);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
HIMAGELIST CCtrlTreeView::CreateDragImage(HTREEITEM hItem)
{ return TreeView_CreateDragImage(m_hwnd, hItem);
}
|