362 lines
11 KiB
C++
362 lines
11 KiB
C++
#include <imagelst/tvdisp.hpp>
|
|
#include <imagelst/tvkey.hpp>
|
|
#include <imagelst/treeview.hpp>
|
|
#include <imagelst/tvmsghdr.hpp>
|
|
#include <imagelst/hittest.hpp>
|
|
#include <common/guiwnd.hpp>
|
|
|
|
TreeView::TreeView(GUIWindow &parentWindow,const Rect &winRect,int controlID,DWORD viewFlags)
|
|
: mParentWindow(parentWindow) //, mControlID(controlID)
|
|
{
|
|
mNotifyHandler.setCallback(this,&TreeView::notifyHandler);
|
|
::InitCommonControls();
|
|
mParentWindow.insertHandler(VectorHandler::NotifyHandler,&mNotifyHandler);
|
|
createTreeView(winRect,viewFlags,controlID);
|
|
}
|
|
|
|
TreeView::~TreeView()
|
|
{
|
|
destroy();
|
|
mParentWindow.removeHandler(VectorHandler::NotifyHandler,&mNotifyHandler);
|
|
}
|
|
|
|
|
|
void TreeView::createTreeView(const Rect &winRect,DWORD viewFlags,int controlID)
|
|
{
|
|
createControl(WS_EX_LEFT|WS_EX_LTRREADING|WS_EX_RIGHTSCROLLBAR|WS_EX_CLIENTEDGE,WC_TREEVIEW,"",WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE|viewFlags,winRect,mParentWindow,controlID);
|
|
}
|
|
|
|
HTREEITEM TreeView::hitTest(HitTestInfo &someHitTestInfo)const
|
|
{
|
|
if(!isOkay())return FALSE;
|
|
return (HTREEITEM)sendMessage(TVM_HITTEST,0,(LPARAM)&((TV_HITTESTINFO&)someHitTestInfo));
|
|
}
|
|
|
|
WORD TreeView::remove(void)const
|
|
{
|
|
if(!isOkay())return FALSE;
|
|
if(!getCount())return TRUE;
|
|
sendMessage(TVM_DELETEITEM,0,(LPARAM)TVI_ROOT);
|
|
return !getCount();
|
|
}
|
|
|
|
CallbackData::ReturnType TreeView::rightButtonDownHandler(CallbackData &/*someCallbackData*/)
|
|
{
|
|
return (CallbackData::ReturnType)TRUE;
|
|
}
|
|
|
|
CallbackData::ReturnType TreeView::rightButtonUpHandler(CallbackData &/*someCallbackData*/)
|
|
{
|
|
return (CallbackData::ReturnType)FALSE;
|
|
}
|
|
|
|
CallbackData::ReturnType TreeView::notifyHandler(CallbackData &someCallbackData)
|
|
{
|
|
NotifyMessageHeader nmHeader(*(((NMHDR*)someCallbackData.lParam())));
|
|
if(controlID()==nmHeader.idFrom())
|
|
{
|
|
switch(nmHeader.code())
|
|
{
|
|
case TVN_SELCHANGING :
|
|
return tvnSelChanging(TreeViewMessageHeader(*(((NM_TREEVIEW*)someCallbackData.lParam()))));
|
|
case TVN_SELCHANGED :
|
|
return tvnSelChanged(TreeViewMessageHeader(*(((NM_TREEVIEW*)someCallbackData.lParam()))));
|
|
case TVN_GETDISPINFO :
|
|
return handleGetDisplayInfo(someCallbackData);
|
|
case TVN_SETDISPINFO :
|
|
return tvnSetDispInfo(TreeViewDisplayInfo(*(((TV_DISPINFO*)someCallbackData.lParam()))));
|
|
case TVN_ITEMEXPANDING :
|
|
return tvnItemExpanding(TreeViewMessageHeader(*(((NM_TREEVIEW*)someCallbackData.lParam()))));
|
|
case TVN_ITEMEXPANDED :
|
|
return tvnItemExpanded(TreeViewMessageHeader(*(((NM_TREEVIEW*)someCallbackData.lParam()))));
|
|
case TVN_BEGINDRAG :
|
|
return tvnBeginDrag(TreeViewMessageHeader(*(((NM_TREEVIEW*)someCallbackData.lParam()))));
|
|
case TVN_BEGINRDRAG :
|
|
return tvnBeginRDrag(TreeViewMessageHeader(*(((NM_TREEVIEW*)someCallbackData.lParam()))));
|
|
case TVN_DELETEITEM :
|
|
return tvnDeleteItem(TreeViewMessageHeader(*(((NM_TREEVIEW*)someCallbackData.lParam()))));
|
|
case TVN_BEGINLABELEDIT :
|
|
return tvnBeginLabelEdit(TreeViewDisplayInfo(*(((TV_DISPINFO*)someCallbackData.lParam()))));
|
|
case TVN_ENDLABELEDIT :
|
|
return tvnEndLabelEdit(TreeViewDisplayInfo(*(((TV_DISPINFO*)someCallbackData.lParam()))));
|
|
case TVN_KEYDOWN :
|
|
return tvnKeyDown(TreeViewKeyDown(*(((TV_KEYDOWN*)someCallbackData.lParam()))));
|
|
}
|
|
}
|
|
return (CallbackData::ReturnType)::DefWindowProc(someCallbackData.hwndFrom(),WM_NOTIFY,someCallbackData.wParam(),someCallbackData.lParam());
|
|
}
|
|
|
|
HTREEITEM TreeView::addRootNode(DWORD itemIndex,const String &text,DWORD userData)
|
|
{
|
|
TreeViewItem treeViewItem;
|
|
TreeViewInsert treeViewInsert;
|
|
|
|
treeViewItem.mask(TreeViewItem::MaskText|TreeViewItem::MaskImage|TreeViewItem::MaskSelectedImage|TreeViewItem::MaskParam);
|
|
treeViewItem.text((LPSTR)(String&)text);
|
|
treeViewItem.maxText(text.length());
|
|
treeViewItem.image(itemIndex);
|
|
treeViewItem.selectedImage(I_IMAGECALLBACK);
|
|
treeViewItem.lParam(userData);
|
|
treeViewInsert.parent(TVGN_ROOT);
|
|
treeViewInsert.insertAfter(TVGN_ROOT);
|
|
treeViewInsert.viewItem(treeViewItem);
|
|
return insertItem(treeViewInsert);
|
|
}
|
|
|
|
WORD TreeView::appendNode(NodeType nodeType,DWORD itemIndex,const String &text,DWORD userData,WORD selected)
|
|
{
|
|
HTREEITEM hInsertItem;
|
|
TreeViewItem treeViewItem;
|
|
TreeViewInsert treeViewInsert;
|
|
|
|
treeViewItem.mask(TreeViewItem::MaskText|TreeViewItem::MaskImage|TreeViewItem::MaskSelectedImage|TreeViewItem::MaskParam);
|
|
treeViewItem.text((LPSTR)(String&)text);
|
|
treeViewItem.maxText(text.length());
|
|
treeViewItem.image(itemIndex);
|
|
treeViewItem.selectedImage(I_IMAGECALLBACK);
|
|
treeViewItem.lParam(userData);
|
|
if(NodeChild==nodeType)treeViewInsert.parent(mLastInsert.insertAfter());
|
|
else treeViewInsert.parent(mLastInsert.parent());
|
|
treeViewInsert.insertAfter(mLastInsert.insertAfter());
|
|
treeViewInsert.viewItem(treeViewItem);
|
|
hInsertItem=insertItem(treeViewInsert);
|
|
if(!hInsertItem)return FALSE;
|
|
if(selected)selectItem(hInsertItem);
|
|
return (hInsertItem?TRUE:FALSE);
|
|
}
|
|
|
|
WORD TreeView::addNode(NodeType nodeType,TreeViewItem &insertTreeViewItem,const String &parentString,WORD selected,BYTE delimeter)
|
|
{
|
|
HTREEITEM hTreeItem;
|
|
HTREEITEM hPrevItem;
|
|
HTREEITEM hChildItem;
|
|
String workString;
|
|
TreeViewInsert viewInsert;
|
|
TreeViewItem viewItem;
|
|
|
|
workString.length(String::MaxString);
|
|
viewItem.maxText(workString.length());
|
|
hTreeItem=getChild((HTREEITEM)TreeViewInsert::GetRoot);
|
|
while(hTreeItem)
|
|
{
|
|
hChildItem=getChild(hTreeItem);
|
|
if(hChildItem&&searchInsert(nodeType,insertTreeViewItem,viewInsert,parentString,hTreeItem,hChildItem,delimeter))
|
|
{
|
|
HTREEITEM hInsertItem(insertItem(viewInsert));
|
|
if(!hInsertItem)return FALSE;
|
|
if(selected)selectItem(hInsertItem);
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
viewItem.mask(TreeViewItem::MaskText);
|
|
viewItem.item(hTreeItem);
|
|
viewItem.text((LPSTR)workString);
|
|
getItem(viewItem);
|
|
if(parentString==String(viewItem.text()).betweenString(0,delimeter))
|
|
{
|
|
String workString(insertTreeViewItem.text());
|
|
viewItem=TreeViewItem();
|
|
viewItem.mask(TreeViewItem::MaskText|TreeViewItem::MaskImage|TreeViewItem::MaskSelectedImage|TreeViewItem::MaskParam);
|
|
viewItem.text((LPSTR)workString);
|
|
viewItem.maxText(workString.length());
|
|
viewItem.image(insertTreeViewItem.image());
|
|
viewItem.selectedImage(I_IMAGECALLBACK);
|
|
viewItem.lParam(insertTreeViewItem.lParam());
|
|
viewInsert.parent(hTreeItem);
|
|
viewInsert.insertAfter(hPrevItem);
|
|
viewInsert.viewItem(viewItem);
|
|
HTREEITEM hInsertItem(insertItem(viewInsert));
|
|
if(!hInsertItem)return FALSE;
|
|
if(selected)selectItem(hInsertItem);
|
|
return TRUE;
|
|
}
|
|
}
|
|
hPrevItem=hTreeItem;
|
|
hTreeItem=getNextSibling(hTreeItem);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
HTREEITEM TreeView::searchItem(const String &searchString,HTREEITEM hDescendItem)const
|
|
{
|
|
TreeViewItem viewItem;
|
|
String workString;
|
|
HTREEITEM hTreeItem;
|
|
HTREEITEM hChildItem;
|
|
|
|
workString.length(String::MaxString);
|
|
viewItem.maxText(workString.length());
|
|
if(!hDescendItem)hTreeItem=getChild((HTREEITEM)TreeViewInsert::GetRoot);
|
|
else hTreeItem=hDescendItem;
|
|
while(hTreeItem)
|
|
{
|
|
hChildItem=getChild(hTreeItem);
|
|
if(hChildItem)
|
|
{
|
|
HTREEITEM hFoundItem(searchItem(searchString,hChildItem));
|
|
if(hFoundItem)return hFoundItem;
|
|
}
|
|
viewItem.mask(TreeViewItem::MaskText);
|
|
viewItem.item(hTreeItem);
|
|
viewItem.text((LPSTR)workString);
|
|
getItem(viewItem);
|
|
if(searchString==viewItem.text())return hTreeItem;
|
|
hTreeItem=getNextSibling(hTreeItem);
|
|
}
|
|
return (HTREEITEM)0;
|
|
}
|
|
|
|
WORD TreeView::searchInsert(NodeType nodeType,TreeViewItem &viewItem,TreeViewInsert &viewInsert,const String &parentString,HTREEITEM hParentItem,HTREEITEM hChildItem,BYTE delimeter)
|
|
{
|
|
WORD searchResult(FALSE);
|
|
HTREEITEM hPrevItem(FALSE);
|
|
HTREEITEM hTreeItem(hChildItem);
|
|
HTREEITEM hChildNode;
|
|
TreeViewItem searchItem;
|
|
String bufferString;
|
|
|
|
bufferString.length(String::MaxString);
|
|
searchItem.maxText(bufferString.length());
|
|
while(hTreeItem)
|
|
{
|
|
hChildNode=getChild(hTreeItem);
|
|
if(hChildNode&&searchInsert(nodeType,viewItem,viewInsert,parentString,hTreeItem,hChildNode,delimeter))
|
|
{
|
|
searchResult=TRUE;
|
|
break;
|
|
}
|
|
searchItem.mask(TreeViewItem::MaskText);
|
|
searchItem.item(hTreeItem);
|
|
searchItem.text((LPSTR)bufferString);
|
|
getItem(searchItem);
|
|
if(parentString==delimeter?String(searchItem.text()).betweenString(0,delimeter):String(searchItem.text()))
|
|
{
|
|
viewItem.mask(TreeViewItem::MaskText|TreeViewItem::MaskImage|TreeViewItem::MaskSelectedImage|TreeViewItem::MaskParam);
|
|
viewItem.selectedImage(I_IMAGECALLBACK);
|
|
if(NodeChild==nodeType)viewInsert.parent(hTreeItem);
|
|
else viewInsert.parent(hParentItem);
|
|
viewInsert.insertAfter(hPrevItem);
|
|
viewInsert.viewItem(viewItem);
|
|
searchResult=TRUE;
|
|
break;
|
|
}
|
|
hPrevItem=hTreeItem;
|
|
hTreeItem=getNextSibling(hTreeItem);
|
|
}
|
|
return searchResult;
|
|
}
|
|
|
|
String TreeView::getRootItemText(void)const
|
|
{
|
|
TreeViewItem viewItem;
|
|
String rootText;
|
|
|
|
viewItem.maxText(String::MaxString);
|
|
viewItem.mask(TreeViewItem::MaskText);
|
|
viewItem.item(getRoot());
|
|
viewItem.text((LPSTR)rootText);
|
|
getItem(viewItem);
|
|
return rootText;
|
|
}
|
|
|
|
String TreeView::currentSelection(void)const
|
|
{
|
|
TreeViewItem viewItem;
|
|
String workString;
|
|
|
|
workString.length(String::MaxString);
|
|
viewItem.mask(TreeViewItem::MaskText);
|
|
viewItem.item(getSelection());
|
|
viewItem.text(workString);
|
|
viewItem.maxText(workString.length());
|
|
getItem(viewItem);
|
|
return (const char*)viewItem.text();
|
|
}
|
|
|
|
String TreeView::currentParentSelection(void)const
|
|
{
|
|
TreeViewItem viewItem;
|
|
String workString;
|
|
|
|
workString.length(String::MaxString);
|
|
viewItem.mask(TreeViewItem::MaskText);
|
|
viewItem.item(getParent(getSelection()));
|
|
viewItem.text(workString);
|
|
viewItem.maxText(workString.length());
|
|
getItem(viewItem);
|
|
return (const char *)viewItem.text();
|
|
}
|
|
|
|
WORD TreeView::handleGetDisplayInfo(CallbackData &someCallbackData)
|
|
{
|
|
WORD returnCode;
|
|
TreeViewDisplayInfo tvDispInfo(*((TV_DISPINFO*)someCallbackData.lParam()));
|
|
returnCode=tvnGetDispInfo(tvDispInfo);
|
|
*((TV_DISPINFO*)someCallbackData.lParam())=(TV_DISPINFO&)tvDispInfo;
|
|
return returnCode;
|
|
}
|
|
|
|
// *******virtuals
|
|
|
|
WORD TreeView::tvnSelChanging(const TreeViewMessageHeader &/*treeViewMessageHeader*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnSelChanged(const TreeViewMessageHeader &/*treeViewMessageHeader*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnGetDispInfo(TreeViewDisplayInfo &/*treeViewDisplayInfo*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnSetDispInfo(TreeViewDisplayInfo &/*treeViewDisplayInfo*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnItemExpanding(const TreeViewMessageHeader &/*treeViewMessageHeader*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnItemExpanded(const TreeViewMessageHeader &/*treeViewMessageHeader*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnBeginDrag(const TreeViewMessageHeader &/*treeViewMessageHeader*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnBeginRDrag(const TreeViewMessageHeader &/*treeViewMessageHeader*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnDeleteItem(const TreeViewMessageHeader &/*treeViewMessageHeader*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnBeginLabelEdit(const TreeViewDisplayInfo &/*treeViewDisplayInfo*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnEndLabelEdit(const TreeViewDisplayInfo &/*treeViewDisplayInfo*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
WORD TreeView::tvnKeyDown(const TreeViewKeyDown &/*treeViewMessageHeader*/)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|