summaryrefslogtreecommitdiff
path: root/iup/src/win/iupwin_tree.c
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2010-06-15 00:59:57 -0700
committerPixel <pixel@nobis-crew.org>2010-06-15 00:59:57 -0700
commiteed0eb6a476d54ce19aeff137984aa981d9e3976 (patch)
tree807891636efd2f87dcbd261e971216269973ae07 /iup/src/win/iupwin_tree.c
parentccc8261e4d48de89da4ddfe7b55e378ae0cd6f47 (diff)
Upgrading to iup 3.1
Diffstat (limited to 'iup/src/win/iupwin_tree.c')
-rwxr-xr-xiup/src/win/iupwin_tree.c1292
1 files changed, 664 insertions, 628 deletions
diff --git a/iup/src/win/iupwin_tree.c b/iup/src/win/iupwin_tree.c
index e6877dc..4a5f8be 100755
--- a/iup/src/win/iupwin_tree.c
+++ b/iup/src/win/iupwin_tree.c
@@ -31,17 +31,19 @@
#include "iupwin_draw.h"
#include "iupwin_info.h"
+
typedef struct _winTreeItemData
{
COLORREF color;
unsigned char kind;
- void* userdata;
HFONT hFont;
short image;
short image_expanded;
} winTreeItemData;
-#ifndef TVN_ITEMCHANGING /* Vista Only */
+/* Vista Only */
+
+#ifndef TVN_ITEMCHANGING
typedef struct tagNMTVITEMCHANGE {
NMHDR hdr;
UINT uChanged;
@@ -54,257 +56,125 @@ typedef struct tagNMTVITEMCHANGE {
#define TVN_ITEMCHANGINGW (TVN_FIRST-17)
#endif
-static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem);
-typedef int (*winTreeNodeFunc)(Ihandle* ih, HTREEITEM hItem, void* userdata);
-
-static int winTreeForEach(Ihandle* ih, HTREEITEM hItem, winTreeNodeFunc func, void* userdata)
-{
- HTREEITEM hItemChild;
-
- if (!hItem)
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
+#ifndef TVS_EX_DOUBLEBUFFER
+#define TVS_EX_DOUBLEBUFFER 0x0004
+#endif
- while(hItem != NULL)
- {
- if (!func(ih, hItem, userdata))
- return 0;
+#ifndef TVM_SETEXTENDEDSTYLE
+#define TVM_SETEXTENDEDSTYLE (TV_FIRST + 44)
+#endif
- hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- if (hItemChild)
- {
- /* Recursively traverse child items */
- if (!winTreeForEach(ih, hItemChild, func, userdata))
- return 0;
- }
- /* Go to next sibling item */
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
- }
+static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem);
- return 1;
-}
/*****************************************************************************/
/* FINDING ITEMS */
/*****************************************************************************/
-static HTREEITEM winTreeFindNodeID(Ihandle* ih, HTREEITEM hItem, HTREEITEM hNode)
-{
- TVITEM item;
- winTreeItemData* itemData;
-
- while(hItem != NULL)
- {
- /* ID control to traverse items */
- ih->data->id_control++;
-
- /* StateID founded! */
- if(hItem == hNode)
- return hItem;
- /* Get hItem attributes */
- item.hItem = hItem;
- item.mask = TVIF_HANDLE|TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- /* Check whether we have child items */
- if (itemData->kind == ITREE_BRANCH)
- {
- /* Recursively traverse child items */
- HTREEITEM hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- hItemChild = winTreeFindNodeID(ih, hItemChild, hNode);
-
- /* StateID founded! */
- if(hItemChild)
- return hItemChild;
- }
- /* Go to next sibling item */
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
- }
-
- return NULL;
+InodeHandle* iupdrvTreeGetFocusNode(Ihandle* ih)
+{
+ return (InodeHandle*)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CARET, 0);
}
-static int winTreeGetNodeId(Ihandle* ih, HTREEITEM hItem)
+static HTREEITEM winTreeFindNodeXY(Ihandle* ih, int x, int y)
{
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- ih->data->id_control = -1;
- if (winTreeFindNodeID(ih, hItemRoot, hItem))
- return ih->data->id_control;
- else
- return -1;
+ TVHITTESTINFO info;
+ info.pt.x = x;
+ info.pt.y = y;
+ return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info);
}
-static HTREEITEM winTreeFindUserDataID(Ihandle* ih, HTREEITEM hItem, void* userdata)
+static HTREEITEM winTreeFindNodePointed(Ihandle* ih)
{
- TVITEM item;
- winTreeItemData* itemData;
-
- while(hItem != NULL)
- {
- /* ID control to traverse items */
- ih->data->id_control++;
-
- /* Get hItem attributes */
- item.hItem = hItem;
- item.mask = TVIF_HANDLE|TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- /* userdata founded! */
- if(itemData->userdata == userdata)
- return hItem;
-
- /* Check whether we have child items */
- if (itemData->kind == ITREE_BRANCH)
- {
- /* Recursively traverse child items */
- HTREEITEM hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- hItemChild = winTreeFindUserDataID(ih, hItemChild, userdata);
-
- /* userdata founded! */
- if (hItemChild)
- return hItemChild;
- }
-
- /* Go to next sibling item */
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
- }
-
- return NULL;
+ TVHITTESTINFO info;
+ DWORD pos = GetMessagePos();
+ info.pt.x = LOWORD(pos);
+ info.pt.y = HIWORD(pos);
+ ScreenToClient(ih->handle, &info.pt);
+ return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info);
}
-static int winTreeGetUserDataId(Ihandle* ih, void* userdata)
+int iupwinGetColor(const char* value, COLORREF *color)
{
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- ih->data->id_control = -1;
- if (winTreeFindUserDataID(ih, hItemRoot, userdata))
- return ih->data->id_control;
- else
- return -1;
+ unsigned char r, g, b;
+ if (iupStrToRGB(value, &r, &g, &b))
+ {
+ *color = RGB(r,g,b);
+ return 1;
+ }
+ return 0;
}
-static HTREEITEM winTreeFindNodeFromID(Ihandle* ih, HTREEITEM hItem)
+static void winTreeChildCountRec(Ihandle* ih, HTREEITEM hItem, int *count)
{
- TVITEM item;
- winTreeItemData* itemData;
-
+ hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
while(hItem != NULL)
{
- /* ID control to traverse items */
- ih->data->id_control--;
-
- /* StateID founded! */
- if(ih->data->id_control < 0)
- return hItem;
-
- /* Get hItem attributes */
- item.hItem = hItem;
- item.mask = TVIF_HANDLE|TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- /* Check whether we have child items */
- if (itemData->kind == ITREE_BRANCH)
- {
- /* Recursively traverse child items */
- HTREEITEM hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- hItemChild = winTreeFindNodeFromID(ih, hItemChild);
+ (*count)++;
- /* StateID founded! */
- if(ih->data->id_control < 0)
- return hItemChild;
- }
+ /* go recursive to children */
+ winTreeChildCountRec(ih, hItem, count);
/* Go to next sibling item */
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
}
-
- return hItem;
}
-static HTREEITEM winTreeFindNodeFromString(Ihandle* ih, const char* name_id)
+int iupdrvTreeTotalChildCount(Ihandle* ih, HTREEITEM hItem)
{
- if (name_id[0])
- {
- HTREEITEM hRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- iupStrToInt(name_id, &ih->data->id_control);
- return winTreeFindNodeFromID(ih, hRoot);
- }
- else
- return (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CARET, 0);
+ int count = 0;
+ winTreeChildCountRec(ih, hItem, &count);
+ return count;
}
-/* Recursively, find a new brother for the item
- that will have its depth changed. Returns the new brother. */
-static HTREEITEM winTreeFindNewBrother(Ihandle* ih, HTREEITEM hBrotherItem)
+static void winTreeChildRebuildCacheRec(Ihandle* ih, HTREEITEM hItem, int *id)
{
- TVITEM item;
- winTreeItemData* itemData;
-
- while(hBrotherItem != NULL)
+ hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
+ while(hItem != NULL)
{
- if(ih->data->id_control < 0)
- return hBrotherItem;
-
- item.hItem = hBrotherItem;
- item.mask = TVIF_HANDLE|TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- if (itemData->kind == ITREE_BRANCH)
- {
- HTREEITEM hItemChild;
-
- ih->data->id_control--;
- hItemChild = winTreeFindNewBrother(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hBrotherItem));
+ (*id)++;
+ ih->data->node_cache[*id].node_handle = hItem;
- if(ih->data->id_control < 0)
- return hItemChild;
- }
+ /* go recursive to children */
+ winTreeChildRebuildCacheRec(ih, hItem, id);
- hBrotherItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hBrotherItem);
+ /* Go to next sibling item */
+ hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
}
-
- return hBrotherItem;
}
-static HTREEITEM winTreeFindNodePointed(Ihandle* ih)
+static void winTreeRebuildNodeCache(Ihandle* ih, int id, HTREEITEM hItem)
{
- TVHITTESTINFO info;
- DWORD pos = GetMessagePos();
- info.pt.x = LOWORD(pos);
- info.pt.y = HIWORD(pos);
-
- ScreenToClient(ih->handle, &info.pt);
-
- return (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)(LPTVHITTESTINFO)&info);
+ ih->data->node_cache[id].node_handle = hItem;
+ winTreeChildRebuildCacheRec(ih, hItem, &id);
}
-int iupwinGetColor(const char* value, COLORREF *color)
-{
- unsigned char r, g, b;
- if (iupStrToRGB(value, &r, &g, &b))
- {
- *color = RGB(r,g,b);
- return 1;
- }
- return 0;
-}
/*****************************************************************************/
/* ADDING ITEMS */
/*****************************************************************************/
+
+static void winTreeExpandItem(Ihandle* ih, HTREEITEM hItem, int expand);
+
void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* title, int add)
{
- TVITEM item, tviPrevItem;
+ TVITEM item;
TVINSERTSTRUCT tvins;
- HTREEITEM hPrevItem = winTreeFindNodeFromString(ih, name_id);
- int kindPrev;
+ HTREEITEM hPrevItem = iupTreeGetNodeFromString(ih, name_id);
+ HTREEITEM hItemNew;
winTreeItemData* itemData;
if (!hPrevItem)
- return;
+ {
+ /* check if the root was really specified */
+ int id = 0;
+ if (!iupStrToInt(name_id, &id) || id != -1)
+ return;
+ }
+
+ if (!title)
+ title = "";
itemData = calloc(1, sizeof(winTreeItemData));
itemData->image = -1;
@@ -318,83 +188,71 @@ void iupdrvTreeAddNode(Ihandle* ih, const char* name_id, int kind, const char* t
iupwinGetColor(iupAttribGetStr(ih, "FGCOLOR"), &itemData->color);
if (kind == ITREE_BRANCH)
- {
item.iSelectedImage = item.iImage = (int)ih->data->def_image_collapsed;
-
- if (ih->data->add_expanded)
- {
- item.mask |= TVIF_STATE;
- item.state = item.stateMask = TVIS_EXPANDED;
- item.iSelectedImage = item.iImage = (int)ih->data->def_image_expanded;
- }
- }
else
item.iSelectedImage = item.iImage = (int)ih->data->def_image_leaf;
/* Save the heading level in the node's application-defined data area */
tvins.item = item;
- /* get the KIND attribute of node selected */
- tviPrevItem.hItem = hPrevItem;
- tviPrevItem.mask = TVIF_PARAM|TVIF_CHILDREN;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&tviPrevItem);
- kindPrev = ((winTreeItemData*)tviPrevItem.lParam)->kind;
-
- /* Define the parent and the position to the new node inside
- the list, using the KIND attribute of node selected */
- if (kindPrev == ITREE_BRANCH && add)
- {
- tvins.hParent = hPrevItem;
- tvins.hInsertAfter = TVI_FIRST; /* insert the new node after item selected, as first child */
- }
- else
- {
- tvins.hParent = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hPrevItem);
- tvins.hInsertAfter = hPrevItem; /* insert the new node after item selected */
- }
-
- /* Add the node to the tree-view control */
- SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
-
- if (kindPrev == ITREE_BRANCH && tviPrevItem.cChildren==0)
+ if (hPrevItem)
{
- /* this is the first child, redraw to update the '+'/'-' buttons */
- iupdrvDisplayRedraw(ih);
- }
-}
+ int kindPrev;
+ TVITEM tviPrevItem;
-static void winTreeAddRootNode(Ihandle* ih)
-{
- TVITEM item;
- TVINSERTSTRUCT tvins;
- HTREEITEM hNewItem;
- winTreeItemData* itemData;
+ /* get the KIND attribute of reference node */
+ tviPrevItem.hItem = hPrevItem;
+ tviPrevItem.mask = TVIF_PARAM|TVIF_CHILDREN;
+ SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&tviPrevItem);
+ kindPrev = ((winTreeItemData*)tviPrevItem.lParam)->kind;
- itemData = calloc(1, sizeof(winTreeItemData));
- itemData->image = -1;
- itemData->image_expanded = -1;
- itemData->kind = ITREE_BRANCH;
+ /* Define the parent and the position to the new node inside
+ the list, using the KIND attribute of reference node */
+ if (kindPrev == ITREE_BRANCH && add)
+ {
+ /* depth+1 */
+ tvins.hParent = hPrevItem;
+ tvins.hInsertAfter = TVI_FIRST; /* insert the new node after the reference node, as first child */
+ }
+ else
+ {
+ /* same depth */
+ tvins.hParent = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hPrevItem);
+ tvins.hInsertAfter = hPrevItem; /* insert the new node after reference node */
+ }
- item.mask = TVIF_PARAM | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
- item.state = item.stateMask = TVIS_EXPANDED;
- item.iSelectedImage = item.iImage = (int)ih->data->def_image_expanded;
- item.lParam = (LPARAM)itemData;
+ /* Add the new node */
+ hItemNew = (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
+ iupTreeAddToCache(ih, add, kindPrev, hPrevItem, hItemNew);
- iupwinGetColor(iupAttribGetStr(ih, "FGCOLOR"), &itemData->color);
+ if (kindPrev == ITREE_BRANCH && tviPrevItem.cChildren==0) /* was 0, now is 1 */
+ {
+ /* this is the first child, redraw to update the '+'/'-' buttons */
+ if (ih->data->add_expanded)
+ winTreeExpandItem(ih, hPrevItem, 1);
+ else
+ winTreeExpandItem(ih, hPrevItem, 0);
+ }
- /* Save the heading level in the node's application-defined data area */
- tvins.item = item;
- tvins.hInsertAfter = TVI_FIRST;
- tvins.hParent = TVI_ROOT;
+ }
+ else
+ {
+ tvins.hInsertAfter = TVI_FIRST;
+ tvins.hParent = TVI_ROOT;
- /* Add the node to the tree-view control */
- hNewItem = (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
+ /* Add the new node */
+ hItemNew = (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
+ iupTreeAddToCache(ih, 0, 0, NULL, hItemNew);
- /* MarkStart node */
- iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)hNewItem);
+ if (ih->data->node_count == 1)
+ {
+ /* MarkStart node */
+ iupAttribSetStr(ih, "_IUPTREE_MARKSTART_NODE", (char*)hItemNew);
- /* Set the default VALUE */
- winTreeSetFocusNode(ih, hNewItem);
+ /* Set the default VALUE */
+ winTreeSetFocusNode(ih, hItemNew);
+ }
+ }
}
static int winTreeIsItemExpanded(Ihandle* ih, HTREEITEM hItem)
@@ -408,13 +266,28 @@ static int winTreeIsItemExpanded(Ihandle* ih, HTREEITEM hItem)
static void winTreeExpandItem(Ihandle* ih, HTREEITEM hItem, int expand)
{
- if (expand == -1)
- expand = !winTreeIsItemExpanded(ih, hItem); /* toggle */
+ TVITEM item;
+ winTreeItemData* itemData;
+
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", "1");
+ /* it only works if the branch has children */
+ SendMessage(ih->handle, TVM_EXPAND, expand? TVE_EXPAND: TVE_COLLAPSE, (LPARAM)hItem);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_BRANCH_CB", NULL);
+
+ /* update image */
+ item.hItem = hItem;
+ item.mask = TVIF_HANDLE|TVIF_PARAM;
+ SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
+ itemData = (winTreeItemData*)item.lParam;
if (expand)
- SendMessage(ih->handle, TVM_EXPAND, TVE_EXPAND, (LPARAM)hItem);
+ item.iSelectedImage = item.iImage = (itemData->image_expanded!=-1)? itemData->image_expanded: (int)ih->data->def_image_expanded;
else
- SendMessage(ih->handle, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)hItem);
+ item.iSelectedImage = item.iImage = (itemData->image!=-1)? itemData->image: (int)ih->data->def_image_collapsed;
+
+ item.hItem = hItem;
+ item.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item);
}
/*****************************************************************************/
@@ -445,12 +318,12 @@ static void winTreeExpandTree(Ihandle* ih, HTREEITEM hItem, int expand)
/* SELECTING ITEMS */
/*****************************************************************************/
-static int winTreeIsItemSelected(Ihandle* ih, HTREEITEM hItem)
+static int winTreeIsNodeSelected(Ihandle* ih, HTREEITEM hItem)
{
return ((SendMessage(ih->handle, TVM_GETITEMSTATE, (WPARAM)hItem, TVIS_SELECTED)) & TVIS_SELECTED)!=0;
}
-static void winTreeSelectItem(Ihandle* ih, HTREEITEM hItem, int select)
+static void winTreeSelectNode(Ihandle* ih, HTREEITEM hItem, int select)
{
TV_ITEM item;
item.mask = TVIF_STATE | TVIF_HANDLE;
@@ -458,16 +331,13 @@ static void winTreeSelectItem(Ihandle* ih, HTREEITEM hItem, int select)
item.hItem = hItem;
if (select == -1)
- select = !winTreeIsItemSelected(ih, hItem);
+ select = !winTreeIsNodeSelected(ih, hItem); /* toggle */
item.state = select ? TVIS_SELECTED : 0;
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)&item);
-}
-
-static HTREEITEM winTreeGetFocusNode(Ihandle* ih)
-{
- return (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CARET, 0);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
}
/* ------------Comment from wxWidgets--------------------
@@ -475,17 +345,17 @@ static HTREEITEM winTreeGetFocusNode(Ihandle* ih)
item without changing anything else. */
static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
if (hItem != hItemFocus)
{
/* remember the selection state of the item */
- int wasSelected = winTreeIsItemSelected(ih, hItem);
+ int wasSelected = winTreeIsNodeSelected(ih, hItem);
int wasFocusSelected = 0;
- if (iupwinIsVista())
+ if (iupwinIsVistaOrNew() && iupwin_comctl32ver6)
iupAttribSetStr(ih, "_IUPTREE_ALLOW_CHANGE", (char*)hItem); /* Vista Only */
else
- wasFocusSelected = hItemFocus && winTreeIsItemSelected(ih, hItemFocus);
+ wasFocusSelected = hItemFocus && winTreeIsNodeSelected(ih, hItemFocus);
iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
@@ -493,58 +363,42 @@ static void winTreeSetFocusNode(Ihandle* ih, HTREEITEM hItem)
{
/* prevent the tree from unselecting the old focus which it would do by default */
SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)NULL); /* remove the focus */
- winTreeSelectItem(ih, hItemFocus, 1); /* select again */
+ winTreeSelectNode(ih, hItemFocus, 1); /* select again */
}
SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem); /* set focus, selection, and unselect the previous focus */
if (!wasSelected)
- winTreeSelectItem(ih, hItem, 0); /* need to clear the selection if was not selected */
+ winTreeSelectNode(ih, hItem, 0); /* need to clear the selection if was not selected */
iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
iupAttribSetStr(ih, "_IUPTREE_ALLOW_CHANGE", NULL);
}
}
-typedef struct _winTreeRange{
- HTREEITEM hItem1, hItem2;
- char inside, clear;
-}winTreeRange;
-
-static int winTreeSelectRangeFunc(Ihandle* ih, HTREEITEM hItem, winTreeRange* range)
+static void winTreeSelectRange(Ihandle* ih, HTREEITEM hItem1, HTREEITEM hItem2, int clear)
{
- int end_range = 0;
-
- if (range->inside == 0) /* detect the range start */
+ int i;
+ int id1 = iupTreeFindNodeId(ih, hItem1);
+ int id2 = iupTreeFindNodeId(ih, hItem2);
+ if (id2 == -1) id2 = ih->data->node_count-1;
+ if (id1 > id2)
{
- if (range->hItem1 == hItem) range->inside=1;
- else if (range->hItem2 == hItem) range->inside=1;
+ int tmp = id1;
+ id1 = id2;
+ id2 = tmp;
}
- else if (range->inside == 1) /* detect the range end */
+
+ for (i = 0; i < ih->data->node_count; i++)
{
- if (range->hItem1 == hItem) end_range=1;
- else if (range->hItem2 == hItem) end_range=1;
+ if (i < id1 || i > id2)
+ {
+ if (clear)
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 0);
+ }
+ else
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 1);
}
-
- if (range->inside == 1) /* if inside, select */
- winTreeSelectItem(ih, hItem, 1);
- else if (range->clear) /* if outside and clear, unselect */
- winTreeSelectItem(ih, hItem, 0);
-
- if (end_range || (range->inside && range->hItem1==range->hItem2))
- range->inside=-1; /* update after selecting the node */
-
- return 1;
-}
-
-static void winTreeSelectRange(Ihandle* ih, HTREEITEM hItemFrom, HTREEITEM hItemTo, int clear)
-{
- winTreeRange range;
- range.hItem1 = hItemFrom;
- range.hItem2 = hItemTo;
- range.inside = 0;
- range.clear = (char)clear;
- winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeSelectRangeFunc, &range);
}
static void winTreeSelectAll(Ihandle* ih)
@@ -558,9 +412,10 @@ static void winTreeClearSelection(Ihandle* ih, HTREEITEM hItemExcept)
winTreeSelectRange(ih, hItemExcept, hItemExcept, 1);
}
-static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, void* userdata)
+static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, int id, void* userdata)
{
- winTreeSelectItem(ih, hItem, -1);
+ (void)id;
+ winTreeSelectNode(ih, hItem, -1);
(void)userdata;
return 1;
}
@@ -568,14 +423,11 @@ static int winTreeInvertSelectFunc(Ihandle* ih, HTREEITEM hItem, void* userdata)
typedef struct _winTreeSelArray{
Iarray* markedArray;
char is_handle;
- int id_control;
}winTreeSelArray;
-static int winTreeSelectedArrayFunc(Ihandle* ih, HTREEITEM hItem, winTreeSelArray* selarray)
+static int winTreeSelectedArrayFunc(Ihandle* ih, HTREEITEM hItem, int id, winTreeSelArray* selarray)
{
- selarray->id_control++;
-
- if (winTreeIsItemSelected(ih, hItem))
+ if (winTreeIsNodeSelected(ih, hItem))
{
if (selarray->is_handle)
{
@@ -587,7 +439,7 @@ static int winTreeSelectedArrayFunc(Ihandle* ih, HTREEITEM hItem, winTreeSelArra
{
int* intArrayData = (int*)iupArrayInc(selarray->markedArray);
int i = iupArrayCount(selarray->markedArray);
- intArrayData[i-1] = selarray->id_control;
+ intArrayData[i-1] = id;
}
}
@@ -599,10 +451,9 @@ static Iarray* winTreeGetSelectedArray(Ihandle* ih)
Iarray* markedArray = iupArrayCreate(1, sizeof(HTREEITEM));
winTreeSelArray selarray;
selarray.markedArray = markedArray;
- selarray.id_control = -1;
selarray.is_handle = 1;
- winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);
+ iupTreeForEach(ih, (iupTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);
return markedArray;
}
@@ -612,10 +463,9 @@ static Iarray* winTreeGetSelectedArrayId(Ihandle* ih)
Iarray* markedArray = iupArrayCreate(1, sizeof(int));
winTreeSelArray selarray;
selarray.markedArray = markedArray;
- selarray.id_control = -1;
selarray.is_handle = 0;
- winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);
+ iupTreeForEach(ih, (iupTreeNodeFunc)winTreeSelectedArrayFunc, &selarray);
return markedArray;
}
@@ -625,7 +475,7 @@ static Iarray* winTreeGetSelectedArrayId(Ihandle* ih)
/* COPYING ITEMS (Branches and its children) */
/*****************************************************************************/
/* Insert the copied item in a new location. Returns the new item. */
-static HTREEITEM winTreeCopyItem(Ihandle* ih, HTREEITEM hItem, HTREEITEM hParent, HTREEITEM hPosition, int full_copy)
+static HTREEITEM winTreeCopyItem(Ihandle* ih, HTREEITEM hItem, HTREEITEM hParent, HTREEITEM hPosition, int is_copy)
{
TVITEM item;
TVINSERTSTRUCT tvins;
@@ -637,34 +487,34 @@ static HTREEITEM winTreeCopyItem(Ihandle* ih, HTREEITEM hItem, HTREEITEM hParent
item.cchTextMax = 255;
SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- if (full_copy) /* during a full copy the userdata reference is not copied */
+ if (is_copy) /* during a copy the itemdata reference is not reused */
{
/* create a new one */
winTreeItemData* itemDataNew = malloc(sizeof(winTreeItemData));
memcpy(itemDataNew, (void*)item.lParam, sizeof(winTreeItemData));
- itemDataNew->userdata = NULL;
item.lParam = (LPARAM)itemDataNew;
}
- /* Copy everything including user data reference */
+ /* Copy everything including itemdata reference */
tvins.item = item;
tvins.hInsertAfter = hPosition;
tvins.hParent = hParent;
- /* Add the node to the tree-view control */
+ /* Add the new node */
+ ih->data->node_count++;
return (HTREEITEM)SendMessage(ih->handle, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
}
-static void winTreeCopyChildren(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int full_copy)
+static void winTreeCopyChildren(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int is_copy)
{
HTREEITEM hChildSrc = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItemSrc);
- HTREEITEM hNewItem = TVI_FIRST;
+ HTREEITEM hItemNew = TVI_FIRST;
while (hChildSrc != NULL)
{
- hNewItem = winTreeCopyItem(ih, hChildSrc, hItemDst, hNewItem, full_copy); /* Use the same order they where enumerated */
+ hItemNew = winTreeCopyItem(ih, hChildSrc, hItemDst, hItemNew, is_copy); /* Use the same order they where enumerated */
/* Recursively transfer all the items */
- winTreeCopyChildren(ih, hChildSrc, hNewItem, full_copy);
+ winTreeCopyChildren(ih, hChildSrc, hItemNew, is_copy);
/* Go to next sibling item */
hChildSrc = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hChildSrc);
@@ -672,11 +522,18 @@ static void winTreeCopyChildren(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItem
}
/* Copies all items in a branch to a new location. Returns the new branch node. */
-static HTREEITEM winTreeCopyNode(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int full_copy)
+static HTREEITEM winTreeCopyMoveNode(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hItemDst, int is_copy)
{
- HTREEITEM hNewItem, hParent;
+ HTREEITEM hItemNew, hParent;
TVITEM item;
winTreeItemData* itemDataDst;
+ int id_new, count, id_src, id_dst;
+
+ int old_count = ih->data->node_count;
+
+ id_src = iupTreeFindNodeId(ih, hItemSrc);
+ id_dst = iupTreeFindNodeId(ih, hItemDst);
+ id_new = id_dst+1; /* contains the position for a copy operation */
/* Get DST node attributes */
item.hItem = hItemDst;
@@ -691,31 +548,64 @@ static HTREEITEM winTreeCopyNode(Ihandle* ih, HTREEITEM hItemSrc, HTREEITEM hIte
hItemDst = TVI_FIRST;
}
else
- {
+ {
+ if (itemDataDst->kind == ITREE_BRANCH)
+ {
+ int child_count = iupdrvTreeTotalChildCount(ih, hItemDst);
+ id_new += child_count;
+ }
+
/* copy as next brother of item or collapsed branch */
hParent = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItemDst);
}
- hNewItem = winTreeCopyItem(ih, hItemSrc, hParent, hItemDst, full_copy);
+ /* move to the same place does nothing */
+ if (!is_copy && id_new == id_src)
+ return NULL;
+
+ hItemNew = winTreeCopyItem(ih, hItemSrc, hParent, hItemDst, is_copy);
+
+ winTreeCopyChildren(ih, hItemSrc, hItemNew, is_copy);
+
+ count = ih->data->node_count - old_count;
+ iupTreeCopyMoveCache(ih, id_src, id_new, count, is_copy);
+
+ if (!is_copy)
+ {
+ /* Deleting the node (and its children) from the old position */
+ /* do not delete the itemdata, we reuse the references in CopyNode */
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+ SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemSrc);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
- winTreeCopyChildren(ih, hItemSrc, hNewItem, full_copy);
+ /* restore count, because we remove src */
+ ih->data->node_count = old_count;
- return hNewItem;
+ /* compensate position for a move */
+ if (id_new > id_src)
+ id_new -= count;
+ }
+
+ winTreeRebuildNodeCache(ih, id_new, hItemNew);
+
+ return hItemNew;
}
/*****************************************************************************/
/* MANIPULATING IMAGES */
/*****************************************************************************/
-static void winTreeUpdateImages(Ihandle* ih, HTREEITEM hItem, int mode)
+static void winTreeUpdateImages(Ihandle* ih, int mode)
{
- HTREEITEM hItemChild;
+ HTREEITEM hItem;
TVITEM item;
winTreeItemData* itemData;
+ int i;
/* called when one of the default images is changed */
-
- while(hItem != NULL)
+ for (i = 0; i < ih->data->node_count; i++)
{
+ hItem = ih->data->node_cache[i].node_handle;
+
/* Get node attributes */
item.hItem = hItem;
item.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE;
@@ -742,10 +632,6 @@ static void winTreeUpdateImages(Ihandle* ih, HTREEITEM hItem, int mode)
SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item);
}
}
-
- /* Recursively traverse child items */
- hItemChild = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
- winTreeUpdateImages(ih, hItemChild, mode);
}
else
{
@@ -756,9 +642,6 @@ static void winTreeUpdateImages(Ihandle* ih, HTREEITEM hItem, int mode)
SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item);
}
}
-
- /* Go to next sibling node */
- hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hItem);
}
}
@@ -828,29 +711,57 @@ static int winTreeCallBranchLeafCb(Ihandle* ih, HTREEITEM hItem)
if (itemData->kind == ITREE_BRANCH)
{
+ if (iupAttribGet(ih, "_IUPTREE_IGNORE_BRANCH_CB"))
+ return IUP_DEFAULT;
+
if (item.state & TVIS_EXPANDED)
{
IFni cbBranchClose = (IFni)IupGetCallback(ih, "BRANCHCLOSE_CB");
if (cbBranchClose)
- return cbBranchClose(ih, winTreeGetNodeId(ih, hItem));
+ return cbBranchClose(ih, iupTreeFindNodeId(ih, hItem));
}
else
{
IFni cbBranchOpen = (IFni)IupGetCallback(ih, "BRANCHOPEN_CB");
if (cbBranchOpen)
- return cbBranchOpen(ih, winTreeGetNodeId(ih, hItem));
+ return cbBranchOpen(ih, iupTreeFindNodeId(ih, hItem));
}
}
else
{
IFni cbExecuteLeaf = (IFni)IupGetCallback(ih, "EXECUTELEAF_CB");
if (cbExecuteLeaf)
- return cbExecuteLeaf(ih, winTreeGetNodeId(ih, hItem));
+ return cbExecuteLeaf(ih, iupTreeFindNodeId(ih, hItem));
}
return IUP_DEFAULT;
}
+static void winTreeCallMultiUnSelectionCb(Ihandle* ih)
+{
+ IFnIi cbMulti = (IFnIi)IupGetCallback(ih, "MULTIUNSELECTION_CB");
+ IFnii cbSelec = (IFnii)IupGetCallback(ih, "SELECTION_CB");
+ if (cbSelec || cbMulti)
+ {
+ Iarray* markedArray = winTreeGetSelectedArrayId(ih);
+ int* id_hitem = (int*)iupArrayGetData(markedArray);
+ int i, count = iupArrayCount(markedArray);
+
+ if (count > 1)
+ {
+ if (cbMulti)
+ cbMulti(ih, id_hitem, iupArrayCount(markedArray));
+ else
+ {
+ for (i=0; i<count; i++)
+ cbSelec(ih, id_hitem[i], 0);
+ }
+ }
+
+ iupArrayDestroy(markedArray);
+ }
+}
+
static void winTreeCallMultiSelectionCb(Ihandle* ih)
{
IFnIi cbMulti = (IFnIi)IupGetCallback(ih, "MULTISELECTION_CB");
@@ -885,6 +796,8 @@ static void winTreeCallSelectionCb(Ihandle* ih, int status, HTREEITEM hItem)
IFnii cbSelec = (IFnii)IupGetCallback(ih, "SELECTION_CB");
if (cbSelec)
{
+ int id;
+
if (ih->data->mark_mode == ITREE_MARK_MULTIPLE && IupGetCallback(ih,"MULTISELECTION_CB"))
{
if ((GetKeyState(VK_SHIFT) & 0x8000))
@@ -894,7 +807,9 @@ static void winTreeCallSelectionCb(Ihandle* ih, int status, HTREEITEM hItem)
if (iupAttribGet(ih, "_IUPTREE_IGNORE_SELECTION_CB"))
return;
- cbSelec(ih, winTreeGetNodeId(ih, hItem), status);
+ id = iupTreeFindNodeId(ih, hItem);
+ if (id != -1)
+ cbSelec(ih, id, status);
}
}
@@ -911,8 +826,8 @@ static int winTreeCallDragDropCb(Ihandle* ih, HTREEITEM hItemDrag, HTREEITEM hIt
if (cbDragDrop)
{
- int drag_id = winTreeGetNodeId(ih, hItemDrag);
- int drop_id = winTreeGetNodeId(ih, hItemDrop);
+ int drag_id = iupTreeFindNodeId(ih, hItemDrag);
+ int drop_id = iupTreeFindNodeId(ih, hItemDrop);
return cbDragDrop(ih, drag_id, drop_id, is_shift, *is_ctrl);
}
@@ -929,8 +844,8 @@ static int winTreeSetImageBranchExpandedAttrib(Ihandle* ih, const char* value)
{
ih->data->def_image_expanded = (void*)winTreeGetImageIndex(ih, value);
- /* Update all images, starting at root node */
- winTreeUpdateImages(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0), ITREE_UPDATEIMAGE_EXPANDED);
+ /* Update all images */
+ winTreeUpdateImages(ih, ITREE_UPDATEIMAGE_EXPANDED);
return 1;
}
@@ -939,8 +854,8 @@ static int winTreeSetImageBranchCollapsedAttrib(Ihandle* ih, const char* value)
{
ih->data->def_image_collapsed = (void*)winTreeGetImageIndex(ih, value);
- /* Update all images, starting at root node */
- winTreeUpdateImages(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0), ITREE_UPDATEIMAGE_COLLAPSED);
+ /* Update all images */
+ winTreeUpdateImages(ih, ITREE_UPDATEIMAGE_COLLAPSED);
return 1;
}
@@ -949,8 +864,8 @@ static int winTreeSetImageLeafAttrib(Ihandle* ih, const char* value)
{
ih->data->def_image_leaf = (void*)winTreeGetImageIndex(ih, value);
- /* Update all images, starting at root node */
- winTreeUpdateImages(ih, (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0), ITREE_UPDATEIMAGE_LEAF);
+ /* Update all images */
+ winTreeUpdateImages(ih, ITREE_UPDATEIMAGE_LEAF);
return 1;
}
@@ -959,7 +874,7 @@ static int winTreeSetImageExpandedAttrib(Ihandle* ih, const char* name_id, const
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -986,7 +901,7 @@ static int winTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* v
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -1025,7 +940,7 @@ static int winTreeSetImageAttrib(Ihandle* ih, const char* name_id, const char* v
static int winTreeSetTopItemAttrib(Ihandle* ih, const char* value)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, value);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, value);
if (hItem)
SendMessage(ih->handle, TVM_ENSUREVISIBLE, 0, (LPARAM)hItem);
return 0;
@@ -1056,9 +971,8 @@ static int winTreeSetSpacingAttrib(Ihandle* ih, const char* value)
static int winTreeSetExpandAllAttrib(Ihandle* ih, const char* value)
{
HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- HTREEITEM hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItemRoot); /* skip the root node that is always expanded */
int expand = iupStrBoolean(value);
- winTreeExpandTree(ih, hItem, expand);
+ winTreeExpandTree(ih, hItemRoot, expand);
return 0;
}
@@ -1131,7 +1045,7 @@ static char* winTreeGetTitle(Ihandle* ih, HTREEITEM hItem)
static char* winTreeGetTitleAttrib(Ihandle* ih, const char* name_id)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
return winTreeGetTitle(ih, hItem);
@@ -1140,10 +1054,13 @@ static char* winTreeGetTitleAttrib(Ihandle* ih, const char* name_id)
static int winTreeSetTitleAttrib(Ihandle* ih, const char* name_id, const char* value)
{
TVITEM item;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
+ if (!value)
+ value = "";
+
item.hItem = hItem;
item.mask = TVIF_HANDLE | TVIF_TEXT;
item.pszText = (char*)value;
@@ -1151,60 +1068,11 @@ static int winTreeSetTitleAttrib(Ihandle* ih, const char* name_id, const char* v
return 0;
}
-static char* winTreeGetFindUserDataAttrib(Ihandle* ih, const char* name_id)
-{
- int id;
- char* str = (char*)(name_id+1); /* skip ':' */
- void* userdata = NULL;
- if (sscanf(str, "%p", &userdata)!=1)
- return NULL;
- id = winTreeGetUserDataId(ih, userdata);
- if (id == -1)
- return NULL;
- str = iupStrGetMemory(16);
- sprintf(str, "%d", id);
- return str;
-}
-
-static char* winTreeGetUserDataAttrib(Ihandle* ih, const char* name_id)
-{
- TVITEM item;
- winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
- if (!hItem)
- return NULL;
-
- item.hItem = hItem;
- item.mask = TVIF_HANDLE | TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- return itemData->userdata;
-}
-
-static int winTreeSetUserDataAttrib(Ihandle* ih, const char* name_id, const char* value)
-{
- TVITEM item;
- winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
- if (!hItem)
- return 0;
-
- item.hItem = hItem;
- item.mask = TVIF_HANDLE | TVIF_PARAM;
- SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
- itemData = (winTreeItemData*)item.lParam;
-
- itemData->userdata = (void*)value;
-
- return 0;
-}
-
static char* winTreeGetTitleFontAttrib(Ihandle* ih, const char* name_id)
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1220,7 +1088,7 @@ static int winTreeSetTitleFontAttrib(Ihandle* ih, const char* name_id, const cha
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -1230,11 +1098,23 @@ static int winTreeSetTitleFontAttrib(Ihandle* ih, const char* name_id, const cha
itemData = (winTreeItemData*)item.lParam;
if (value)
+ {
itemData->hFont = iupwinGetHFont(value);
+ if (itemData->hFont)
+ {
+ TV_ITEM item;
+ item.mask = TVIF_STATE | TVIF_HANDLE | TVIF_TEXT;
+ item.stateMask = TVIS_BOLD;
+ item.hItem = hItem;
+ item.pszText = winTreeGetTitle(ih, hItem); /* reset text to resize item */
+ item.state = (strstr(value, "Bold")||strstr(value, "BOLD"))? TVIS_BOLD: 0;
+ SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)&item);
+ }
+ }
else
itemData->hFont = NULL;
- iupdrvDisplayUpdate(ih);
+ iupdrvPostRedraw(ih);
return 0;
}
@@ -1259,7 +1139,7 @@ static char* winTreeGetStateAttrib(Ihandle* ih, const char* name_id)
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1281,25 +1161,34 @@ static char* winTreeGetStateAttrib(Ihandle* ih, const char* name_id)
static int winTreeSetStateAttrib(Ihandle* ih, const char* name_id, const char* value)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ TVITEM item;
+ winTreeItemData* itemData;
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
- winTreeExpandItem(ih, hItem, iupStrEqualNoCase(value, "EXPANDED"));
+ /* Get Children: branch or leaf */
+ item.mask = TVIF_HANDLE|TVIF_PARAM;
+ item.hItem = hItem;
+ SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
+ itemData = (winTreeItemData*)item.lParam;
+
+ if (itemData->kind == ITREE_BRANCH)
+ winTreeExpandItem(ih, hItem, iupStrEqualNoCase(value, "EXPANDED"));
+
return 0;
}
static char* winTreeGetDepthAttrib(Ihandle* ih, const char* name_id)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- int depth = 0;
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
+ int depth = -1;
char* str;
- if (!hItem)
+ if (!hItem)
return NULL;
- while((hItemRoot != hItem) && (hItem != NULL))
+ while(hItem != NULL)
{
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hItem);
depth++;
@@ -1314,12 +1203,13 @@ static int winTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char
{
HTREEITEM hItemDst, hParent, hItemSrc;
- if (!ih->handle) /* do not store the action before map */
+ if (!ih->handle) /* do not do the action before map */
return 0;
- hItemSrc = winTreeFindNodeFromString(ih, name_id);
+
+ hItemSrc = iupTreeGetNodeFromString(ih, name_id);
if (!hItemSrc)
return 0;
- hItemDst = winTreeFindNodeFromString(ih, value);
+ hItemDst = iupTreeGetNodeFromString(ih, value);
if (!hItemDst)
return 0;
@@ -1332,11 +1222,8 @@ static int winTreeSetMoveNodeAttrib(Ihandle* ih, const char* name_id, const char
return 0;
}
- /* Copying the node and its children to the new position */
- winTreeCopyNode(ih, hItemSrc, hItemDst, 0); /* not a full copy, preserve user data */
-
- /* do not delete the user data, we copy the references in CopyNode */
- SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemSrc);
+ /* Move the node and its children to the new position */
+ winTreeCopyMoveNode(ih, hItemSrc, hItemDst, 0);
return 0;
}
@@ -1345,12 +1232,13 @@ static int winTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char
{
HTREEITEM hItemDst, hParent, hItemSrc;
- if (!ih->handle) /* do not store the action before map */
+ if (!ih->handle) /* do not do the action before map */
return 0;
- hItemSrc = winTreeFindNodeFromString(ih, name_id);
+
+ hItemSrc = iupTreeGetNodeFromString(ih, name_id);
if (!hItemSrc)
return 0;
- hItemDst = winTreeFindNodeFromString(ih, value);
+ hItemDst = iupTreeGetNodeFromString(ih, value);
if (!hItemDst)
return 0;
@@ -1363,8 +1251,8 @@ static int winTreeSetCopyNodeAttrib(Ihandle* ih, const char* name_id, const char
return 0;
}
- /* Copying the node and its children to the new position */
- winTreeCopyNode(ih, hItemSrc, hItemDst, 1);
+ /* Copy the node and its children to the new position */
+ winTreeCopyMoveNode(ih, hItemSrc, hItemDst, 1);
return 0;
}
@@ -1375,7 +1263,7 @@ static char* winTreeGetColorAttrib(Ihandle* ih, const char* name_id)
char* str;
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1398,7 +1286,7 @@ static int winTreeSetColorAttrib(Ihandle* ih, const char* name_id, const char* v
unsigned char r, g, b;
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -1410,7 +1298,7 @@ static int winTreeSetColorAttrib(Ihandle* ih, const char* name_id, const char* v
if (iupStrToRGB(value, &r, &g, &b))
{
itemData->color = RGB(r,g,b);
- iupdrvDisplayUpdate(ih);
+ iupdrvPostRedraw(ih);
}
return 0;
@@ -1435,7 +1323,7 @@ static char* winTreeGetChildCountAttrib(Ihandle* ih, const char* name_id)
{
int count;
char* str;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1454,18 +1342,11 @@ static char* winTreeGetChildCountAttrib(Ihandle* ih, const char* name_id)
return str;
}
-static char* winTreeGetCountAttrib(Ihandle* ih)
-{
- char* str = iupStrGetMemory(10);
- sprintf(str, "%d", (int)SendMessage(ih->handle, TVM_GETCOUNT, 0, 0));
- return str;
-}
-
static char* winTreeGetKindAttrib(Ihandle* ih, const char* name_id)
{
TVITEM item;
winTreeItemData* itemData;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1483,7 +1364,7 @@ static char* winTreeGetKindAttrib(Ihandle* ih, const char* name_id)
static char* winTreeGetParentAttrib(Ihandle* ih, const char* name_id)
{
char* str;
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
@@ -1492,15 +1373,13 @@ static char* winTreeGetParentAttrib(Ihandle* ih, const char* name_id)
return NULL;
str = iupStrGetMemory(10);
- sprintf(str, "%d", winTreeGetNodeId(ih, hItem));
+ sprintf(str, "%d", iupTreeFindNodeId(ih, hItem));
return str;
}
-static void winTreeDelNodeData(Ihandle* ih, HTREEITEM hItem)
+static void winTreeRemoveItemData(Ihandle* ih, HTREEITEM hItem, IFns cb, int id)
{
TVITEM item;
- HTREEITEM hChildItem;
-
item.hItem = hItem;
item.mask = TVIF_HANDLE|TVIF_PARAM;
if (SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item))
@@ -1508,81 +1387,153 @@ static void winTreeDelNodeData(Ihandle* ih, HTREEITEM hItem)
winTreeItemData* itemData = (winTreeItemData*)item.lParam;
if (itemData)
{
- IFnis cb = (IFnis)IupGetCallback(ih, "NODEREMOVED_CB");
- if (cb) cb(ih, winTreeGetNodeId(ih, hItem), (char*)itemData->userdata);
+ if (cb)
+ cb(ih, (char*)ih->data->node_cache[id].userdata);
+
free(itemData);
item.lParam = (LPARAM)NULL;
SendMessage(ih->handle, TVM_SETITEM, 0, (LPARAM)(LPTVITEM)&item);
}
}
+}
+
+static void winTreeRemoveNodeDataRec(Ihandle* ih, HTREEITEM hItem, IFns cb, int *id)
+{
+ int old_id = *id;
- hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
+ /* Check whether we have child items */
+ /* remove from children first */
+ HTREEITEM hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
while (hChildItem)
{
- winTreeDelNodeData(ih, hChildItem);
+ /* go recursive to children */
+ winTreeRemoveNodeDataRec(ih, hChildItem, cb, id);
+
+ /* Go to next sibling item */
hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)hChildItem);
}
+
+ /* actually do it for the node */
+ ih->data->node_count--;
+ (*id)++;
+
+ winTreeRemoveItemData(ih, hItem, cb, old_id);
+}
+
+static void winTreeRemoveNodeData(Ihandle* ih, HTREEITEM hItem, int call_cb)
+{
+ IFns cb = call_cb? (IFns)IupGetCallback(ih, "NODEREMOVED_CB"): NULL;
+ int old_count = ih->data->node_count;
+ int id = iupTreeFindNodeId(ih, hItem);
+ int old_id = id;
+
+ winTreeRemoveNodeDataRec(ih, hItem, cb, &id);
+
+ if (call_cb)
+ iupTreeDelFromCache(ih, old_id, old_count-ih->data->node_count);
+}
+
+static void winTreeRemoveAllNodeData(Ihandle* ih, int call_cb)
+{
+ IFns cb = call_cb? (IFns)IupGetCallback(ih, "NODEREMOVED_CB"): NULL;
+ int i, old_count = ih->data->node_count;
+ HTREEITEM hItem;
+
+ for (i = 0; i < ih->data->node_count; i++)
+ {
+ hItem = ih->data->node_cache[i].node_handle;
+ winTreeRemoveItemData(ih, hItem, cb, i);
+ }
+
+ ih->data->node_count = 0;
+
+ if (call_cb)
+ iupTreeDelFromCache(ih, 0, old_count);
}
static int winTreeSetDelNodeAttrib(Ihandle* ih, const char* name_id, const char* value)
{
- if (!ih->handle) /* do not store the action before map */
+ if (!ih->handle) /* do not do the action before map */
return 0;
- if(iupStrEqualNoCase(value, "SELECTED")) /* selected here means the specified one */
+ if (iupStrEqualNoCase(value, "ALL"))
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
+ winTreeRemoveAllNodeData(ih, 1);
- /* the root node can't be deleted */
- if(!hItem || hItem == hItemRoot)
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+ SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
+ return 0;
+ }
+ if (iupStrEqualNoCase(value, "SELECTED")) /* selected here means the reference one */
+ {
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
+ if(!hItem)
return 0;
- /* deleting the specified node (and it's children) */
- winTreeDelNodeData(ih, hItem);
+ /* deleting the reference node (and it's children) */
+ winTreeRemoveNodeData(ih, hItem, 1);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItem);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
return 0;
}
- else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the specified one */
+ else if(iupStrEqualNoCase(value, "CHILDREN")) /* children of the reference node */
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
HTREEITEM hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
if(!hItem)
return 0;
- /* deleting the selected node's children */
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+
+ /* deleting the reference node children */
while (hChildItem)
{
- winTreeDelNodeData(ih, hChildItem);
+ winTreeRemoveNodeData(ih, hChildItem, 1);
SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hChildItem);
hChildItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hItem);
}
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
return 0;
}
else if(iupStrEqualNoCase(value, "MARKED"))
{
- int i, count;
- Iarray* markedArray;
- HTREEITEM* hItemArrayData;
- HTREEITEM hItemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
+ int i, del_focus = 0;
+ HTREEITEM hItemFocus;
- /* Delete the array of marked nodes */
- markedArray = winTreeGetSelectedArray(ih);
- hItemArrayData = (HTREEITEM*)iupArrayGetData(markedArray);
- count = iupArrayCount(markedArray);
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+ hItemFocus = iupdrvTreeGetFocusNode(ih);
- for(i = 0; i < count; i++)
+ for(i = 1; i < ih->data->node_count; /* increment only if not removed */)
{
- if (hItemArrayData[i] != hItemRoot) /* the root node can't be deleted */
+ if (winTreeIsNodeSelected(ih, ih->data->node_cache[i].node_handle))
{
- winTreeDelNodeData(ih, hItemArrayData[i]);
- SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemArrayData[i]);
+ HTREEITEM hItem = ih->data->node_cache[i].node_handle;
+ if (hItemFocus == hItem)
+ {
+ del_focus = 1;
+ i++;
+ }
+ else
+ {
+ winTreeRemoveNodeData(ih, hItem, 1);
+ SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItem);
+ }
}
+ else
+ i++;
}
- iupArrayDestroy(markedArray);
+ if (del_focus)
+ {
+ winTreeRemoveNodeData(ih, hItemFocus, 1);
+ SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemFocus);
+ }
+
+ iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
return 0;
}
@@ -1592,22 +1543,13 @@ static int winTreeSetDelNodeAttrib(Ihandle* ih, const char* name_id, const char*
static int winTreeSetRenameAttrib(Ihandle* ih, const char* value)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
if (ih->data->show_rename)
{
- IFni cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB");
- if (cbShowRename)
- cbShowRename(ih, winTreeGetNodeId(ih, hItemFocus));
-
+ HTREEITEM hItemFocus;
SetFocus(ih->handle); /* the tree must have focus to activate the edit */
+ hItemFocus = iupdrvTreeGetFocusNode(ih);
SendMessage(ih->handle, TVM_EDITLABEL, 0, (LPARAM)hItemFocus);
}
- else
- {
- IFnis cbRenameNode = (IFnis)IupGetCallback(ih, "RENAMENODE_CB");
- if (cbRenameNode)
- cbRenameNode(ih, winTreeGetNodeId(ih, hItemFocus), winTreeGetTitle(ih, hItemFocus));
- }
(void)value;
return 0;
@@ -1615,11 +1557,11 @@ static int winTreeSetRenameAttrib(Ihandle* ih, const char* value)
static char* winTreeGetMarkedAttrib(Ihandle* ih, const char* name_id)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return NULL;
- if (winTreeIsItemSelected(ih, hItem))
+ if (winTreeIsNodeSelected(ih, hItem))
return "YES";
else
return "NO";
@@ -1627,17 +1569,23 @@ static char* winTreeGetMarkedAttrib(Ihandle* ih, const char* name_id)
static int winTreeSetMarkedAttrib(Ihandle* ih, const char* name_id, const char* value)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
- winTreeSelectItem(ih, hItem, iupStrBoolean(value));
+ if (ih->data->mark_mode==ITREE_MARK_SINGLE)
+ {
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
+ winTreeSelectNode(ih, hItemFocus, 0);
+ }
+
+ winTreeSelectNode(ih, hItem, iupStrBoolean(value));
return 0;
}
static int winTreeSetMarkStartAttrib(Ihandle* ih, const char* name_id)
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, name_id);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, name_id);
if (!hItem)
return 0;
@@ -1649,15 +1597,59 @@ static int winTreeSetMarkStartAttrib(Ihandle* ih, const char* name_id)
static char* winTreeGetValueAttrib(Ihandle* ih)
{
char* str;
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
if (!hItemFocus)
- return "0"; /* default VALUE is root */
+ {
+ if (ih->data->node_count)
+ return "0"; /* default VALUE is root */
+ else
+ return "-1";
+ }
str = iupStrGetMemory(16);
- sprintf(str, "%d", winTreeGetNodeId(ih, hItemFocus));
+ sprintf(str, "%d", iupTreeFindNodeId(ih, hItemFocus));
+ return str;
+}
+
+static char* winTreeGetMarkedNodesAttrib(Ihandle* ih)
+{
+ char* str = iupStrGetMemory(ih->data->node_count+1);
+ int i;
+
+ for (i=0; i<ih->data->node_count; i++)
+ {
+ if (winTreeIsNodeSelected(ih, ih->data->node_cache[i].node_handle))
+ str[i] = '+';
+ else
+ str[i] = '-';
+ }
+
+ str[ih->data->node_count] = 0;
return str;
}
+static int winTreeSetMarkedNodesAttrib(Ihandle* ih, const char* value)
+{
+ int count, i;
+
+ if (ih->data->mark_mode==ITREE_MARK_SINGLE || !value)
+ return 0;
+
+ count = strlen(value);
+ if (count > ih->data->node_count)
+ count = ih->data->node_count;
+
+ for (i=0; i<count; i++)
+ {
+ if (value[i] == '+')
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 1);
+ else
+ winTreeSelectNode(ih, ih->data->node_cache[i].node_handle, 0);
+ }
+
+ return 0;
+}
+
static int winTreeSetMarkAttrib(Ihandle* ih, const char* value)
{
if (ih->data->mark_mode==ITREE_MARK_SINGLE)
@@ -1665,7 +1657,7 @@ static int winTreeSetMarkAttrib(Ihandle* ih, const char* value)
if(iupStrEqualNoCase(value, "BLOCK"))
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
winTreeSelectRange(ih, (HTREEITEM)iupAttribGet(ih, "_IUPTREE_MARKSTART_NODE"), hItemFocus, 0);
}
else if(iupStrEqualNoCase(value, "CLEARALL"))
@@ -1673,14 +1665,14 @@ static int winTreeSetMarkAttrib(Ihandle* ih, const char* value)
else if(iupStrEqualNoCase(value, "MARKALL"))
winTreeSelectAll(ih);
else if(iupStrEqualNoCase(value, "INVERTALL")) /* INVERTALL *MUST* appear before INVERT, or else INVERTALL will never be called. */
- winTreeForEach(ih, NULL, (winTreeNodeFunc)winTreeInvertSelectFunc, NULL);
+ iupTreeForEach(ih, (iupTreeNodeFunc)winTreeInvertSelectFunc, NULL);
else if(iupStrEqualPartial(value, "INVERT")) /* iupStrEqualPartial allows the use of "INVERTid" form */
{
- HTREEITEM hItem = winTreeFindNodeFromString(ih, &value[strlen("INVERT")]);
+ HTREEITEM hItem = iupTreeGetNodeFromString(ih, &value[strlen("INVERT")]);
if (!hItem)
return 0;
- winTreeSelectItem(ih, hItem, -1); /* toggle */
+ winTreeSelectNode(ih, hItem, -1); /* toggle */
}
else
{
@@ -1690,10 +1682,10 @@ static int winTreeSetMarkAttrib(Ihandle* ih, const char* value)
if (iupStrToStrStr(value, str1, str2, '-')!=2)
return 0;
- hItem1 = winTreeFindNodeFromString(ih, str1);
+ hItem1 = iupTreeGetNodeFromString(ih, str1);
if (!hItem1)
return 0;
- hItem2 = winTreeFindNodeFromString(ih, str2);
+ hItem2 = iupTreeGetNodeFromString(ih, str2);
if (!hItem2)
return 0;
@@ -1711,9 +1703,9 @@ static int winTreeSetValueAttrib(Ihandle* ih, const char* value)
if (winTreeSetMarkAttrib(ih, value))
return 0;
- hItemFocus = winTreeGetFocusNode(ih);
+ hItemFocus = iupdrvTreeGetFocusNode(ih);
- if(iupStrEqualNoCase(value, "ROOT"))
+ if(iupStrEqualNoCase(value, "ROOT") || iupStrEqualNoCase(value, "FIRST"))
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
else if(iupStrEqualNoCase(value, "LAST"))
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0);
@@ -1759,15 +1751,14 @@ static int winTreeSetValueAttrib(Ihandle* ih, const char* value)
else if(iupStrEqualNoCase(value, "PREVIOUS"))
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItemFocus);
else
- hItem = winTreeFindNodeFromString(ih, value);
+ hItem = iupTreeGetNodeFromString(ih, value);
if (hItem)
{
if (ih->data->mark_mode==ITREE_MARK_SINGLE)
{
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
- winTreeSelectItem(ih, hItem, 1);
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
+ winTreeSelectNode(ih, hItemFocus, 0);
+ winTreeSelectNode(ih, hItem, 1);
}
winTreeSetFocusNode(ih, hItem);
}
@@ -1832,27 +1823,60 @@ static LRESULT CALLBACK winTreeEditWinProc(HWND hwnd, UINT msg, WPARAM wp, LPARA
return CallWindowProc(oldProc, hwnd, msg, wp, lp);
}
-static void winTreeDrag(Ihandle* ih, int x, int y)
+static void winTreeBeginDrag(Ihandle* ih, int x, int y)
{
- HTREEITEM hItemDrop;
+ HIMAGELIST dragImageList;
+
+ HTREEITEM hItemDrag = winTreeFindNodeXY(ih, x, y);
+ if (!hItemDrag)
+ return;
+
+ SendMessage(ih->handle, TVM_ENDEDITLABELNOW, TRUE, 0);
+
+ /* store the drag-and-drop item */
+ iupAttribSetStr(ih, "_IUPTREE_DRAGITEM", (char*)hItemDrag);
+ /* get the image list for dragging */
+ dragImageList = (HIMAGELIST)SendMessage(ih->handle, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItemDrag);
+ if (dragImageList)
+ {
+ POINT pt;
+ ImageList_BeginDrag(dragImageList, 0, 0, 0);
+
+ pt.x = x;
+ pt.y = y;
+
+ ClientToScreen(ih->handle, &pt);
+ ImageList_DragEnter(NULL, pt.x, pt.y);
+
+ iupAttribSetStr(ih, "_IUPTREE_DRAGIMAGELIST", (char*)dragImageList);
+ }
+
+ ShowCursor(FALSE);
+ SetCapture(ih->handle); /* drag only inside the tree */
+}
+
+static void winTreeDrag(Ihandle* ih, int x, int y)
+{
+ HTREEITEM hItemDrop = winTreeFindNodeXY(ih, x, y);
+ HTREEITEM hItemDrag = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_DRAGITEM");
HIMAGELIST dragImageList = (HIMAGELIST)iupAttribGet(ih, "_IUPTREE_DRAGIMAGELIST");
+
if (dragImageList)
{
- POINT pnt;
- pnt.x = x;
- pnt.y = y;
- GetCursorPos(&pnt);
- ClientToScreen(GetDesktopWindow(), &pnt) ;
- ImageList_DragMove(pnt.x, pnt.y);
+ POINT pt;
+ pt.x = x;
+ pt.y = y;
+ ClientToScreen(ih->handle, &pt);
+ ImageList_DragMove(pt.x, pt.y);
}
- if ((hItemDrop = winTreeFindNodePointed(ih)) != NULL)
+ if (hItemDrop && hItemDrop!=hItemDrag)
{
if(dragImageList)
ImageList_DragShowNolock(FALSE);
- SendMessage(ih->handle, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)hItemDrop);
+ SendMessage(ih->handle, TVM_SETINSERTMARK, TRUE, (LPARAM)hItemDrop);
/* store the drop item to be executed */
iupAttribSetStr(ih, "_IUPTREE_DROPITEM", (char*)hItemDrop);
@@ -1860,6 +1884,8 @@ static void winTreeDrag(Ihandle* ih, int x, int y)
if(dragImageList)
ImageList_DragShowNolock(TRUE);
}
+ else
+ iupAttribSetStr(ih, "_IUPTREE_DROPITEM", NULL);
}
static void winTreeDrop(Ihandle* ih)
@@ -1882,7 +1908,7 @@ static void winTreeDrop(Ihandle* ih)
ShowCursor(TRUE);
/* Remove drop target highlighting */
- SendMessage(ih->handle, TVM_SELECTITEM, TVGN_DROPHILITE, (LPARAM)NULL);
+ SendMessage(ih->handle, TVM_SETINSERTMARK, 0, (LPARAM)NULL);
iupAttribSetStr(ih, "_IUPTREE_DRAGITEM", NULL);
iupAttribSetStr(ih, "_IUPTREE_DROPITEM", NULL);
@@ -1901,16 +1927,12 @@ static void winTreeDrop(Ihandle* ih)
if (winTreeCallDragDropCb(ih, hItemDrag, hItemDrop, &is_ctrl) == IUP_CONTINUE)
{
- /* Copy the dragged item to the new position. */
- HTREEITEM hItemNew = winTreeCopyNode(ih, hItemDrag, hItemDrop, is_ctrl);
-
- if (!is_ctrl)
- {
- /* do not delete the user data, we copy the references in CopyNode */
- SendMessage(ih->handle, TVM_DELETEITEM, 0, (LPARAM)hItemDrag);
- }
+ /* Copy or move the dragged item to the new position. */
+ HTREEITEM hItemNew = winTreeCopyMoveNode(ih, hItemDrag, hItemDrop, is_ctrl);
- SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItemNew); /* set focus and selection */
+ /* Set focus and selection */
+ if (hItemNew)
+ SendMessage(ih->handle, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItemNew);
}
}
@@ -1929,9 +1951,7 @@ static void winTreeExtendSelect(Ihandle* ih, int x, int y)
hItemFirstSel = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_FIRSTSELITEM");
if (hItemFirstSel)
{
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
winTreeSelectRange(ih, hItemFirstSel, hItem, 1);
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
iupAttribSetStr(ih, "_IUPTREE_LASTSELITEM", (char*)hItem);
winTreeSetFocusNode(ih, hItem);
@@ -1952,10 +1972,10 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y)
if (GetKeyState(VK_CONTROL) & 0x8000) /* Control key is down */
{
/* Toggle selection state */
- winTreeSelectItem(ih, hItem, -1);
+ winTreeSelectNode(ih, hItem, -1);
iupAttribSetStr(ih, "_IUPTREE_FIRSTSELITEM", (char*)hItem);
- winTreeCallSelectionCb(ih, winTreeIsItemSelected(ih, hItem), hItem);
+ winTreeCallSelectionCb(ih, winTreeIsNodeSelected(ih, hItem), hItem);
winTreeSetFocusNode(ih, hItem);
return 1;
@@ -1965,9 +1985,11 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y)
HTREEITEM hItemFirstSel = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_FIRSTSELITEM");
if (hItemFirstSel)
{
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
+ int last_id = iupTreeFindNodeId(ih, hItem);
winTreeSelectRange(ih, hItemFirstSel, hItem, 1);
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
+
+ /* if last selected item is a branch, then select its children */
+ iupTreeSelectLastCollapsedBranch(ih, &last_id);
winTreeCallMultiSelectionCb(ih);
winTreeSetFocusNode(ih, hItem);
@@ -1975,11 +1997,15 @@ static int winTreeMouseMultiSelect(Ihandle* ih, int x, int y)
}
}
+ winTreeCallMultiUnSelectionCb(ih);
+
/* simple click */
winTreeClearSelection(ih, hItem);
iupAttribSetStr(ih, "_IUPTREE_FIRSTSELITEM", (char*)hItem);
iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", "1");
+ /* Call SELECT_CB for all unselected nodes */
+
return 0;
}
@@ -2039,7 +2065,7 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
if (wp == VK_RETURN)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
if (winTreeCallBranchLeafCb(ih, hItemFocus) != IUP_IGNORE)
winTreeExpandItem(ih, hItemFocus, -1);
@@ -2056,14 +2082,14 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
{
if (GetKeyState(VK_CONTROL) & 0x8000)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
/* Toggle selection state */
- winTreeSelectItem(ih, hItemFocus, -1);
+ winTreeSelectNode(ih, hItemFocus, -1);
}
}
else if (wp == VK_UP || wp == VK_DOWN)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
if (wp == VK_UP)
hItemFocus = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_PREVIOUSVISIBLE, (LPARAM)hItemFocus);
else
@@ -2084,9 +2110,7 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
HTREEITEM hItemFirstSel = (HTREEITEM)iupAttribGet(ih, "_IUPTREE_FIRSTSELITEM");
if (hItemFirstSel)
{
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", "1");
winTreeSelectRange(ih, hItemFirstSel, hItemFocus, 1);
- iupAttribSetStr(ih, "_IUPTREE_IGNORE_SELECTION_CB", NULL);
winTreeCallMultiSelectionCb(ih);
winTreeSetFocusNode(ih, hItemFocus);
@@ -2138,10 +2162,20 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
}
break;
case WM_MOUSEMOVE:
- if (ih->data->show_dragdrop && (HTREEITEM)iupAttribGet(ih, "_IUPTREE_DRAGITEM") != NULL)
- winTreeDrag(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ if (ih->data->show_dragdrop && (wp & MK_LBUTTON))
+ {
+ if (!iupAttribGet(ih, "_IUPTREE_DRAGITEM"))
+ winTreeBeginDrag(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ else
+ winTreeDrag(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ }
else if (iupAttribGet(ih, "_IUPTREE_EXTENDSELECT"))
- winTreeExtendSelect(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ {
+ if (wp & MK_LBUTTON)
+ winTreeExtendSelect(ih, (int)(short)LOWORD(lp), (int)(short)HIWORD(lp));
+ else
+ iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", NULL);
+ }
iupwinMouseMove(ih, msg, wp, lp);
break;
@@ -2157,6 +2191,7 @@ static int winTreeProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *res
if (iupAttribGet(ih, "_IUPTREE_EXTENDSELECT"))
{
iupAttribSetStr(ih, "_IUPTREE_EXTENDSELECT", NULL);
+
if (iupAttribGet(ih, "_IUPTREE_LASTSELITEM"))
{
winTreeCallMultiSelectionCb(ih);
@@ -2205,14 +2240,19 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
else if (msg_info->code == TVN_SELCHANGED)
{
NMTREEVIEW* info = (NMTREEVIEW*)msg_info;
- winTreeCallSelectionCb(ih, 0, info->itemOld.hItem); /* node unselected */
- winTreeCallSelectionCb(ih, 1, info->itemNew.hItem); /* node selected */
+ if (ih->data->mark_mode!=ITREE_MARK_MULTIPLE || /* (NOT) Multiple selection with Control or Shift key is down */
+ !(GetKeyState(VK_CONTROL) & 0x8000 || GetKeyState(VK_SHIFT) & 0x8000))
+ {
+ winTreeCallSelectionCb(ih, 0, info->itemOld.hItem); /* node unselected */
+ winTreeCallSelectionCb(ih, 1, info->itemNew.hItem); /* node selected */
+ }
}
else if(msg_info->code == TVN_BEGINLABELEDIT)
{
char* value;
HWND hEdit;
NMTVDISPINFO* info = (NMTVDISPINFO*)msg_info;
+ IFni cbShowRename;
if (iupAttribGet(ih, "_IUPTREE_EXTENDSELECT"))
{
@@ -2220,6 +2260,13 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
return 1;
}
+ cbShowRename = (IFni)IupGetCallback(ih, "SHOWRENAME_CB");
+ if (cbShowRename && cbShowRename(ih, iupTreeFindNodeId(ih, info->item.hItem))==IUP_IGNORE)
+ {
+ *result = TRUE; /* prevent the change */
+ return 1;
+ }
+
hEdit = (HWND)SendMessage(ih->handle, TVM_GETEDITCONTROL, 0, 0);
/* save the edit box. */
@@ -2253,57 +2300,30 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
}
else if(msg_info->code == TVN_ENDLABELEDIT)
{
+ IFnis cbRename;
NMTVDISPINFO* info = (NMTVDISPINFO*)msg_info;
iupAttribSetStr(ih, "_IUPWIN_EDITBOX", NULL);
- if (info->item.pszText)
- {
- IFnis cbRename = (IFnis)IupGetCallback(ih, "RENAME_CB");
- if (cbRename)
- {
- if (cbRename(ih, winTreeGetNodeId(ih, info->item.hItem), info->item.pszText) == IUP_IGNORE)
- {
- *result = FALSE;
- return 1;
- }
- }
+ if (!info->item.pszText) /* cancel, so abort */
+ return 0;
- *result = TRUE;
- return 1;
- }
- }
- else if(msg_info->code == TVN_BEGINDRAG)
- {
- if (ih->data->show_dragdrop)
+ cbRename = (IFnis)IupGetCallback(ih, "RENAME_CB");
+ if (cbRename)
{
- NMTREEVIEW* pNMTreeView = (NMTREEVIEW*)msg_info;
- HTREEITEM hItemDrag = pNMTreeView->itemNew.hItem;
- HIMAGELIST dragImageList;
-
- /* store the drag-and-drop item */
- iupAttribSetStr(ih, "_IUPTREE_DRAGITEM", (char*)hItemDrag);
-
- /* get the image list for dragging */
- dragImageList = (HIMAGELIST)SendMessage(ih->handle, TVM_CREATEDRAGIMAGE, 0, (LPARAM)hItemDrag);
- if (dragImageList)
+ if (cbRename(ih, iupTreeFindNodeId(ih, info->item.hItem), info->item.pszText) == IUP_IGNORE)
{
- POINT pt = pNMTreeView->ptDrag;
- ImageList_BeginDrag(dragImageList, 0, 0, 0);
-
- ClientToScreen(ih->handle, &pt);
- ImageList_DragEnter(NULL, pt.x, pt.y);
-
- iupAttribSetStr(ih, "_IUPTREE_DRAGIMAGELIST", (char*)dragImageList);
+ *result = FALSE;
+ return 1;
}
-
- ShowCursor(FALSE);
- SetCapture(ih->handle); /* drag only inside the tree */
}
+
+ *result = TRUE;
+ return 1;
}
else if(msg_info->code == NM_DBLCLK)
{
- HTREEITEM hItemFocus = winTreeGetFocusNode(ih);
+ HTREEITEM hItemFocus = iupdrvTreeGetFocusNode(ih);
TVITEM item;
winTreeItemData* itemData;
@@ -2317,7 +2337,7 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
{
IFni cbExecuteLeaf = (IFni)IupGetCallback(ih, "EXECUTELEAF_CB");
if(cbExecuteLeaf)
- cbExecuteLeaf(ih, winTreeGetNodeId(ih, hItemFocus));
+ cbExecuteLeaf(ih, iupTreeFindNodeId(ih, hItemFocus));
}
}
else if(msg_info->code == TVN_ITEMEXPANDING)
@@ -2351,7 +2371,7 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
HTREEITEM hItem = winTreeFindNodePointed(ih);
IFni cbRightClick = (IFni)IupGetCallback(ih, "RIGHTCLICK_CB");
if (cbRightClick)
- cbRightClick(ih, winTreeGetNodeId(ih, hItem));
+ cbRightClick(ih, iupTreeFindNodeId(ih, hItem));
}
else if (msg_info->code == NM_CUSTOMDRAW)
{
@@ -2374,7 +2394,7 @@ static int winTreeWmNotify(Ihandle* ih, NMHDR* msg_info, int *result)
SendMessage(ih->handle, TVM_GETITEM, 0, (LPARAM)(LPTVITEM)&item);
itemData = (winTreeItemData*)item.lParam;
- if (winTreeIsItemSelected(ih, hItem))
+ if (GetFocus()==ih->handle && (customdraw->nmcd.uItemState & CDIS_SELECTED))
customdraw->clrText = winTreeInvertColor(itemData->color);
else
customdraw->clrText = itemData->color;
@@ -2402,47 +2422,34 @@ static int winTreeConvertXYToPos(Ihandle* ih, int x, int y)
info.pt.y = y;
hItem = (HTREEITEM)SendMessage(ih->handle, TVM_HITTEST, 0, (LPARAM)&info);
if (hItem)
- return winTreeGetNodeId(ih, hItem);
+ return iupTreeFindNodeId(ih, hItem);
return -1;
}
/*******************************************************************************************/
-static void winTreeUnMapMethod(Ihandle* ih)
-{
- Iarray* bmp_array;
- HIMAGELIST image_list;
-
- HTREEITEM itemRoot = (HTREEITEM)SendMessage(ih->handle, TVM_GETNEXTITEM, TVGN_ROOT, 0);
- winTreeDelNodeData(ih, itemRoot);
-
- image_list = (HIMAGELIST)SendMessage(ih->handle, TVM_GETIMAGELIST, TVSIL_NORMAL, 0);
- if (image_list)
- ImageList_Destroy(image_list);
-
- bmp_array = (Iarray*)iupAttribGet(ih, "_IUPWIN_BMPARRAY");
- if (bmp_array)
- iupArrayDestroy(bmp_array);
-
- iupdrvBaseUnMapMethod(ih);
-}
static int winTreeMapMethod(Ihandle* ih)
{
- DWORD dwStyle = WS_CHILD | WS_BORDER | TVS_SHOWSELALWAYS;
+ DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | WS_BORDER | TVS_SHOWSELALWAYS;
- /* can be set only on the Tree View creation */
+ /* styles can be set only on the Tree View creation */
- if (!ih->data->show_dragdrop)
- dwStyle |= TVS_DISABLEDRAGDROP;
+ /* always disable the internal drag&drop, because it affects our selection and drawing */
+ dwStyle |= TVS_DISABLEDRAGDROP;
if (ih->data->show_rename)
dwStyle |= TVS_EDITLABELS;
if (!iupAttribGetBoolean(ih, "HIDELINES"))
+ {
dwStyle |= TVS_HASLINES;
+ if (!iupAttribGetInt(ih, "ADDROOT"))
+ dwStyle |= TVS_LINESATROOT;
+ }
+
if (!iupAttribGetBoolean(ih, "HIDEBUTTONS"))
dwStyle |= TVS_HASBUTTONS;
@@ -2455,6 +2462,11 @@ static int winTreeMapMethod(Ihandle* ih)
if (!iupwinCreateWindowEx(ih, WC_TREEVIEW, 0, dwStyle))
return IUP_ERROR;
+ if (!iupwin_comctl32ver6) /* To improve drawing of items when TITLEFONT is set */
+ SendMessage(ih->handle, CCM_SETVERSION, 5, 0);
+ else
+ SendMessage(ih->handle, TVM_SETEXTENDEDSTYLE, TVS_EX_DOUBLEBUFFER, TVS_EX_DOUBLEBUFFER);
+
IupSetCallback(ih, "_IUPWIN_CTRLPROC_CB", (Icallback)winTreeProc);
IupSetCallback(ih, "_IUPWIN_NOTIFY_CB", (Icallback)winTreeWmNotify);
@@ -2466,7 +2478,7 @@ static int winTreeMapMethod(Ihandle* ih)
winTreeSetBgColorAttrib(ih, value);
iupAttribSetStr(ih, "BGCOLOR", NULL);
}
- else if (iupwinGetSystemMajorVersion()<6) /* force background in XP because of the editbox background */
+ else if (!iupwin_comctl32ver6 || iupwinGetSystemMajorVersion()<6) /* force background in XP because of the editbox background */
winTreeSetBgColorAttrib(ih, IupGetGlobal("TXTBGCOLOR"));
}
@@ -2475,8 +2487,8 @@ static int winTreeMapMethod(Ihandle* ih)
ih->data->def_image_collapsed = (void*)winTreeGetImageIndex(ih, "IMGCOLLAPSED");
ih->data->def_image_expanded = (void*)winTreeGetImageIndex(ih, "IMGEXPANDED");
- /* Add the Root Node */
- winTreeAddRootNode(ih);
+ if (iupAttribGetInt(ih, "ADDROOT"))
+ iupdrvTreeAddNode(ih, "-1", ITREE_BRANCH, "", 0);
/* configure for DRAG&DROP of files */
if (IupGetCallback(ih, "DROPFILES_CB"))
@@ -2484,9 +2496,31 @@ static int winTreeMapMethod(Ihandle* ih)
IupSetCallback(ih, "_IUP_XY2POS_CB", (Icallback)winTreeConvertXYToPos);
+ iupdrvTreeUpdateMarkMode(ih);
+
return IUP_NOERROR;
}
+static void winTreeUnMapMethod(Ihandle* ih)
+{
+ Iarray* bmp_array;
+ HIMAGELIST image_list;
+
+ winTreeRemoveAllNodeData(ih, 0);
+
+ ih->data->node_count = 0;
+
+ image_list = (HIMAGELIST)SendMessage(ih->handle, TVM_GETIMAGELIST, TVSIL_NORMAL, 0);
+ if (image_list)
+ ImageList_Destroy(image_list);
+
+ bmp_array = (Iarray*)iupAttribGet(ih, "_IUPWIN_BMPARRAY");
+ if (bmp_array)
+ iupArrayDestroy(bmp_array);
+
+ iupdrvBaseUnMapMethod(ih);
+}
+
void iupdrvTreeInitClass(Iclass* ic)
{
/* Driver Dependent Class functions */
@@ -2500,7 +2534,6 @@ void iupdrvTreeInitClass(Iclass* ic)
/* IupTree Attributes - GENERAL */
iupClassRegisterAttribute(ic, "EXPANDALL", NULL, winTreeSetExpandAllAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "INDENTATION", winTreeGetIndentationAttrib, winTreeSetIndentationAttrib, NULL, NULL, IUPAF_DEFAULT);
- iupClassRegisterAttribute(ic, "COUNT", winTreeGetCountAttrib, NULL, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_READONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "DRAGDROP", NULL, iupwinSetDragDropAttrib, NULL, NULL, IUPAF_NO_INHERIT);
iupClassRegisterAttribute(ic, "SPACING", iupTreeGetSpacingAttrib, winTreeSetSpacingAttrib, NULL, NULL, IUPAF_NOT_MAPPED);
iupClassRegisterAttribute(ic, "TOPITEM", NULL, winTreeSetTopItemAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
@@ -2521,7 +2554,6 @@ void iupdrvTreeInitClass(Iclass* ic)
iupClassRegisterAttributeId(ic, "NAME", winTreeGetTitleAttrib, winTreeSetTitleAttrib, IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "TITLE", winTreeGetTitleAttrib, winTreeSetTitleAttrib, IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "CHILDCOUNT", winTreeGetChildCountAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
- iupClassRegisterAttributeId(ic, "USERDATA", winTreeGetUserDataAttrib, winTreeSetUserDataAttrib, IUPAF_NO_STRING|IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "COLOR", winTreeGetColorAttrib, winTreeSetColorAttrib, IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "TITLEFONT", winTreeGetTitleFontAttrib, winTreeSetTitleFontAttrib, IUPAF_NO_INHERIT);
@@ -2530,6 +2562,7 @@ void iupdrvTreeInitClass(Iclass* ic)
iupClassRegisterAttribute (ic, "MARK", NULL, winTreeSetMarkAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttribute (ic, "STARTING", NULL, winTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
iupClassRegisterAttribute (ic, "MARKSTART", NULL, winTreeSetMarkStartAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
+ iupClassRegisterAttribute (ic, "MARKEDNODES", winTreeGetMarkedNodesAttrib, winTreeSetMarkedNodesAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
iupClassRegisterAttribute (ic, "VALUE", winTreeGetValueAttrib, winTreeSetValueAttrib, NULL, NULL, IUPAF_NO_DEFAULTVALUE|IUPAF_NO_INHERIT);
@@ -2538,5 +2571,8 @@ void iupdrvTreeInitClass(Iclass* ic)
iupClassRegisterAttribute(ic, "RENAME", NULL, winTreeSetRenameAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "MOVENODE", NULL, winTreeSetMoveNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
iupClassRegisterAttributeId(ic, "COPYNODE", NULL, winTreeSetCopyNodeAttrib, IUPAF_NOT_MAPPED|IUPAF_WRITEONLY|IUPAF_NO_INHERIT);
- iupClassRegisterAttributeId(ic, "FINDUSERDATA", winTreeGetFindUserDataAttrib, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT);
+
+ /* necessary because transparent background does not work when not using visual styles */
+ if (!iupwin_comctl32ver6) /* Used by iupdrvImageCreateImage */
+ iupClassRegisterAttribute(ic, "FLAT_ALPHA", NULL, NULL, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
}