#include "GuiTreeViewControls.h"
#include "GuiListControlItemArrangers.h"
#include "../GuiButtonControls.h"
#include "../Templates/GuiThemeStyleFactory.h"
#include "../../GraphicsComposition/GuiGraphicsTableComposition.h"
namespace
{
namespace
{
namespace
{
using
namespace
elements
;
using
namespace
compositions
;
using
namespace
reflection
::
description
;
namespace
{
const
wchar_t
*
const
::
=
L"vl::presentation::controls::tree::INodeItemView"
;
<
>
::
(
<
>
,
)
{
if
(
==
0
)
return
;
<
>
;
if
(
() &&
>
0
)
{
-=
1
;
=
();
for
(
=
0
; (!
result
&&
i
<
count
);
i
++)
{
auto
=
(
i
);
=
child
CalculateTotalVisibleNodes
();
if
(
<
visibleCount
)
{
result
(
child
,
);
}
else
{
-=
visibleCount
;
}
}
}
return
result
;
}
void
::
(
*
)
{
}
void
::
(
*
,
,
,
)
{
=
0
;
=
CalculateNodeVisibilityIndexInternal
(
);
if
(
base
!= -
2
&&
->
())
{
for
(
=
0
;
i
<
;
i
++)
{
auto
=
->
(
+
i
);
offset
+=
child
CalculateTotalVisibleNodes
();
}
}
offsetBeforeChildModifieds
.
(
,
offset
);
}
void
::
(
*
,
,
,
)
{
offsetBeforeChildModified
=
0
;
{
=
offsetBeforeChildModifieds
.
().
(
);
if
(
index
!= -
1
)
{
offsetBeforeChildModified
=
offsetBeforeChildModifieds
.
().
(
index
);
offsetBeforeChildModifieds
.
(
);
}
}
=
CalculateNodeVisibilityIndexInternal
(
);
if
(
base
!= -
2
&&
->
())
{
=
0
;
= -
1
;
for
(
=
0
;
i
<
;
i
++)
{
auto
=
->
(
+
i
);
if
(
i
==
0
)
{
firstChildStart
=
CalculateNodeVisibilityIndexInternal
(
child
.
());
}
offset
+=
child
CalculateTotalVisibleNodes
();
}
if
(
firstChildStart
== -
1
)
{
=
->
();
if
(
childCount
==
0
)
{
firstChildStart
=
base
+
1
;
}
else
if
(
<
childCount
)
{
auto
=
->
(
);
firstChildStart
=
CalculateNodeVisibilityIndexInternal
(
child
.
());
}
else
{
auto
=
->
(
-
1
);
firstChildStart
=
CalculateNodeVisibilityIndexInternal
(
child
.
());
firstChildStart
+=
child
CalculateTotalVisibleNodes
();
}
}
(
firstChildStart
,
offsetBeforeChildModified
,
offset
);
}
}
void
::
(
*
)
{
=
CalculateNodeVisibilityIndexInternal
(
);
if
(
base
!= -
2
)
{
=
->
CalculateTotalVisibleNodes
();
(
base
+
1
,
0
,
visibility
-
1
);
}
}
void
::
(
*
)
{
=
CalculateNodeVisibilityIndexInternal
(
);
if
(
base
!= -
2
)
{
=
0
;
=
->
();
for
(
=
0
;
i
<
count
;
i
++)
{
auto
=
->
(
i
);
visibility
+=
child
CalculateTotalVisibleNodes
();
}
(
base
+
1
,
visibility
,
0
);
}
}
::
CalculateNodeVisibilityIndexInternal
(
*
)
{
auto
=
->
();
if
(!
parent
)
{
return
-
1
;
}
if
(!
parent
())
{
return
-
2
;
}
=
CalculateNodeVisibilityIndexInternal
(
parent
.
());
if
(
index
== -
2
)
{
return
-
2
;
}
=
parent
();
for
(
=
0
;
i
<
count
;
i
++)
{
auto
=
parent
(
i
);
bool
=
child
;
if
(
findResult
)
{
index
++;
}
else
{
index
+=
child
CalculateTotalVisibleNodes
();
}
if
(
findResult
)
{
return
index
;
}
}
return
-
1
;
}
::
CalculateNodeVisibilityIndex
(
*
)
{
=
CalculateNodeVisibilityIndexInternal
(
);
return
result
<
0
? -
1
:
result
;
}
<
>
::
(
)
{
if
(
())
{
return
(
+
1
);
}
else
{
return
(
(),
+
1
);
}
}
::
(
<
>
)
:root(
)
{
(
this
);
}
::
()
{
(
this
);
}
<
>
::
()
{
return
;
}
::
()
{
return
()
CalculateTotalVisibleNodes
()-
1
;
}
::
(
)
{
if
(
auto
=
(
))
{
return
(
node
.
());
}
return
L""
;
}
description
::
::
(
)
{
if
(
auto
=
(
))
{
return
(
node
.
());
}
return
();
}
*
::
(
const
&
)
{
if
(
==
::
)
{
return
(
*)
this
;
}
else
{
return
(
);
}
}
void
::
::
(
,
,
)
{
if
(
->
)
{
for
(
=
0
;
i
<
;
i
++)
{
offsetBeforeChildModified
+=
+
i
]
;
}
}
*
=
->
();
if
(
proxy
)
{
proxy
->
(
,
,
,
);
}
}
void
::
::
(
,
,
)
{
->
+= (
-
);
if
(
->
)
{
=
0
;
for
(
=
0
;
i
<
;
i
++)
{
offset
+=
+
i
]
;
}
->
OnChildTotalVisibleNodesChanged
(
offset
-
offsetBeforeChildModified
);
}
offsetBeforeChildModified
=
0
;
*
=
->
();
if
(
proxy
)
{
proxy
->
(
,
,
,
);
}
}
bool
::
::
(
,
<
>
const
&
)
{
return
==
0
;
}
bool
::
::
(
,
<
>
const
&
)
{
return
==
;
}
void
::
::
(
,
<
>
const
&
)
{
(
,
0
,
1
);
=
;
}
void
::
::
(
,
<
>
const
&
)
{
(
,
1
,
0
);
=
0
;
}
void
::
::
(
,
<
>
const
&
)
{
(
,
0
,
1
);
}
void
::
::
(
,
)
{
(
,
,
0
);
}
::
::
()
:ownerProvider(
0
)
{
}
*
::
()
{
if
(
)
{
return
->
();
}
else
{
return
0
;
}
}
void
::
OnChildTotalVisibleNodesChanged
(
)
{
+=
;
if
(
)
{
->
OnChildTotalVisibleNodesChanged
(
);
}
}
::
(
<
>
)
:data(
)
{
.
=
this
;
}
::
()
{
}
<
>
::
()
{
return
;
}
void
::
(
const
<
>&
)
{
;
();
}
void
::
()
{
if
(
)
{
=
->
.
(
this
);
*
=
();
if
(
proxy
)
{
proxy
->
(
,
index
,
1
,
1
);
proxy
->
(
,
index
,
1
,
1
);
}
}
}
::
&
::
()
{
return
;
}
bool
::
()
{
return
;
}
void
::
(
bool
)
{
if
(
!=
)
{
=
;
=
0
;
for
(
=
0
;
i
<
;
i
++)
{
offset
+=
i
]
;
}
OnChildTotalVisibleNodesChanged
(
?
offset
:-
offset
);
*
=
();
if
(
proxy
)
{
if
(
)
{
proxy
->
(
this
);
}
else
{
proxy
->
(
this
);
}
}
}
}
::
CalculateTotalVisibleNodes
()
{
return
;
}
::
()
{
return
;
}
<
>
::
()
{
return
;
}
<
>
::
(
)
{
if
(
0
<=
&&
<
)
{
return
].
();
}
else
{
return
nullptr
;
}
}
void
::
(
*
)
{
}
void
::
(
*
,
,
,
)
{
for
(
=
0
;
i
<
.
();
i
++)
{
i
]->
(
,
,
,
);
}
}
void
::
(
*
,
,
,
)
{
for
(
=
0
;
i
<
.
();
i
++)
{
i
]->
(
,
,
,
);
}
}
void
::
(
*
)
{
for
(
=
0
;
i
<
.
();
i
++)
{
i
]->
(
);
}
}
void
::
(
*
)
{
for
(
=
0
;
i
<
.
();
i
++)
{
i
]->
(
);
}
}
::
()
{
}
::
()
{
}
bool
::
()
{
return
false
;
}
<
>
::
(
)
{
return
nullptr
;
}
bool
::
(
*
)
{
if
(
.
(
))
{
return
false
;
}
else
{
.
(
);
->
(
this
);
return
true
;
}
}
bool
::
(
*
)
{
=
.
(
);
if
(
index
==-
1
)
{
return
false
;
}
else
{
->
(
0
);
.
(
);
return
true
;
}
}
*
::
(
const
&
)
{
return
0
;
}
*
::
()
{
return
this
;
}
::
()
{
(
true
);
}
::
()
{
}
<
>
::
()
{
return
this
;
}
*
::
(
*
)
{
return
dynamic_cast
<
*>(
);
}
}
void
GuiVirtualTreeListControl
::
BeforeControlTemplateUninstalled_
()
{
}
void
GuiVirtualTreeListControl
::
AfterControlTemplateInstalled_
(
bool
)
{
}
void
GuiVirtualTreeListControl
::
(
tree
::
*
)
{
}
void
GuiVirtualTreeListControl
::
(
tree
::
*
,
,
,
)
{
}
void
GuiVirtualTreeListControl
::
(
tree
::
*
,
,
,
)
{
}
void
GuiVirtualTreeListControl
::
(
tree
::
*
)
{
;
(
&)
arguments
();
arguments
.
=
;
.
(
arguments
);
}
void
GuiVirtualTreeListControl
::
(
tree
::
*
)
{
;
(
&)
arguments
();
arguments
.
=
;
.
(
arguments
);
}
void
GuiVirtualTreeListControl
::
(
compositions
::
&
,
compositions
::
*
,
compositions
::
&
)
{
auto
=
()->
(
.
);
if
(
node
)
{
;
(
&)
redirectArguments
;
redirectArguments
.
=
node
.
();
.
(
redirectArguments
);
(
&)
redirectArguments
;
}
}
void
GuiVirtualTreeListControl
::
(
compositions
::
&
,
compositions
::
*
,
compositions
::
&
)
{
if
(
auto
=
()->
(
.
))
{
;
(
&)
redirectArguments
;
redirectArguments
.
=
node
.
();
.
(
redirectArguments
);
(
&)
redirectArguments
;
}
}
#define ATTACH_ITEM_MOUSE_EVENT(NODEEVENTNAME, ITEMEVENTNAME)\
{\
Func<void(GuiNodeMouseEvent&, GuiGraphicsComposition*, GuiItemMouseEventArgs&)> func(this, &GuiVirtualTreeListControl::OnItemMouseEvent);\
ITEMEVENTNAME.AttachFunction(Curry(func)(NODEEVENTNAME));\
}\
#define ATTACH_ITEM_NOTIFY_EVENT(NODEEVENTNAME, ITEMEVENTNAME)\
{\
Func<void(GuiNodeNotifyEvent&, GuiGraphicsComposition*, GuiItemEventArgs&)> func(this, &GuiVirtualTreeListControl::OnItemNotifyEvent);\
ITEMEVENTNAME.AttachFunction(Curry(func)(NODEEVENTNAME));\
}\
void
GuiVirtualTreeListControl
::
(
compositions
::
*
,
compositions
::
&
)
{
if
(
.
->
() >
0
)
{
.
->
(!
.
->
());
}
}
GuiVirtualTreeListControl
::
GuiVirtualTreeListControl
(
theme
::
,
<
tree
::
>
)
:
(
,
new
tree
::
(
))
{
=
dynamic_cast
<
tree
::
*>(
());
=
dynamic_cast
<
tree
::
*>(
()->
(
tree
::
::
));
.
(
);
.
(
);
NodeLeftButtonDoubleClick
.
(
);
.
(
);
.
(
);
NodeMiddleButtonDoubleClick
.
(
);
.
(
);
.
(
);
NodeRightButtonDoubleClick
.
(
);
.
(
);
.
(
);
.
(
);
.
(
);
.
(
);
ATTACH_ITEM_MOUSE_EVENT(NodeLeftButtonDown, ItemLeftButtonDown);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
.
(
(
func
)(
)); };
ATTACH_ITEM_MOUSE_EVENT(NodeLeftButtonUp, ItemLeftButtonUp);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
.
(
(
func
)(
)); };
ATTACH_ITEM_MOUSE_EVENT(NodeLeftButtonDoubleClick, ItemLeftButtonDoubleClick);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
ItemLeftButtonDoubleClick
.
(
(
func
)(
NodeLeftButtonDoubleClick
)); };
ATTACH_ITEM_MOUSE_EVENT(NodeMiddleButtonDown, ItemMiddleButtonDown);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
.
(
(
func
)(
)); };
ATTACH_ITEM_MOUSE_EVENT(NodeMiddleButtonUp, ItemMiddleButtonUp);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
.
(
(
func
)(
)); };
ATTACH_ITEM_MOUSE_EVENT(NodeMiddleButtonDoubleClick, ItemMiddleButtonDoubleClick);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
ItemMiddleButtonDoubleClick
.
(
(
func
)(
NodeMiddleButtonDoubleClick
)); };
ATTACH_ITEM_MOUSE_EVENT(NodeRightButtonDown, ItemRightButtonDown);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
.
(
(
func
)(
)); };
ATTACH_ITEM_MOUSE_EVENT(NodeRightButtonUp, ItemRightButtonUp);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
.
(
(
func
)(
)); };
ATTACH_ITEM_MOUSE_EVENT(NodeRightButtonDoubleClick, ItemRightButtonDoubleClick);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
ItemRightButtonDoubleClick
.
(
(
func
)(
NodeRightButtonDoubleClick
)); };
ATTACH_ITEM_MOUSE_EVENT(NodeMouseMove, ItemMouseMove);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
.
(
(
func
)(
)); };
ATTACH_ITEM_NOTIFY_EVENT(NodeMouseEnter, ItemMouseEnter);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
.
(
(
func
)(
)); };
ATTACH_ITEM_NOTIFY_EVENT(NodeMouseLeave, ItemMouseLeave);
{
<
void
(
&,
*,
&)>
(
this
, &
GuiVirtualTreeListControl
::
);
.
(
(
func
)(
)); };
->
()
(
this
);
NodeLeftButtonDoubleClick
.
(
this
, &
GuiVirtualTreeListControl
::
OnNodeLeftButtonDoubleClick
);
}
#undef ATTACH_ITEM_MOUSE_EVENT
#undef ATTACH_ITEM_NOTIFY_EVENT
GuiVirtualTreeListControl
::
~
GuiVirtualTreeListControl
()
{
}
tree
::
*
GuiVirtualTreeListControl
::
()
{
return
;
}
tree
::
*
GuiVirtualTreeListControl
::
()
{
return
->
().
();
}
namespace
{
const
wchar_t
*
const
::
=
L"vl::presentation::controls::tree::ITreeViewItemView"
;
::
()
{
}
::
(
const
<
>&
,
const
&
)
:image(
)
,text(
)
{
}
<
>
::
(
*
)
{
*
=
dynamic_cast
<
*>(
);
if
(
memoryNode
)
{
<
>
=
memoryNode
->
().
<
>();
if
(
data
)
{
return
data
;
}
}
return
0
;
}
::
(
*
)
{
*
=
dynamic_cast
<
*>(
);
if
(
memoryNode
)
{
<
>
=
memoryNode
->
().
<
>();
if
(
data
)
{
return
data
text
;
}
}
return
L""
;
}
description
::
::
(
*
)
{
return
::
(
(
));
}
::
()
{
}
::
~
TreeViewItemRootProvider
()
{
}
*
::
(
const
&
)
{
if
(
==
::
)
{
return
(
*)
this
;
}
else
{
return
::
(
);
}
}
<
>
::
(
*
)
{
*
=
(
);
if
(
memoryNode
)
{
return
memoryNode
->
().
<
>();
}
else
{
return
0
;
}
}
void
::
(
*
,
<
>
)
{
*
=
(
);
if
(
memoryNode
)
{
memoryNode
->
(
);
}
}
void
::
(
*
)
{
*
=
(
);
if
(
memoryNode
)
{
memoryNode
->
();
}
}
}
templates
::
*
::
(
tree
::
*
)
{
if
(
)
{
=
->
CalculateNodeVisibilityIndex
(
);
if
(
index
!= -
1
)
{
auto
=
(
index
);
return
dynamic_cast
<
templates
::
*>(
style
);
}
}
return
nullptr
;
}
void
::
(
tree
::
*
,
bool
)
{
if
(
auto
=
(
))
{
treeItemStyle
->
(
);
}
}
void
::
(
tree
::
*
,
bool
)
{
if
(
auto
=
(
))
{
treeItemStyle
->
(
);
}
}
void
::
(
tree
::
*
,
,
,
)
{
GuiVirtualTreeListControl
::
(
,
,
,
);
(
,
->
() >
0
);
}
void
::
(
tree
::
*
)
{
GuiVirtualTreeListControl
::
(
);
(
,
true
);
}
void
::
(
tree
::
*
)
{
GuiVirtualTreeListControl
::
(
);
(
,
false
);
}
void
::
(
,
*
)
{
GuiVirtualTreeListControl
::
(
,
);
if
(
auto
=
dynamic_cast
<
templates
::
*>(
))
{
treeItemStyle
->
(
TypedControlTemplateObject
(
true
)->
());
if
(
)
{
if
(
auto
=
->
(
))
{
treeItemStyle
->
(
->
(
node
.
()));
treeItemStyle
->
(
node
());
treeItemStyle
->
(
node
() >
0
);
{
= -
1
;
auto
=
node
;
while
(
current
())
{
level
++;
current
current
();
}
treeItemStyle
->
(
level
);
}
}
}
}
}
::
(
theme
::
,
<
tree
::
>
)
:
GuiVirtualTreeListControl
(
,
)
{
=
dynamic_cast
<
tree
::
*>(
()->
(
tree
::
::
));
(
[](
const
&) {
return
new
tree
::
; },
new
list
::
);
}
::
()
{
}
::
(
theme
::
)
:
(
,
new
tree
::
)
{
->
().
<
tree
::
>();
}
::
()
{
}
<
tree
::
>
::
()
{
return
;
}
<
tree
::
>
::
()
{
<
tree
::
>
;
=
();
if
(
index
!= -
1
)
{
if
(
auto
=
->
(
index
))
{
if
(
auto
=
node
.
<
tree
::
>())
{
result
memoryNode
().
<
tree
::
>();
}
}
}
return
result
;
}
namespace
{
void
::
()
{
templates
::
::
();
(
::
LimitToElementAndChildren
);
=
new
;
(
);
->
(
3
,
4
);
->
(
0
,
::
(
0.5
));
->
(
1
,
::
());
->
(
2
,
::
(
0.5
));
->
(
0
,
::
(
0
));
->
(
1
,
::
());
->
(
2
,
::
());
->
(
3
,
::
());
->
(
(
0
,
0
,
0
,
0
));
->
(
2
);
{
*
=
new
;
->
(
cell
);
cell
->
(
0
,
1
,
3
,
1
);
cell
->
(
(
16
,
16
));
=
new
(
theme
::
::
);
if
(
auto
=
dynamic_cast
<
*>(
))
{
if
(
auto
=
treeView
->
TypedControlTemplateObject
(
true
)->
GetExpandingDecoratorTemplate
())
{
->
(
expanderStyle
);
}
}
->
(
false
);
->
(
false
);
->
()->
(
(
0
,
0
,
0
,
0
));
->
()->
()->
.
(
this
, &
::
OnExpandingButtonDoubleClick
);
->
.
(
this
, &
::
);
cell
->
(
->
());
}
{
*
=
new
;
->
(
cell
);
cell
->
(
1
,
2
,
1
,
1
);
cell
->
(
(
16
,
16
));
=
::
();
->
(
true
);
cell
->
(
);
}
{
*
=
new
;
->
(
cell
);
cell
->
(
0
,
3
,
3
,
1
);
cell
->
(
(
192
,
0
));
=
::
();
->
(
::
,
::
);
->
(
true
);
cell
->
(
);
}
.
(
this
, &
::
);
.
(
this
, &
::
);
.
(
this
, &
::
);
.
(
this
, &
::
);
.
(
this
, &
::
);
.
(
this
, &
::
);
.
(
this
, &
::
);
.
(
compositions
::
(
this
));
.
(
compositions
::
(
this
));
.
(
compositions
::
(
this
));
.
(
compositions
::
(
this
));
.
(
compositions
::
(
this
));
.
(
compositions
::
(
this
));
.
(
compositions
::
(
this
));
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
->
(
());
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
->
(
());
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
->
(
());
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
->
(
());
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
->
(
());
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
->
(
0
,
::
(
() *
12
));
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
if
(
auto
=
())
{
->
(
imageData
(),
imageData
());
}
else
{
->
(
nullptr
);
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
.
=
true
;
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
if
(
->
())
{
if
(
auto
=
dynamic_cast
<
GuiVirtualTreeListControl
*>(
))
{
if
(
auto
=
treeControl
->
())
{
=
treeControl
->
()->
(
this
);
if
(
index
!= -
1
)
{
if
(
auto
=
view
->
(
index
))
{
bool
=
node
();
node
(!
expanding
);
}
}
}
}
}
}
::
()
{
}
::
()
{
}
}
}
}
}