#include "GuiRibbonControls.h"
#include "../Templates/GuiThemeStyleFactory.h"
#include "../../GraphicsComposition/GuiGraphicsStackComposition.h"
#include "../../GraphicsComposition/GuiGraphicsTableComposition.h"
#include "../../GraphicsComposition/GuiGraphicsResponsiveComposition.h"
#include "../../GraphicsComposition/GuiGraphicsSharedSizeComposition.h"
namespace
{
namespace
{
namespace
{
using
namespace
reflection
::
description
;
using
namespace
collections
;
using
namespace
compositions
;
using
namespace
theme
;
using
namespace
templates
;
void
::
BeforeControlTemplateUninstalled_
()
{
auto
=
TypedControlTemplateObject
(
false
);
if
(!
ct
)
return
;
if
(
auto
=
ct
->
GetBeforeHeadersContainer
())
{
bhc
->
(
);
}
if
(
auto
=
ct
->
())
{
ahc
->
(
);
}
}
void
::
AfterControlTemplateInstalled_
(
bool
)
{
auto
=
TypedControlTemplateObject
(
true
);
if
(
auto
=
ct
->
GetBeforeHeadersContainer
())
{
bhc
->
(
);
}
if
(
auto
=
ct
->
())
{
ahc
->
(
);
}
}
::
(
theme
::
)
:
(
)
{
=
new
();
->
(
(
0
,
0
,
0
,
0
));
->
(
::
LimitToElementAndChildren
);
=
new
();
->
(
(
0
,
0
,
0
,
0
));
->
(
::
LimitToElementAndChildren
);
}
::
()
{
if
(!
->
())
{
(
);
}
if
(!
->
())
{
(
);
}
}
compositions
::
*
::()
{
return
;
}
compositions
::
*
::()
{
return
;
}
bool
::
(
,
*
const
&
)
{
return
!
->
()->
();
}
void
::
(
,
*
const
&
)
{
->
()->
(
(
0
,
0
,
0
,
0
));
auto
=
new
();
item
->
(
->
());
->
->
(
,
item
);
}
void
::
(
,
)
{
for
(
=
0
;
i
<
;
i
++)
{
auto
=
->
->
()
];
->
->
(
item
);
item
->
(
item
->
()
0
]);
delete
item
;
}
}
::
(
*
)
:tabPage(
)
{
}
::
~
GuiRibbonGroupCollection
()
{
}
::
(
theme
::
)
:
(
)
, groups(
this
)
{
=
new
();
->
(
::
);
->
(
(
2
,
2
,
2
,
2
));
->
(
2
);
->
(
::
LimitToElementAndChildren
);
=
new
GuiResponsiveStackComposition
();
->
(
::
);
->
(
(
0
,
0
,
0
,
0
));
->
(
);
=
new
GuiResponsiveContainerComposition
();
->
(
(
0
,
0
,
0
,
0
));
->
(
);
->
(
);
.
(
);
}
::
()
{
}
bool
::
()
{
return
;
}
void
::
(
bool
)
{
if
(
!=
)
{
=
;
.
(
());
}
}
collections
::
<
*>&
::
()
{
return
;
}
bool
GuiRibbonGroupItemCollection
::
(
,
*
const
&
)
{
return
!
->
()->
();
}
void
GuiRibbonGroupItemCollection
::
(
,
*
const
&
)
{
->
()->
(
(
0
,
0
,
0
,
0
));
auto
=
new
();
item
->
(
->
());
->
->
(
,
item
);
}
void
GuiRibbonGroupItemCollection
::
(
,
)
{
for
(
=
0
;
i
<
;
i
++)
{
auto
=
->
->
()
];
->
->
(
item
);
item
->
(
item
->
()
0
]);
delete
item
;
}
}
GuiRibbonGroupItemCollection
::
GuiRibbonGroupItemCollection
(
*
)
:group(
)
{
}
GuiRibbonGroupItemCollection
::
~
GuiRibbonGroupItemCollection
()
{
}
::
::
(
*
)
:group(
)
{
}
::
::
()
{
}
void
::
::
()
{
->
.
(
->
());
}
class
:
public
,
public
<
>
{
private
:
::
()
override
{
return
::
;
}
bool
()
override
{
return
false
;
}
public
:
(
theme
::
,
* )
:
(
,
)
{
}
};
void
::
BeforeControlTemplateUninstalled_
()
{
auto
=
TypedControlTemplateObject
(
false
);
if
(!
ct
)
return
;
ct
->
(
nullptr
);
}
void
::
AfterControlTemplateInstalled_
(
bool
)
{
auto
=
TypedControlTemplateObject
(
true
);
ct
->
(
);
ct
->
(
->
() ==
);
ct
->
(
.
());
->
(
ct
->
GetLargeDropdownButtonTemplate
());
->
(
ct
->
());
}
bool
::
()
{
return
!=
L""
;
}
compositions
::
*
::
()
{
if
(
())
{
return
this
;
}
else
{
return
::
();
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
->
()->
(
(
0
,
->
().
()));
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
->
(
());
}
void
::(
compositions
::
* ,
compositions
::
& )
{
if
(
->
().
(
))
{
auto
=
;
if
(
.
() ==
1
)
{
if
(
auto
=
0
]->
<
>())
{
if
(
auto
=
provider
->
())
{
currentDropdown
=
menu
;
}
}
}
->
(
currentDropdown
,
false
);
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
if
(
auto
=
TypedControlTemplateObject
(
false
))
{
ct
->
(
.
==
1
);
}
if
(
.
==
0
)
{
while
(
->
());
->
()->
(
);
->
(
);
->
(
nullptr
,
false
);
}
else
{
while
(
->
());
->
(
);
->
()->
(
);
}
}
::
(
theme
::
)
:
(
)
, items(
this
)
{
(
);
(
this
,
false
);
new
(
this
);
{
=
new
();
->
(
::
);
->
(
(
0
,
0
,
0
,
0
));
->
(
2
);
->
(
::
LimitToElementAndChildren
);
=
new
GuiResponsiveStackComposition
();
->
(
::
);
->
(
(
0
,
0
,
0
,
0
));
->
(
);
}
{
=
new
(
theme
::
::
RibbonLargeDropdownButton
);
->
()->
(
(
0
,
0
,
0
,
0
));
=
new
GuiResponsiveFixedComposition
();
->
(
(
0
,
0
,
0
,
0
));
->
(
->
());
=
new
(
theme
::
::
,
);
}
=
new
GuiResponsiveViewComposition
();
->
(
(
0
,
0
,
0
,
0
));
->
().
(
);
->
(
);
.
(
);
.
(
);
.
(
);
.
(
this
, &
::
);
->
.
(
this
, &
::
);
->
.
(
this
, &
::
);
->
.
(
this
, &
::
);
}
::
()
{
if
(!
->
().
(
))
{
(
);
}
delete
;
}
bool
::
()
{
return
;
}
void
::
(
bool
)
{
if
(
!=
)
{
=
;
TypedControlTemplateObject
(
true
)->
(
);
.
(
());
}
}
<
>
::
()
{
return
;
}
void
::
(
<
>
)
{
if
(
)
{
;
->
(
);
.
(
());
if
(
)
{
if
(!
->
().
(
))
{
->
().
(
);
}
}
else
{
if
(
->
().
(
))
{
->
().
(
);
}
}
}
}
collections
::
<
*>&
::
()
{
return
;
}
void
::
BeforeControlTemplateUninstalled_
()
{
}
void
::
AfterControlTemplateInstalled_
(
bool
)
{
auto
=
TypedControlTemplateObject
(
true
);
ct
->
(
);
}
::
(
theme
::
)
:
(
)
{
.
(
);
}
::
()
{
}
<
>
::
()
{
return
;
}
void
::
(
<
>
)
{
if
(
)
{
;
TypedControlTemplateObject
(
true
)->
(
);
.
(
());
}
}
bool
GuiRibbonButtonsItemCollection
::
(
,
*
const
&
)
{
return
!
->
()->
();
}
void
GuiRibbonButtonsItemCollection
::
(
,
*
const
&
)
{
->
->
().
(
);
->
(
->
->
(),
);
for
(
=
0
;
i
<
sizeof
(
->
) /
sizeof
(*
->
);
i
++)
{
if
(
auto
=
->
[
i
])
{
auto
=
dynamic_cast
<
*>(
view
->
()
0
]);
auto
=
new
GuiResponsiveSharedComposition
();
shared
->
(
(
0
,
0
,
0
,
0
));
shared
->
(
);
auto
=
new
();
item
->
(
shared
);
stack
->
(
,
item
);
}
}
}
void
GuiRibbonButtonsItemCollection
::
(
,
*
const
&
)
{
CHECK_FAIL(L"GuiRibbonButtonsItemCollection::BeforeRemove(vint, GuiControl* const&)#Controls are not allowed to be removed from GuiRibbonButtons.");
do
{
throw
(
L"GuiRibbonButtonsItemCollection::BeforeRemove(vint, GuiControl* const&)#Controls are not allowed to be removed from GuiRibbonButtons."
);}
while
(
0
);
}
GuiRibbonButtonsItemCollection
::
(
*
)
:buttons(
)
{
}
GuiRibbonButtonsItemCollection
::
()
{
}
void
::
()
{
}
void
::
(
bool
)
{
FOREACH(GuiControl*, button, buttons)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
*>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
*
;
__foreach_iterator__
.
(
button
);)
{
(
->
(),
button
);
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
FOREACH(GuiControl*, button, buttons)
if
(
bool
=
true
)
for
(
const
::
vl
::
collections
::
<
*>&
= ::
vl
::
collections
::
(
);
__scope_variable_flag__
;
__scope_variable_flag__
=
false
)
for
(
*
;
__foreach_iterator__
.
(
button
);)
{
(
->
()
.
],
button
);
}
}
void
::
(
compositions
::
GuiResponsiveCompositionBase
*
,
*
)
{
if
(
&&
)
{
auto
=
->
();
= -
1
;
switch
(
themeName
)
{
case
::
:
case
::
:
case
::
:
type
=
0
;
break
;
case
::
RibbonLargeDropdownButton
:
case
::
RibbonSmallDropdownButton
:
case
::
:
type
=
1
;
break
;
case
::
:
case
::
:
case
::
:
type
=
2
;
break
;
case
::
:
case
::
:
type
=
3
;
break
;
default
:;
}
if
(
type
!= -
1
)
{
=
::
;
<
GuiToolstripButtonTemplate
>
;
if
(
==
[(
)
::
])
{
switch
(
type
)
{
case
0
:
themeName
=
::
;
break
;
case
1
:
themeName
=
::
RibbonLargeDropdownButton
;
break
;
case
2
:
themeName
=
::
;
break
;
case
3
:
themeName
=
::
;
break
;
}
}
else
if
(
==
[(
)
::
])
{
switch
(
type
)
{
case
0
:
themeName
=
::
;
break
;
case
1
:
themeName
=
::
RibbonSmallDropdownButton
;
break
;
case
2
:
themeName
=
::
;
break
;
case
3
:
themeName
=
::
;
break
;
}
}
else
if
(
==
[(
)
::
])
{
switch
(
type
)
{
case
0
:
themeName
=
::
;
break
;
case
1
:
themeName
=
::
;
break
;
case
2
:
themeName
=
::
;
break
;
case
3
:
themeName
=
::
;
break
;
}
}
if
(
auto
=
TypedControlTemplateObject
(
false
))
{
if
(
==
[(
)
::
])
{
switch
(
type
)
{
case
0
:
controlTemplate
ct
->
();
break
;
case
1
:
controlTemplate
ct
->
GetLargeDropdownButtonTemplate
();
break
;
case
2
:
controlTemplate
ct
->
GetLargeSplitButtonTemplate
();
break
;
case
3
:
controlTemplate
ct
->
GetSmallIconLabelTemplate
();
break
;
}
}
else
if
(
==
[(
)
::
])
{
switch
(
type
)
{
case
0
:
controlTemplate
ct
->
();
break
;
case
1
:
controlTemplate
ct
->
GetSmallDropdownButtonTemplate
();
break
;
case
2
:
controlTemplate
ct
->
GetSmallSplitButtonTemplate
();
break
;
case
3
:
controlTemplate
ct
->
GetSmallIconLabelTemplate
();
break
;
}
}
else
if
(
==
[(
)
::
])
{
switch
(
type
)
{
case
0
:
controlTemplate
ct
->
();
break
;
case
1
:
controlTemplate
ct
->
GetIconDropdownButtonTemplate
();
break
;
case
2
:
controlTemplate
ct
->
GetIconSplitButtonTemplate
();
break
;
case
3
:
controlTemplate
ct
->
();
break
;
}
}
}
->
SetControlThemeNameAndTemplate
(
themeName
,
controlTemplate
);
}
}
}
::
(
theme
::
,
,
)
:
(
)
, maxSize(
)
, minSize(
)
, buttons(
this
)
{
=
new
GuiResponsiveViewComposition
();
->
(
::
);
->
(
(
0
,
0
,
0
,
0
));
->
.
(
this
, &
::
);
auto
= [&](
*
,
,
,
*
)
{
auto
=
new
GuiResponsiveSharedComposition
();
shared
->
(
(
0
,
0
,
0
,
0
));
shared
->
(
buttonContainer
);
auto
=
new
();
cell
->
(
row
,
column
,
1
,
1
);
cell
->
(
shared
);
table
->
(
cell
);
};
for
(
=
0
;
i
<
sizeof
(
) /
sizeof
(*
);
i
++)
{
if
((
)
<=
i
&&
i
<= (
)
)
{
auto
=
new
();
stack
->
(
(
0
,
0
,
0
,
0
));
stack
->
(
::
LimitToElementAndChildren
);
stack
->
(
i
==
0
?
::
:
::
);
[
i
] =
new
GuiResponsiveFixedComposition
();
[
i
]->
(
stack
);
->
().
(
[
i
]);
}
}
auto
=
new
GuiSharedSizeRootComposition
();
sharedSizeRootComposition
->
(
(
0
,
0
,
0
,
0
));
sharedSizeRootComposition
->
(
::
LimitToElementAndChildren
);
sharedSizeRootComposition
->
(
);
->
(
sharedSizeRootComposition
);
}
::
()
{
}
collections
::
<
*>&
::
()
{
return
;
}
bool
GuiRibbonToolstripsGroupCollection
::
(
,
*
const
&
)
{
return
!
->
()->
();
}
void
GuiRibbonToolstripsGroupCollection
::
(
,
*
const
&
)
{
->
();
}
void
GuiRibbonToolstripsGroupCollection
::
(
,
)
{
->
();
}
GuiRibbonToolstripsGroupCollection
::
(
*
)
:toolstrips(
)
{
}
GuiRibbonToolstripsGroupCollection
::
()
{
}
#define ARRLEN(X) sizeof(X) / sizeof(*X)
void
::
()
{
}
void
::
(
bool
)
{
auto
=
TypedControlTemplateObject
(
true
);
for (vint i = 0; i < ARRLEN(toolbars); i++)
for
(
=
0
;
i
<
sizeof
(
) /
sizeof
(*
);
i
++)
{
[
i
]->
(
ct
->
());
}
}
void
::
(
compositions
::
*
,
compositions
::
&
)
{
(
.
);
}
void
::
(
)
{
static_assert(ARRLEN(longContainers) == 2, "");
static_assert
(
sizeof
(
) /
sizeof
(*
) ==
2
,
""
);
static_assert(ARRLEN(shortContainers) == 3, "");
static_assert
(
sizeof
(
) /
sizeof
(*
) ==
3
,
""
);
if
(
== -
1
)
{
=
->
().
(
->
());
}
for (vint i = 0; i < ARRLEN(longContainers); i++)
for
(
=
0
;
i
<
sizeof
(
) /
sizeof
(*
);
i
++)
{
[
i
]->
().
();
}
for (vint i = 0; i < ARRLEN(shortContainers); i++)
for
(
=
0
;
i
<
sizeof
(
) /
sizeof
(*
);
i
++)
{
[
i
]->
().
();
}
=
==
0
?
2
:
3
;
if
(
.
() <=
count
)
{
auto
=
==
0
?
:
;
for
(
=
0
;
i
<
.
();
i
++)
{
containers
[
i
]->GetToolstripItems().Add(
i
]);
}
}
else
if
(
count
==
3
)
{
#define DELTA(POSTFIX) (abs(count1##POSTFIX - count2##POSTFIX) + abs(count2##POSTFIX - count3##POSTFIX) + abs(count3##POSTFIX - count1##POSTFIX))
#define DEFINE_COUNT(POSTFIX, OFFSET_FIRST, OFFSET_LAST) \
vint count1##POSTFIX = count1_o + (OFFSET_FIRST); \
vint count2##POSTFIX = count2_o - (OFFSET_FIRST) - (OFFSET_LAST); \
vint count3##POSTFIX = count3_o + (OFFSET_LAST)
#define MIN(a, b) (a)<(b)?(a):(b)
=
0
;
=
0
;
=
0
;
=
(
)
.Select([](
*
) {
return
group
->
().
(); })
.Aggregate([](
,
) {
return
a
+
b
; });
=
0
;
vint delta_o = DELTA(_o);
= (
(
count1_o
-
count2_o
) +
(
count2_o
-
count3_o
) +
(
count3_o
-
count1_o
));
while
(
firstGroupCount
+
lastGroupCount
<
.
())
{
auto
=
firstGroupCount
];
auto
=
.
() -
lastGroupCount
-
1
];
DEFINE_COUNT(_f, newFirstGroup->GetToolstripItems().Count(), 0);
=
count1_o
+ (
newFirstGroup
->
().
());
=
count2_o
- (
newFirstGroup
->
().
()) - (
0
);
=
count3_o
+ (
0
);
vint delta_f = DELTA(_f);
= (
(
count1_f
-
count2_f
) +
(
count2_f
-
count3_f
) +
(
count3_f
-
count1_f
));
DEFINE_COUNT(_l, 0, newLastGroup->GetToolstripItems().Count());
=
count1_o
+ (
0
);
=
count2_o
- (
0
) - (
newLastGroup
->
().
());
=
count3_o
+ (
newLastGroup
->
().
());
vint delta_l = DELTA(_l);
= (
(
count1_l
-
count2_l
) +
(
count2_l
-
count3_l
) +
(
count3_l
-
count1_l
));
vint delta = MIN(delta_o, MIN(delta_f, delta_l));
= (
delta_o
)<((
delta_f
)<(
delta_l
)?(
delta_f
):(
delta_l
))?(
delta_o
):((
delta_f
)<(
delta_l
)?(
delta_f
):(
delta_l
));
if
(
delta
==
delta_f
)
{
firstGroupCount
++;
count1_o
=
count1_f
;
count2_o
=
count2_f
;
count3_o
=
count3_f
;
delta_o
=
delta_f
;
}
else
if
(
delta
==
delta_l
)
{
lastGroupCount
++;
count1_o
=
count1_l
;
count2_o
=
count2_l
;
count3_o
=
count3_l
;
delta_o
=
delta_l
;
}
else
{
break
;
}
}
=
firstGroupCount
;
=
.
() -
lastGroupCount
-
1
;
for
(
=
0
;
j
<
.
();
j
++)
{
[
j
<
minMiddle
?
0
:
j
>
maxMiddle
?
2
:
1
]->
().
(
j
]);
}
#undef MIN
#undef DEFINE_COUNT
#undef DELTA
}
else
if
(
count
==
2
)
{
=
.
();
{
=
0
;
=
(
)
.Select([](
*
) {
return
group
->
().
(); })
.Aggregate([](
,
) {
return
a
+
b
; });
=
(
count2
-
count1
);
for
(
=
0
;
i
<
.
();
i
++)
{
auto
=
i
]->
().
();
=
count1
+
groupCount
;
=
count2
-
groupCount
;
=
(
count2_2
-
count1_2
);
if
(
delta
<
delta_2
)
{
firstGroupCount
=
i
;
break
;
}
count1
=
count1_2
;
count2
=
count2_2
;
delta
=
delta_2
;
}
}
for
(
=
0
;
j
<
.
();
j
++)
{
[
j
<
firstGroupCount
?
0
:
1
]->
().
(
j
]);
}
}
}
::
(
theme
::
)
:
(
)
, groups(
this
)
{
=
new
GuiResponsiveViewComposition
();
->
(
::
);
->
(
(
0
,
0
,
0
,
0
));
->
.
(
this
, &
::
);
=
0
;
for
(
=
0
;
i
<
sizeof
(
) /
sizeof
(*
);
i
++)
{
auto
=
i
==
0
?
:
;
=
i
==
0
?
2
:
3
;
auto
=
new
();
table
->
(
(
0
,
0
,
0
,
0
));
table
->
(
::
LimitToElementAndChildren
);
table
->
(
count
*
2
+
1
,
1
);
table
->
(
0
,
::
());
table
->
(
0
,
::
(
1.0
));
for
(
=
0
;
j
<
count
;
j
++)
{
table
->
(
j
*
2
+
1
,
::
());
table
->
(
j
*
2
+
2
,
::
(
1.0
));
}
for
(
=
0
;
j
<
count
;
j
++)
{
auto
=
new
(
theme
::
::
);
toolbar
->
()->
(
(
0
,
0
,
0
,
0
));
[
toolbarIndex
++] =
toolbar
;
auto
=
new
();
cell
->
(
j
*
2
+
1
,
0
,
1
,
1
);
cell
->
(
toolbar
->
());
table
->
(
cell
);
auto
=
new
GuiToolstripGroupContainer
(
theme
::
::
);
toolbar
->
().
(
container
);
containers
[
j
] =
container
;
}
[
i
] =
new
GuiResponsiveFixedComposition
();
[
i
]->
(
table
);
->
().
(
[
i
]);
}
->
(
);
}
::
()
{
}
collections
::
<
*>&
::
()
{
return
;
}
#undef ARRLEN
::
::
(
*
)
:gallery(
)
{
}
::
::
()
{
}
void
::
::
()
{
->
.
(
->
());
}
void
::
::
()
{
->
.
(
->
());
}
void
::
::
()
{
->
.
(
->
());
}
void
::
BeforeControlTemplateUninstalled_
()
{
auto
=
TypedControlTemplateObject
(
false
);
if
(!
ct
)
return
;
ct
->
(
nullptr
);
}
void
::
AfterControlTemplateInstalled_
(
bool
)
{
auto
=
TypedControlTemplateObject
(
true
);
ct
->
(
.
());
ct
->
(
);
ct
->
(
);
}
::
(
theme
::
)
:
(
)
{
new
(
this
);
.
(
);
.
(
);
.
(
);
.
(
);
.
(
);
}
::
()
{
}
bool
::
()
{
return
;
}
void
::
(
bool
)
{
if
(
!=
)
{
=
;
TypedControlTemplateObject
(
true
)->
(
);
}
}
bool
::
()
{
return
;
}
void
::
(
bool
)
{
if
(
!=
)
{
=
;
TypedControlTemplateObject
(
true
)->
(
);
}
}
void
::()
{
auto
=
TypedControlTemplateObject
(
false
);
if
(!
ct
)
return
;
if
(
auto
=
ct
->
())
{
cc
->
(
);
}
}
void
::(
bool
)
{
auto
=
TypedControlTemplateObject
(
true
);
if
(
auto
=
ct
->
())
{
cc
->
(
);
}
}
::(
theme
::
,
* )
:
(
,
)
{
=
new
();
->
(
(
0
,
0
,
0
,
0
));
->
(
::
LimitToElementAndChildren
);
}
::()
{
if
(!
->
())
{
(
);
}
}
compositions
::
*
::()
{
return
;
}
}
}
}