summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2015-05-13 00:09:14 +0000
committerGeorge Hazan <george.hazan@gmail.com>2015-05-13 00:09:14 +0000
commitfd54c1d33cf4d53c71f725484bf6963be0f1fd85 (patch)
treefecb8348b8cf934b95bf6460ffed8258c70aae16
parentf65a307b84288eabf54a8a337bb249aed5eee0ba (diff)
- MTREE_DND implemented, all drag-n-drop operations in trees went into the core;
- fixed chaos inside CCtrlBase::Subclass(); - two app dialogs switched to MTREE_DND; git-svn-id: http://svn.miranda-ng.org/main/trunk@13566 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--bin10/lib/mir_core.libbin328512 -> 329106 bytes
-rw-r--r--bin10/lib/mir_core64.libbin330264 -> 330882 bytes
-rw-r--r--bin12/lib/mir_core.libbin328512 -> 329106 bytes
-rw-r--r--bin12/lib/mir_core64.libbin330264 -> 330882 bytes
-rw-r--r--include/m_gui.h9
-rw-r--r--src/mir_core/src/ui_utils.cpp144
-rw-r--r--src/modules/clist/contacts.cpp85
-rw-r--r--src/modules/clist/protocolorder.cpp93
8 files changed, 133 insertions, 198 deletions
diff --git a/bin10/lib/mir_core.lib b/bin10/lib/mir_core.lib
index 5c42c3fcea..b5626ddaf2 100644
--- a/bin10/lib/mir_core.lib
+++ b/bin10/lib/mir_core.lib
Binary files differ
diff --git a/bin10/lib/mir_core64.lib b/bin10/lib/mir_core64.lib
index 076048fe5f..b90021e5dc 100644
--- a/bin10/lib/mir_core64.lib
+++ b/bin10/lib/mir_core64.lib
Binary files differ
diff --git a/bin12/lib/mir_core.lib b/bin12/lib/mir_core.lib
index bef3f2344e..ec60ffb43a 100644
--- a/bin12/lib/mir_core.lib
+++ b/bin12/lib/mir_core.lib
Binary files differ
diff --git a/bin12/lib/mir_core64.lib b/bin12/lib/mir_core64.lib
index 01adcae79d..11a84c974b 100644
--- a/bin12/lib/mir_core64.lib
+++ b/bin12/lib/mir_core64.lib
Binary files differ
diff --git a/include/m_gui.h b/include/m_gui.h
index c850d8c18b..d369ed5058 100644
--- a/include/m_gui.h
+++ b/include/m_gui.h
@@ -373,8 +373,6 @@ public:
virtual void OnApply();
virtual void OnReset();
- CCallback<CCtrlBase> OnChange;
-
static int cmp(const CCtrlBase *c1, const CCtrlBase *c2)
{
if (c1->m_idCtrl < c2->m_idCtrl) return -1;
@@ -389,6 +387,10 @@ protected:
CDlgBase* m_parentWnd;
bool m_bChanged;
+public:
+ CCallback<CCtrlBase> OnChange;
+
+protected:
virtual LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam);
void Subclass();
void Unsubclass();
@@ -957,7 +959,10 @@ public:
CCallback<TEventInfo> OnSingleExpand;
protected:
+ virtual void OnInit();
virtual BOOL OnNotify(int idCtrl, NMHDR *pnmh);
+
+ virtual LRESULT CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam);
union {
uint32_t m_dwFlags;
diff --git a/src/mir_core/src/ui_utils.cpp b/src/mir_core/src/ui_utils.cpp
index 700dd30f67..ce86fe1735 100644
--- a/src/mir_core/src/ui_utils.cpp
+++ b/src/mir_core/src/ui_utils.cpp
@@ -34,10 +34,10 @@ static int CompareDialogs(const CDlgBase *p1, const CDlgBase *p2)
}
static LIST<CDlgBase> arDialogs(10, CompareDialogs);
-static int CompareDialogs(const CCtrlBase *p1, const CCtrlBase *p2)
+static int CompareControls(const CCtrlBase *p1, const CCtrlBase *p2)
{ return (INT_PTR)p1->GetHwnd() - (INT_PTR)p2->GetHwnd();
}
-static LIST<CCtrlBase> arControls(10, PtrKeySortT);
+static LIST<CCtrlBase> arControls(10, CompareControls);
#pragma comment(lib, "uxtheme")
@@ -1382,31 +1382,131 @@ void CCtrlTreeView::SetFlags(uint32_t dwFlags)
}
}
+void CCtrlTreeView::OnInit()
+{
+ CSuper::OnInit();
+
+ if (m_bDndEnabled)
+ Subclass();
+}
+
+LRESULT CCtrlTreeView::CustomWndProc(UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TVHITTESTINFO hti;
+
+ 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;
+ 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);
+ }
+ break;
+
+ case WM_LBUTTONUP:
+ if (!m_bDragging)
+ 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)
+ 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();
+ }
+ break;
+ }
+
+ return CSuper::CustomWndProc(msg, wParam, lParam);
+}
+
BOOL CCtrlTreeView::OnNotify(int, NMHDR *pnmh)
{
TEventInfo evt = { this, pnmh };
switch (pnmh->code) {
- case TVN_BEGINDRAG: OnBeginDrag(&evt); return TRUE;
- case TVN_BEGINLABELEDIT: OnBeginLabelEdit(&evt); return TRUE;
- case TVN_BEGINRDRAG: OnBeginRDrag(&evt); return TRUE;
- case TVN_DELETEITEM: OnDeleteItem(&evt); return TRUE;
- case TVN_ENDLABELEDIT: OnEndLabelEdit(&evt); return TRUE;
- case TVN_GETDISPINFO: OnGetDispInfo(&evt); return TRUE;
- case TVN_GETINFOTIP: OnGetInfoTip(&evt); return TRUE;
- case TVN_ITEMEXPANDED: OnItemExpanded(&evt); return TRUE;
- case TVN_ITEMEXPANDING: OnItemExpanding(&evt); return TRUE;
- case TVN_SELCHANGED: OnSelChanged(&evt); return TRUE;
- case TVN_SELCHANGING: OnSelChanging(&evt); return TRUE;
- case TVN_SETDISPINFO: OnSetDispInfo(&evt); return TRUE;
- case TVN_SINGLEEXPAND: OnSingleExpand(&evt); return TRUE;
-
- case TVN_KEYDOWN:
- if (m_bCheckBox && evt.nmtvkey->wVKey == VK_SPACE)
- InvertCheck(GetSelection());
-
- OnKeyDown(&evt);
- return TRUE;
+ case TVN_BEGINLABELEDIT: OnBeginLabelEdit(&evt); return TRUE;
+ case TVN_BEGINRDRAG: OnBeginRDrag(&evt); return TRUE;
+ case TVN_DELETEITEM: OnDeleteItem(&evt); return TRUE;
+ case TVN_ENDLABELEDIT: OnEndLabelEdit(&evt); return TRUE;
+ case TVN_GETDISPINFO: OnGetDispInfo(&evt); return TRUE;
+ case TVN_GETINFOTIP: OnGetInfoTip(&evt); return TRUE;
+ case TVN_ITEMEXPANDED: OnItemExpanded(&evt); return TRUE;
+ case TVN_ITEMEXPANDING: OnItemExpanding(&evt); return TRUE;
+ case TVN_SELCHANGED: OnSelChanged(&evt); return TRUE;
+ case TVN_SELCHANGING: OnSelChanging(&evt); return TRUE;
+ case TVN_SETDISPINFO: OnSetDispInfo(&evt); return TRUE;
+ case TVN_SINGLEEXPAND: OnSingleExpand(&evt); return TRUE;
+
+ case TVN_BEGINDRAG:
+ OnBeginDrag(&evt);
+
+ // user-defined can clear the event code to disable dragging
+ if (m_bDndEnabled && pnmh->code) {
+ ::SetCapture(m_hwnd);
+ m_bDragging = true;
+ m_hDragItem = evt.nmtv->itemNew.hItem;
+ SelectItem(m_hDragItem);
+ }
+ return TRUE;
+
+ case TVN_KEYDOWN:
+ if (m_bCheckBox && evt.nmtvkey->wVKey == VK_SPACE)
+ InvertCheck(GetSelection());
+
+ OnKeyDown(&evt);
+ return TRUE;
}
if (m_bCheckBox && pnmh->code == NM_CLICK) {
diff --git a/src/modules/clist/contacts.cpp b/src/modules/clist/contacts.cpp
index 204dc3221c..98e2669fe0 100644
--- a/src/modules/clist/contacts.cpp
+++ b/src/modules/clist/contacts.cpp
@@ -376,9 +376,6 @@ static INT_PTR GetContactInfo(WPARAM, LPARAM lParam)
class CContactOptsDlg : public CDlgBase
{
- int dragging;
- HTREEITEM hDragItem;
-
CCtrlTreeView m_nameOrder;
public:
@@ -386,13 +383,12 @@ public:
CDlgBase(hInst, IDD_OPT_CONTACT),
m_nameOrder(this, IDC_NAMEORDER)
{
- m_nameOrder.OnBeginDrag = Callback(this, &CContactOptsDlg::OnBeginDrag);
+ m_nameOrder.SetFlags(MTREE_DND);
+ m_nameOrder.OnBeginDrag = Callback(this, &CContactOptsDlg::OnBeginDrag);
}
virtual void OnInitDialog()
{
- dragging = 0;
-
TVINSERTSTRUCT tvis;
tvis.hParent = NULL;
tvis.hInsertAfter = TVI_LAST;
@@ -423,82 +419,7 @@ public:
{
LPNMTREEVIEW pNotify = evt->nmtv;
if (pNotify->itemNew.lParam == 0 || pNotify->itemNew.lParam == SIZEOF(nameOrderDescr) - 1)
- return;
-
- SetCapture(m_hwnd);
- dragging = 1;
- hDragItem = pNotify->itemNew.hItem;
- m_nameOrder.SelectItem(hDragItem);
- }
-
- virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
- {
- TVHITTESTINFO hti;
-
- switch (msg) {
- case WM_MOUSEMOVE:
- if (!dragging)
- break;
-
- hti.pt.x = (short)LOWORD(lParam);
- hti.pt.y = (short)HIWORD(lParam);
- ClientToScreen(m_hwnd, &hti.pt);
- ScreenToClient(m_nameOrder.GetHwnd(), &hti.pt);
- m_nameOrder.HitTest(&hti);
- if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) {
- hti.pt.y -= m_nameOrder.GetItemHeight() / 2;
- m_nameOrder.HitTest(&hti);
- m_nameOrder.SetInsertMark(hti.hItem, 1);
- }
- else {
- if (hti.flags & TVHT_ABOVE) m_nameOrder.SendMsg(WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0);
- if (hti.flags & TVHT_BELOW) m_nameOrder.SendMsg(WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0);
- m_nameOrder.SetInsertMark(NULL, 0);
- }
- break;
-
- case WM_LBUTTONUP:
- if (!dragging)
- break;
-
- m_nameOrder.SetInsertMark(NULL, 0);
- dragging = 0;
- ReleaseCapture();
-
- hti.pt.x = (short)LOWORD(lParam);
- hti.pt.y = (short)HIWORD(lParam);
- ClientToScreen(m_hwnd, &hti.pt);
- ScreenToClient(m_nameOrder.GetHwnd(), &hti.pt);
- hti.pt.y -= m_nameOrder.GetItemHeight() / 2;
- m_nameOrder.HitTest(&hti);
- if (hDragItem == hti.hItem)
- break;
-
- TVITEMEX tvi;
- tvi.mask = TVIF_HANDLE | TVIF_PARAM;
- tvi.hItem = hti.hItem;
- m_nameOrder.GetItem(&tvi);
- if (tvi.lParam == SIZEOF(nameOrderDescr) - 1)
- break;
-
- if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) {
- TCHAR name[128];
- TVINSERTSTRUCT tvis = { 0 };
- tvis.itemex.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | TVIF_PARAM;
- tvis.itemex.stateMask = 0xFFFFFFFF;
- tvis.itemex.pszText = name;
- tvis.itemex.cchTextMax = SIZEOF(name);
- tvis.itemex.hItem = hDragItem;
- m_nameOrder.GetItem(&tvis.itemex);
- m_nameOrder.DeleteItem(hDragItem);
- tvis.hParent = NULL;
- tvis.hInsertAfter = hti.hItem;
- m_nameOrder.SelectItem(m_nameOrder.InsertItem(&tvis));
- NotifyChange();
- }
- break;
- }
- return CDlgBase::DlgProc(msg, wParam, lParam);
+ pNotify->hdr.code = 0; // deny dragging
}
};
diff --git a/src/modules/clist/protocolorder.cpp b/src/modules/clist/protocolorder.cpp
index a454793de3..274ae0dce6 100644
--- a/src/modules/clist/protocolorder.cpp
+++ b/src/modules/clist/protocolorder.cpp
@@ -149,8 +149,7 @@ public:
{
m_btnReset.OnClick = Callback(this, &CProtocolOrderOpts::onReset_Click);
- m_order.SetFlags(MTREE_CHECKBOX);
- m_order.OnBeginDrag = Callback(this, &CProtocolOrderOpts::onOrder_BeginDrag);
+ m_order.SetFlags(MTREE_CHECKBOX | MTREE_DND);
m_order.OnDeleteItem = Callback(this, &CProtocolOrderOpts::onOrder_DeleteItem);
}
@@ -216,96 +215,6 @@ public:
if (pnmtv)
mir_free((ProtocolData*)pnmtv->itemOld.lParam);
}
-
- void onOrder_BeginDrag(CCtrlTreeView::TEventInfo *env)
- {
- SetCapture(m_hwnd);
- m_bDragging = true;
- m_hDragItem = env->nmtv->itemNew.hItem;
- m_order.SelectItem(m_hDragItem);
- }
-
- virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
- {
- TVHITTESTINFO hti;
-
- switch (msg) {
- case WM_MOUSEMOVE:
- if (!m_bDragging)
- break;
-
- hti.pt.x = (short)LOWORD(lParam);
- hti.pt.y = (short)HIWORD(lParam);
- ClientToScreen(m_hwnd, &hti.pt);
- ScreenToClient(m_order.GetHwnd(), &hti.pt);
- m_order.HitTest(&hti);
- if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT)) {
- HTREEITEM it = hti.hItem;
- hti.pt.y -= m_order.GetItemHeight() / 2;
- m_order.HitTest(&hti);
- if (!(hti.flags & TVHT_ABOVE))
- m_order.SetInsertMark(hti.hItem, 1);
- else
- m_order.SetInsertMark(it, 0);
- }
- else {
- if (hti.flags & TVHT_ABOVE) m_order.SendMsg(WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0);
- if (hti.flags & TVHT_BELOW) m_order.SendMsg(WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0);
- m_order.SetInsertMark(NULL, 0);
- }
- break;
-
- case WM_LBUTTONUP:
- if (!m_bDragging)
- break;
-
- m_order.SetInsertMark(NULL, 0);
- m_bDragging = false;
- ReleaseCapture();
-
- hti.pt.x = (short)LOWORD(lParam);
- hti.pt.y = (short)HIWORD(lParam);
- ClientToScreen(m_hwnd, &hti.pt);
- ScreenToClient(m_order.GetHwnd(), &hti.pt);
- hti.pt.y -= m_order.GetItemHeight() / 2;
- m_order.HitTest(&hti);
- if (m_hDragItem == hti.hItem)
- break;
- if (hti.flags & TVHT_ABOVE)
- hti.hItem = TVI_FIRST;
-
- TVITEMEX tvi;
- tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_IMAGE;
- tvi.hItem = m_hDragItem;
- m_order.GetItem(&tvi);
- if (hti.flags & (TVHT_ONITEM | TVHT_ONITEMRIGHT) || (hti.hItem == TVI_FIRST)) {
- TCHAR name[128];
- TVINSERTSTRUCT tvis;
- tvis.itemex.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT | 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;
- m_order.GetItem(&tvis.itemex);
-
- // the pointed lParam will be freed inside TVN_DELETEITEM
- // so lets substitute it with 0
- ProtocolData *lpOldData = (ProtocolData*)tvis.itemex.lParam;
- tvis.itemex.lParam = 0;
- m_order.SetItem(&tvis.itemex);
-
- // now current item contain lParam = 0 we can delete it. the memory will be kept.
- tvis.itemex.lParam = (LPARAM)lpOldData;
- m_order.DeleteItem(m_hDragItem);
- tvis.hParent = NULL;
- tvis.hInsertAfter = hti.hItem;
- m_order.SelectItem(m_order.InsertItem(&tvis));
- NotifyChange();
- }
- }
- return CDlgBase::DlgProc(msg, wParam, lParam);
- }
};
int ProtocolOrderOptInit(WPARAM wParam, LPARAM)