leocad/win/GrpTree.cpp
2011-09-07 21:06:51 +00:00

263 lines
6 KiB
C++

// GrpTree.cpp : implementation file
//
#include "stdafx.h"
#include "leocad.h"
#include "GrpTree.h"
#include "group.h"
#include "piece.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CGroupEditTree
CGroupEditTree::CGroupEditTree()
{
m_bDragging = FALSE;
}
CGroupEditTree::~CGroupEditTree()
{
}
BEGIN_MESSAGE_MAP(CGroupEditTree, CTreeCtrl)
//{{AFX_MSG_MAP(CGroupEditTree)
ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBeginDrag)
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnBeginLabelEdit)
ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndLabelEdit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGroupEditTree message handlers
void CGroupEditTree::AddChildren(HTREEITEM hParent, Group* pGroup)
{
int i;
TV_INSERTSTRUCT tvstruct;
tvstruct.hParent = hParent;
tvstruct.hInsertAfter = TVI_SORT;
for (i = 0; i < opts->groupcount; i++)
if (opts->groupsgroups[i] == pGroup)
{
tvstruct.item.lParam = i + 0xFFFF;
tvstruct.item.iImage = 0;
tvstruct.item.iSelectedImage = 1;
tvstruct.item.pszText = opts->groups[i]->m_strName;
tvstruct.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
HTREEITEM hti = InsertItem(&tvstruct);
AddChildren(hti, opts->groups[i]);
}
for (i = 0; i < opts->piececount; i++)
if (opts->piecesgroups[i] == pGroup)
{
tvstruct.item.lParam = i;
tvstruct.item.iImage = 2;
tvstruct.item.iSelectedImage = 2;
tvstruct.item.pszText = (char*)opts->pieces[i]->GetName();
tvstruct.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
InsertItem(&tvstruct);
}
}
void CGroupEditTree::OnBeginLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
GetEditControl()->LimitText(80);
*pResult = 0;
}
void CGroupEditTree::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
// Set result to TRUE to accept the changes
*pResult = TRUE;
}
void CGroupEditTree::OnBeginDrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
*pResult = 0;
SetFocus(); // Receive WM_KEYDOWN
m_hitemDrag = pNMTreeView->itemNew.hItem;
m_hitemDrop = NULL;
SelectItem(m_hitemDrag);
if (!IsDropSource(m_hitemDrag))
return;
// get the image list for dragging
m_pDragImage = CreateDragImage(m_hitemDrag);
// CreateDragImage() returns NULL if no image list
// associated with the tree view control
if (!m_pDragImage)
return;
m_bDragging = TRUE;
m_pDragImage->BeginDrag(0, CPoint(-15,-15));
m_dropCursor = LoadCursor(NULL, IDC_ARROW);
m_noDropCursor = LoadCursor(NULL, IDC_NO);
POINT pt = pNMTreeView->ptDrag;
ClientToScreen(&pt);
m_pDragImage->DragEnter(NULL, pt);
SetCapture();
*pResult = 0;
}
void CGroupEditTree::OnMouseMove(UINT nFlags, CPoint point)
{
HTREEITEM hitem;
UINT flags;
if (m_bDragging)
{
POINT pt = point;
ClientToScreen(&pt);
CImageList::DragMove(pt);
if ((hitem = HitTest(point, &flags)) != NULL)
{
CImageList::DragShowNolock(FALSE);
m_hitemDrop = GetDropTarget(hitem);
SelectDropTarget(m_hitemDrop);
CImageList::DragShowNolock(TRUE);
}
else
m_hitemDrop = NULL;
if (m_hitemDrop)
SetCursor(m_dropCursor);
else
SetCursor(m_noDropCursor);
}
CTreeCtrl::OnMouseMove(nFlags, point);
}
void CGroupEditTree::OnLButtonUp(UINT nFlags, CPoint point)
{
CTreeCtrl::OnLButtonUp(nFlags, point);
if (m_bDragging)
{
m_bDragging = FALSE;
CImageList::DragLeave(this);
CImageList::EndDrag();
ReleaseCapture();
delete m_pDragImage;
// Remove drop target highlighting
SelectDropTarget(NULL);
if (m_hitemDrag == m_hitemDrop || m_hitemDrop == NULL)
return;
// If Drag item is an ancestor of Drop item then return
HTREEITEM htiParent = m_hitemDrop;
while ((htiParent = GetParentItem(htiParent)) != NULL)
if (htiParent == m_hitemDrag)
return;
Expand(m_hitemDrop, TVE_EXPAND);
DWORD source = GetItemData(m_hitemDrag);
DWORD dest = GetItemData(m_hitemDrop) - 0xFFFF;
TV_INSERTSTRUCT tvstruct;
tvstruct.hParent = m_hitemDrop;
tvstruct.hInsertAfter = TVI_SORT;
tvstruct.item.lParam = source;
tvstruct.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
DeleteItem(m_hitemDrag);
if (source < 0xFFFF)
{
opts->piecesgroups[source] = opts->groups[dest];
tvstruct.item.iImage = 2;
tvstruct.item.iSelectedImage = 2;
tvstruct.item.pszText = (char*)opts->pieces[source]->GetName();
InsertItem(&tvstruct);
}
else
{
opts->groupsgroups[source - 0xFFFF] = opts->groups[dest];
tvstruct.item.iImage = 0;
tvstruct.item.iSelectedImage = 1;
tvstruct.item.pszText = opts->groups[source - 0xFFFF]->m_strName;
HTREEITEM hti = InsertItem(&tvstruct);
AddChildren(hti, opts->groups[source - 0xFFFF]);
}
// AddChildren(m_hitemDrop, opts->groups[dest]);
}
}
BOOL CGroupEditTree::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN)
{
if (GetEditControl()
&& (pMsg->wParam == VK_RETURN
|| pMsg->wParam == VK_ESCAPE))
{
::TranslateMessage(pMsg);
::DispatchMessage(pMsg);
return TRUE; // DO NOT process further
}
if (pMsg->wParam == VK_ESCAPE
&& m_bDragging)
{
m_bDragging = 0;
CImageList::DragLeave(NULL);
CImageList::EndDrag();
ReleaseCapture();
SelectDropTarget(NULL);
delete m_pDragImage;
return TRUE; // DO NOT process further
}
}
return CTreeCtrl::PreTranslateMessage(pMsg);
}
BOOL CGroupEditTree::IsDropSource(HTREEITEM /*hItem*/)
{
return TRUE;
}
HTREEITEM CGroupEditTree::GetDropTarget(HTREEITEM hItem)
{
if (GetItemData(hItem) < 0xFFFF)
hItem = GetParentItem(hItem);
// inhibit drop on the drop source or its parent
if (hItem == m_hitemDrag || hItem == GetParentItem(m_hitemDrag))
return NULL;
HTREEITEM htiParent = hItem;
while ((htiParent = GetParentItem(htiParent)) != NULL)
if (htiParent == m_hitemDrag)
return NULL;
return hItem;
}