diff options
author | George Hazan <george.hazan@gmail.com> | 2015-05-14 14:04:35 +0000 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2015-05-14 14:04:35 +0000 |
commit | c13c0b52d24fa6d2c82287aa418f5daaf0fb099b (patch) | |
tree | 11dc0831f0ad6954b7432dab34623a74b6a68979 /src/mir_core | |
parent | 4bae0d71fcc3580f253dc82c98c1120f62b90df2 (diff) |
multiselect mode for CCtrlTreeView
git-svn-id: http://svn.miranda-ng.org/main/trunk@13586 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src/mir_core')
-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 |
3 files changed, 250 insertions, 58 deletions
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);
}
|