#include "GuiListControls.h"
#include "../Templates/GuiControlTemplates.h"
#include "../../GraphicsHost/GuiGraphicsHost.h"
namespace
{
namespace
{
namespace
{
using
namespace
collections
;
using
namespace
elements
;
using
namespace
compositions
;
<
::
::
>
::
::
(
*
,
,
compositions
::
*
)
{
auto
=
->
.
(
this
, &
::
);
->
()->
(
?
:
);
->
(
,
);
return
handler
;
}
::
*
::
::
(
)
{
auto
=
.
()
];
auto
=
.
()
];
->
(
style
);
->
()->
(
style
);
style
->
.
(
handler
);
return
style
;
}
void
::
::
(
compositions
::
*
,
compositions
::
&
)
{
->
([=]()
{
->
();
});
}
::
::
(
*
)
:listControl(
)
{
}
::
::
()
{
();
}
void
::
::
()
{
for
(
=
0
;
i
<
.
();
i
++)
{
auto
=
(
i
);
(
style
);
}
.
();
}
void
::
::
(
*
)
{
=
;
}
void
::
::
(
,
,
)
{
->
(
,
,
);
}
::
*
::
::
(
,
compositions
::
*
)
{
CHECK_ERROR(0 <= itemIndex && itemIndex < itemProvider->Count(), L"GuiListControl::ItemCallback::RequestItem(vint)#Index out of range.");
do
{
if
(!(
0
<=
&&
<
->
()))
throw
(
L"GuiListControl::ItemCallback::RequestItem(vint)#Index out of range."
);}
while
(
0
);
CHECK_ERROR(listControl->itemStyleProperty, L"GuiListControl::ItemCallback::RequestItem(vint)#SetItemTemplate function should be called before adding items to the list control.");
do
{
if
(!(
->
))
throw
(
L"GuiListControl::ItemCallback::RequestItem(vint)#SetItemTemplate function should be called before adding items to the list control."
);}
while
(
0
);
auto
=
->
->
(
));
auto
=
(
style
,
,
);
.
(
style
,
handler
);
return
style
;
}
void
::
::
(
*
)
{
=
.
().
(
);
if
(
index
!= -
1
)
{
auto
=
(
index
);
.
(
style
);
(
style
);
}
}
void
::
::
(
)
{
(
,
->
());
=
->
(
->
,
virtualRect
);
->
(
realRect
.
());
}
::
::
(
compositions
::
*
)
{
=
->
().
();
return
->
(
size
);
}
void
::
::
SetStyleAlignmentToParent
(
compositions
::
*
,
)
{
=
->
VirtualMarginToRealMargin
(
);
->
(
newMargin
);
}
::
::
(
compositions
::
*
)
{
=
->
();
return
->
(
->
(),
bounds
);
}
void
::
::
(
compositions
::
*
,
)
{
=
->
(
->
(),
);
return
->
(
newBounds
);
}
compositions
::
*
::
::
()
{
return
->
();
}
void
::
::
()
{
->
();
}
void
::
BeforeControlTemplateUninstalled_
()
{
}
void
::
AfterControlTemplateInstalled_
(
bool
)
{
if
(
)
{
();
();
}
}
void
::
(
,
,
)
{
}
void
::
(
,
*
)
{
->
(
());
->
(
());
->
(
(
));
->
(
());
->
(
false
);
->
(
);
->
(
this
);
(
);
}
void
::
(
*
)
{
(
);
}
void
::
(
elements
::
*
)
{
(
,
);
::
(
);
}
void
::
OnBeforeReleaseGraphicsHost
()
{
::
OnBeforeReleaseGraphicsHost
();
({},
nullptr
);
}
::
()
{
=
?
() :
(
0
,
0
);
(
virtualSize
);
return
;
}
void
::
(
)
{
if
(
)
{
=
(
,
);
(
newBounds
);
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
if
(
())
{
();
}
}
void
::
(
,
<
>
)
{
if
(
)
{
();
(
nullptr
);
(
.
());
}
();
;
;
if
(
auto
=
())
{
scroll
->
(
0
);
}
if
(
auto
=
())
{
scroll
->
(
0
);
}
if
(
)
{
(
.
());
(
.
());
(
this
);
}
();
}
void
::
()
{
::
();
FOREACH(ItemStyle*, style, visibleStyles.Keys())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
*>&
= ::
vl
::
collections
::
(
.
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
*
;
__foreach_iterator__
.
(
style
);)
{
style
->
(
());
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
auto
=
();
.
(
args
);
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
FOREACH(ItemStyle*, style, visibleStyles.Keys())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
*>&
= ::
vl
::
collections
::
(
.
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
*
;
__foreach_iterator__
.
(
style
);)
{
style
->
(
());
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
FOREACH(ItemStyle*, style, visibleStyles.Keys())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
*>&
= ::
vl
::
collections
::
(
.
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
*
;
__foreach_iterator__
.
(
style
);)
{
style
->
(
());
}
}
void
::
(
compositions
::
&
,
*
,
compositions
::
*
,
compositions
::
&
)
{
if
(
&&
())
{
=
(
);
if
(
itemIndex
!= -
1
)
{
;
(
&)
redirectArguments
;
redirectArguments
.
=
;
redirectArguments
.
=
;
redirectArguments
.
=
itemIndex
;
.
(
redirectArguments
);
redirectArguments
;
}
}
}
void
::
(
compositions
::
&
,
*
,
compositions
::
*
,
compositions
::
&
)
{
if
(
&&
())
{
=
(
);
if
(
itemIndex
!= -
1
)
{
;
(
&)
redirectArguments
;
redirectArguments
.
=
;
redirectArguments
.
=
;
redirectArguments
.
=
itemIndex
;
.
(
redirectArguments
);
redirectArguments
;
}
}
}
#define ATTACH_ITEM_MOUSE_EVENT(EVENTNAME, ITEMEVENTNAME)\
{\
Func<void(GuiItemMouseEvent&, ItemStyle*, GuiGraphicsComposition*, GuiMouseEventArgs&)> func(this, &GuiListControl::OnItemMouseEvent);\
helper->EVENTNAME##Handler = style->GetEventReceiver()->EVENTNAME.AttachFunction(\
Curry(Curry(func)(ITEMEVENTNAME))(style)\
);\
}\
#define ATTACH_ITEM_NOTIFY_EVENT(EVENTNAME, ITEMEVENTNAME)\
{\
Func<void(GuiItemNotifyEvent&, ItemStyle*, GuiGraphicsComposition*, GuiEventArgs&)> func(this, &GuiListControl::OnItemNotifyEvent);\
helper->EVENTNAME##Handler = style->GetEventReceiver()->EVENTNAME.AttachFunction(\
Curry(Curry(func)(ITEMEVENTNAME))(style)\
);\
}\
void
::
(
*
)
{
=
.
().
(
);
if
(
index
==-
1
)
{
<
>
=
new
;
.
(
,
helper
);
ATTACH_ITEM_MOUSE_EVENT(leftButtonDown, ItemLeftButtonDown);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
=
->
()->
.
(
(
(
func
)(
))(
) ); };
ATTACH_ITEM_MOUSE_EVENT(leftButtonUp, ItemLeftButtonUp);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
=
->
()->
.
(
(
(
func
)(
))(
) ); };
ATTACH_ITEM_MOUSE_EVENT(leftButtonDoubleClick, ItemLeftButtonDoubleClick);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
leftButtonDoubleClickHandler
=
->
()->
.
(
(
(
func
)(
ItemLeftButtonDoubleClick
))(
) ); };
ATTACH_ITEM_MOUSE_EVENT(middleButtonDown, ItemMiddleButtonDown);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
=
->
()->
.
(
(
(
func
)(
))(
) ); };
ATTACH_ITEM_MOUSE_EVENT(middleButtonUp, ItemMiddleButtonUp);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
=
->
()->
.
(
(
(
func
)(
))(
) ); };
ATTACH_ITEM_MOUSE_EVENT(middleButtonDoubleClick, ItemMiddleButtonDoubleClick);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
middleButtonDoubleClickHandler
=
->
()->
.
(
(
(
func
)(
ItemMiddleButtonDoubleClick
))(
) ); };
ATTACH_ITEM_MOUSE_EVENT(rightButtonDown, ItemRightButtonDown);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
=
->
()->
.
(
(
(
func
)(
))(
) ); };
ATTACH_ITEM_MOUSE_EVENT(rightButtonUp, ItemRightButtonUp);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
=
->
()->
.
(
(
(
func
)(
))(
) ); };
ATTACH_ITEM_MOUSE_EVENT(rightButtonDoubleClick, ItemRightButtonDoubleClick);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
rightButtonDoubleClickHandler
=
->
()->
.
(
(
(
func
)(
ItemRightButtonDoubleClick
))(
) ); };
ATTACH_ITEM_MOUSE_EVENT(mouseMove, ItemMouseMove);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
=
->
()->
.
(
(
(
func
)(
))(
) ); };
ATTACH_ITEM_NOTIFY_EVENT(mouseEnter, ItemMouseEnter);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
=
->
()->
.
(
(
(
func
)(
))(
) ); };
ATTACH_ITEM_NOTIFY_EVENT(mouseLeave, ItemMouseLeave);
{
<
void
(
&,
*,
*,
&)>
(
this
, &
::
);
helper
=
->
()->
.
(
(
(
func
)(
))(
) ); };
}
}
#undef ATTACH_ITEM_MOUSE_EVENT
#undef ATTACH_ITEM_NOTIFY_EVENT
#define DETACH_ITEM_EVENT(EVENTNAME) style->GetEventReceiver()->EVENTNAME.Detach(helper->EVENTNAME##Handler)
void
::
(
*
)
{
=
.
().
(
);
if
(
index
!=-
1
)
{
<
>
=
.
().
(
index
);
.
(
);
DETACH_ITEM_EVENT(leftButtonDown);
DETACH_ITEM_EVENT(leftButtonUp);
DETACH_ITEM_EVENT(leftButtonDoubleClick);
->
()->
.
(
helper
leftButtonDoubleClickHandler
);
DETACH_ITEM_EVENT(middleButtonDown);
DETACH_ITEM_EVENT(middleButtonUp);
DETACH_ITEM_EVENT(middleButtonDoubleClick);
->
()->
.
(
helper
middleButtonDoubleClickHandler
);
DETACH_ITEM_EVENT(rightButtonDown);
DETACH_ITEM_EVENT(rightButtonUp);
DETACH_ITEM_EVENT(rightButtonDoubleClick);
->
()->
.
(
helper
rightButtonDoubleClickHandler
);
DETACH_ITEM_EVENT(mouseMove);
DETACH_ITEM_EVENT(mouseEnter);
DETACH_ITEM_EVENT(mouseLeave);
}
}
#undef DETACH_ITEM_EVENT
::
(
theme
::
,
*
,
bool
)
:
(
)
, itemProvider(
)
{
.
(
this
, &
::
);
.
(
this
, &
::
);
->
.
(
this
, &
::
);
.
(
);
.
(
);
.
(
);
.
(
);
.
(
);
.
(
);
ItemLeftButtonDoubleClick
.
(
);
.
(
);
.
(
);
ItemMiddleButtonDoubleClick
.
(
);
.
(
);
.
(
);
ItemRightButtonDoubleClick
.
(
);
.
(
);
.
(
);
.
(
);
new
(
this
);
(
.
());
new
;
if
(
)
{
->
()->
.
(
this
, &
::
);
->
()->
.
(
this
, &
::
);
->
()->
.
(
this
, &
::
);
(
);
}
}
::
()
{
if
(
)
{
(
.
());
}
();
{};
nullptr
;
}
::
*
::
()
{
return
.
();
}
::
::
()
{
return
;
}
void
::
(
)
{
(
,
);
.
(
());
}
::
*
::
()
{
return
.
();
}
void
::
(
<
>
)
{
(
,
);
.
(
());
}
compositions
::
*
::
()
{
return
.
();
}
void
::
(
<
compositions
::
>
)
{
<
>
=
;
;
(
,
);
.
(
());
}
bool
::
(
)
{
if
(
<
0
||
>=
())
{
return
false
;
}
if
(!
)
return
false
;
auto
=
(
);
if
(
result
==
::
)
{
if
(
auto
=
()->
())
{
auto
=
();
host
->
([=]()
{
if
(!
flag
())
{
(
);
}
}, {
this
,
0
});
}
}
return
result
!=
::
;
}
::
(
)
{
if
(
)
{
=
->
().
();
=
->
().
();
=
controlSize
.
-
viewSize
.
;
=
controlSize
.
-
viewSize
.
;
(
.
-
x
,
.
-
y
);
if
(
)
{
expectedViewSize
(
expectedViewSize
);
}
=
(
expectedViewSize
);
if
(
)
{
adoptedViewSize
(
adoptedViewSize
);
}
return
(
adoptedViewSize
.
+
x
,
adoptedViewSize
.
+
y
);
}
return
;
}
bool
::
()
{
return
;
}
void
::
(
bool
)
{
if
(
!=
)
{
=
;
(
,
);
}
}
void
::
()
{
.
(
());
}
void
::
(
,
,
)
{
::
(
,
,
);
if
(
!=
)
{
();
}
}
void
::
(
,
*
)
{
::
(
,
);
->
(
.
(
));
}
void
::
(
,
bool
)
{
if
(
auto
=
(
))
{
style
->
(
);
}
}
void
::
()
{
FOREACH(ItemStyle*, style, visibleStyles.Keys())
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
*>&
= ::
vl
::
collections
::
(
.
());
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
*
;
__foreach_iterator__
.
(
style
);)
{
style
->
(
false
);
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
if
(
())
{
(
.
,
.
,
.
,
true
);
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
if
(
())
{
(
.
,
.
,
.
,
false
);
}
}
void
::
NormalizeSelectedItemIndexStartEnd
()
{
if
(
<
0
||
>=
())
{
=
0
;
}
if
(
<
0
||
>=
())
{
=
0
;
}
}
void
::
SetMultipleItemsSelectedSilently
(
,
,
bool
)
{
if
(
>
)
{
=
;
=
;
=
temp
;
}
=
();
if
(
<
0
)
=
0
;
if
(
>=
count
)
=
count
-
1
;
for
(
=
;
i
<=
;
i
++)
{
if
(
)
{
if
(!
.
(
i
))
{
.
(
i
);
}
}
else
{
.
(
i
);
}
(
i
,
);
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
if
(
())
{
if
(
(
.
,
.
,
.
))
{
.
=
true
;
}
}
}
::
(
theme
::
,
*
)
:
(
,
,
true
)
, multiSelect(
false
)
, selectedItemIndexStart(-
1
)
, selectedItemIndexEnd(-
1
)
{
.
(
);
.
(
this
, &
::
);
.
(
this
, &
::
);
if
(
)
{
->
()->
.
(
this
, &
::
);
}
}
::
~
GuiSelectableListControl
()
{
}
bool
::
()
{
return
;
}
void
::
(
bool
)
{
if
(
!=
)
{
=
;
();
}
}
const
collections
::
<
>&
::
()
{
return
;
}
::
()
{
return
.
() ==
1
?
0
] : -
1
;
}
::
()
{
=
();
if
(
index
!= -
1
)
{
return
(
index
);
}
return
L""
;
}
bool
::
(
)
{
return
.
(
);
}
void
::
(
,
bool
)
{
if
(
)
{
if
(!
.
(
))
{
if
(!
)
{
.
();
();
}
.
(
);
(
,
);
();
}
}
else
{
if
(
.
(
))
{
(
,
);
();
}
}
}
bool
::
(
,
bool
,
bool
,
bool
)
{
NormalizeSelectedItemIndexStartEnd
();
if
(
0
<=
&&
<
())
{
if
(!
)
{
if
(
.
(
))
{
return
true
;
}
}
if
(!
)
{
=
false
;
=
false
;
}
if
(
)
{
if
(!
)
{
.
();
();
}
=
;
SetMultipleItemsSelectedSilently
(
,
,
true
);
();
}
else
{
if
(
)
{
=
.
(
);
if
(
index
== -
1
)
{
.
(
);
}
else
{
.
(
index
);
}
(
,
index
== -
1
);
();
}
else
{
.
();
();
.
(
);
(
,
true
);
();
}
=
;
=
;
}
return
true
;
}
return
false
;
}
bool
::
(
,
bool
,
bool
)
{
if
(!
())
return
false
;
NormalizeSelectedItemIndexStartEnd
();
=
::
;
switch
(
)
{
case
::
:
keyDirection
=
::
;
break
;
case
::
:
keyDirection
=
::
;
break
;
case
::
:
keyDirection
=
::
;
break
;
case
::
:
keyDirection
=
::
;
break
;
case
::
:
keyDirection
=
::
;
break
;
case
::
:
keyDirection
=
::
;
break
;
case
::
:
keyDirection
=
::
;
break
;
case
::
:
keyDirection
=
::
;
break
;
default
:
return
false
;
}
if
(
())
{
keyDirection
=
()->
RealKeyDirectionToVirtualKeyDirection
(
keyDirection
);
}
=
()->
(
,
keyDirection
);
if
(
(
itemIndex
,
,
,
true
))
{
return
(
itemIndex
);
}
else
{
return
false
;
}
}
void
::
()
{
if
(
.
()>
0
)
{
.
();
();
();
}
}
namespace
{
void
::
(
,
,
)
{
CHECK_ERROR(!callingOnItemModified, L"ItemProviderBase::InvokeOnItemModified(vint, vint, vint)#Canning modify the observable data source during its item modified event, which will cause this event to be executed recursively.");
do
{
if
(!(!
))
throw
(
L"ItemProviderBase::InvokeOnItemModified(vint, vint, vint)#Canning modify the observable data source during its item modified event, which will cause this event to be executed recursively."
);}
while
(
0
);
=
true
;
for
(
=
0
;
i
<
.
();
i
++)
{
i
]->
(
,
,
);
}
=
false
;
}
::
()
{
}
::
()
{
for
(
=
0
;
i
<
.
();
i
++)
{
i
]->
(
0
);
}
}
bool
::
(
::
*
)
{
if
(
.
(
))
{
return
false
;
}
else
{
.
(
);
->
(
this
);
return
true
;
}
}
bool
::
(
::
*
)
{
=
.
(
);
if
(
index
==-
1
)
{
return
false
;
}
else
{
->
(
0
);
.
(
);
return
true
;
}
}
void
::
()
{
++;
}
bool
::
()
{
if
(
==
0
)
return
false
;
--;
return
true
;
}
bool
::
()
{
return
>
0
;
}
}
}
}
}