X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7ab0c3adb780464f2ee58f88d2443f5a79a2c401..8651867dbcdc35f07b0ae3a07c2a0f254c8293ef:/src/msw/treectrl.cpp diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index d494219360..78b92eaffd 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -725,7 +725,8 @@ wxTreeCtrl::~wxTreeCtrl() // delete any attributes if ( m_hasAnyAttr ) { - for ( wxNode *node = m_attrs.Next(); node; node = m_attrs.Next() ) + for ( wxHashTable::compatibility_iterator node = m_attrs.Next(); + node; node = m_attrs.Next() ) { delete (wxTreeItemAttr *)node->GetData(); } @@ -795,7 +796,7 @@ wxImageList *wxTreeCtrl::GetImageList() const wxImageList *wxTreeCtrl::GetStateImageList() const { - return m_imageListNormal; + return m_imageListState; } void wxTreeCtrl::SetAnyImageList(wxImageList *imageList, int which) @@ -2121,20 +2122,34 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { // avoid doing anything if we click on the only // currently selected item + wxArrayTreeItemIds selections; size_t count = GetSelections(selections); if ( count == 0 || - count > 1 || - HITEM(selections[0]) != htItem ) + count > 1 || + HITEM(selections[0]) != htItem ) { - // clear the previously selected items - UnselectAll(); - - // prevent the click from starting in-place editing - // which should only happen if we click on the - // already selected item (and nothing else is - // selected) - TreeView_SelectItem(GetHwnd(), 0); + // clear the previously selected items, if the + // user clicked outside of the present selection. + // otherwise, perform the deselection on mouse-up. + // this allows multiple drag and drop to work. + + if (IsItemSelected(GetHwnd(), htItem)) + { + ::SetFocus(GetHwnd(), htItem); + } + else + { + UnselectAll(); + + // prevent the click from starting in-place editing + // which should only happen if we click on the + // already selected item (and nothing else is + // selected) + + TreeView_SelectItem(GetHwnd(), 0); + ::SelectItem(GetHwnd(), htItem); + } } // reset on any click without Shift @@ -2160,6 +2175,24 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) break; case WM_LBUTTONUP: + + // facilitates multiple drag-and-drop + if (htItem && isMultiple) + { + wxArrayTreeItemIds selections; + size_t count = GetSelections(selections); + + if (count > 1 && + !(wParam & MK_CONTROL) && + !(wParam & MK_SHIFT)) + { + UnselectAll(); + TreeView_SelectItem(GetHwnd(), htItem); + } + } + + // fall through + case WM_RBUTTONUP: if ( m_dragImage ) { @@ -2582,6 +2615,23 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) return true; #endif // _WIN32_IE >= 0x300 + case NM_CLICK: + { + DWORD pos = GetMessagePos(); + POINT point; + point.x = LOWORD(pos); + point.y = HIWORD(pos); + ::MapWindowPoints(HWND_DESKTOP, GetHwnd(), &point, 1); + int flags = 0; + wxTreeItemId item = HitTest(wxPoint(point.x, point.y), flags); + if (flags & wxTREE_HITTEST_ONITEMSTATEICON) + { + event.m_item = item; + eventType = wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK; + } + break; + } + case NM_DBLCLK: case NM_RCLICK: { @@ -2768,6 +2818,50 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) return processed; } +// ---------------------------------------------------------------------------- +// State control. +// ---------------------------------------------------------------------------- + +// why do they define INDEXTOSTATEIMAGEMASK but not the inverse? +#define STATEIMAGEMASKTOINDEX(state) (((state) & TVIS_STATEIMAGEMASK) >> 12) + +void wxTreeCtrl::SetState(const wxTreeItemId& node, int state) +{ + TV_ITEM tvi; + tvi.hItem = (HTREEITEM)node.m_pItem; + tvi.mask = TVIF_STATE; + tvi.stateMask = TVIS_STATEIMAGEMASK; + + // Select the specified state, or -1 == cycle to the next one. + if ( state == -1 ) + { + TreeView_GetItem(GetHwnd(), &tvi); + + state = STATEIMAGEMASKTOINDEX(tvi.state) + 1; + if ( state == m_imageListState->GetImageCount() ) + state = 1; + } + + wxCHECK_RET( state < m_imageListState->GetImageCount(), + _T("wxTreeCtrl::SetState(): item index out of bounds") ); + + tvi.state = INDEXTOSTATEIMAGEMASK(state); + + TreeView_SetItem(GetHwnd(), &tvi); +} + +int wxTreeCtrl::GetState(const wxTreeItemId& node) +{ + TV_ITEM tvi; + tvi.hItem = (HTREEITEM)node.m_pItem; + tvi.mask = TVIF_STATE; + tvi.stateMask = TVIS_STATEIMAGEMASK; + TreeView_GetItem(GetHwnd(), &tvi); + + return STATEIMAGEMASKTOINDEX(tvi.state); +} + #endif // __WIN95__ #endif // wxUSE_TREECTRL +