2#include <winrt/windows.ui.xaml.h>
3#include <winrt/windows.ui.xaml.media.h>
4#include <winrt/windows.UI.Xaml.Controls.h>
5#include <winrt/Windows.UI.Xaml.Interop.h>
6#include <winrt/Windows.UI.Xaml.Markup.h>
8#include <winrt/Windows.Foundation.Collections.h>
9#include <winrt/Windows.Foundation.h>
15#include <microsoft.ui.xaml.window.h>
43 WrapperT(
const T& v = T()) : m_value(v) {}
48 const T* operator->()
const {
return &m_value; }
54 auto Name()
const {
return m_value.Name(); }
60 auto Name(std::wstring_view n)
const { m_value.Name(n);
return *
this; }
66 auto Margin()
const {
return m_value.Margin(); }
72 auto Margin(cppxaml::xaml::Thickness t)
const { m_value.Margin(t);
return *
this; }
78 auto Margin(
double m)
const { m_value.Margin(cppxaml::xaml::ThicknessHelper::FromUniformLength(m));
return *
this; }
87 auto Margin(
double left,
double top,
double right,
double bottom)
const {
88 m_value.Margin(cppxaml::xaml::ThicknessHelper::FromLengths(left, top, right, bottom));
return *
this;
95 auto Padding()
const {
return m_value.Padding(); }
101 auto Padding(cppxaml::xaml::Thickness t)
const { m_value.Padding(t);
return *
this; }
107 auto Padding(
double m)
const { m_value.Padding(cppxaml::xaml::ThicknessHelper::FromUniformLength(m));
return *
this; }
116 auto Padding(
double left,
double top,
double right,
double bottom)
const {
117 m_value.Padding(cppxaml::xaml::ThicknessHelper::FromLengths(left, top, right, bottom));
return *
this;
120 template<
typename D, std::enable_if_t<std::is_assignable_v<D, T>,
bool> = true>
138 template<
typename TValue>
139 auto Set(cppxaml::xaml::DependencyProperty dp, TValue&& value) {
140 if constexpr (std::is_assignable_v<winrt::Windows::Foundation::IInspectable, TValue>) {
141 m_value.SetValue(dp, std::move(value));
144 m_value.SetValue(dp, winrt::box_value(std::move(value)));
170 auto VisualStates(
const std::unordered_map<std::wstring, cppxaml::xaml::VisualStateChangedEventHandler>& map) {
171 return cppxaml::VSMListener(*
this, map);
175 using VisualStateMap = std::unordered_map<std::wstring, cppxaml::xaml::VisualStateChangedEventHandler>;
177 template<
typename T,
typename TItems =
void>
178 struct Wrapper : WrapperT<T> {};
184 struct Wrapper<
cppxaml::xaml::Controls::ContentDialog> :
WrapperT<cppxaml::xaml::Controls::ContentDialog> {
185 auto PrimaryButtonText(std::wstring_view t) {
186 this->m_value.as<cppxaml::xaml::Controls::ContentDialog>().PrimaryButtonText(t);
195 struct Wrapper<
cppxaml::xaml::Controls::StackPanel> :
WrapperT<cppxaml::xaml::Controls::StackPanel> {
196 auto Orientation(cppxaml::xaml::Controls::Orientation o) {
197 this->m_value.as<cppxaml::xaml::Controls::StackPanel>().Orientation(o);
206 template<
typename TItems>
207 struct Wrapper<
cppxaml::xaml::Controls::AutoSuggestBox, TItems> :
WrapperT<cppxaml::xaml::Controls::AutoSuggestBox>, std::enable_shared_from_this<Wrapper<cppxaml::xaml::Controls::AutoSuggestBox, TItems>> {
210 bool m_caseInsensitive{
false };
212 Wrapper(
const TItems& items) : m_items(items) {}
213 Wrapper(
const Wrapper<cppxaml::xaml::Controls::AutoSuggestBox, TItems>& other) : m_items(other.m_items) {
214 if (other.m_textChangedToken) {
215 SetEventHandlers(other.m_caseInsensitive);
218 Wrapper(Wrapper&& other) : m_items(other.m_items),
219 m_textChangedToken(std::move(other.m_textChangedToken)),
220 m_suggestionChosenToken(std::move(other.m_suggestionChosenToken))
222 other.m_textChangedToken = {};
223 other.m_suggestionChosenToken = {};
241 winrt::event_token m_textChangedToken{};
242 winrt::event_token m_suggestionChosenToken{};
243 void SetEventHandlers(
bool caseInsensitive) {
244 m_caseInsensitive = caseInsensitive;
246 auto GetReason = [](cppxaml::xaml::Controls::AutoSuggestBoxTextChangedEventArgs
const& args) -> cppxaml::xaml::Controls::AutoSuggestionBoxTextChangeReason {
return args.Reason(); };
247 m_textChangedToken = m_value.TextChanged([GetReason, caseInsensitive, items = this->m_items](cppxaml::xaml::Controls::AutoSuggestBox sender, cppxaml::xaml::Controls::AutoSuggestBoxTextChangedEventArgs args) {
248 if (GetReason(args) == cppxaml::xaml::Controls::AutoSuggestionBoxTextChangeReason::UserInput) {
249 std::wstring search = caseInsensitive ?
utils::tolower(sender.Text()) : sender.Text().c_str();
252 for (
const auto& entry : items) {
253 auto str = caseInsensitive ?
utils::tolower(entry) : entry.c_str();
254 if (search == L
"" || str.find(search) != -1) {
255 vec.push_back(entry);
258 auto suitableItems = winrt::single_threaded_vector<winrt::Windows::Foundation::IInspectable>();
259 winrt::Windows::Foundation::IInspectable selected{
nullptr };
260 for (
const auto& e : vec) {
261 auto boxed = winrt::box_value(e);
265 suitableItems.Append(boxed);
267 sender.ItemsSource(suitableItems);
269 sender.Text(winrt::unbox_value<winrt::hstring>(selected));
273 m_suggestionChosenToken = m_value.SuggestionChosen([](cppxaml::xaml::Controls::AutoSuggestBox sender, cppxaml::xaml::Controls::AutoSuggestBoxSuggestionChosenEventArgs args) {
274 sender.Text(winrt::unbox_value<winrt::hstring>(args.SelectedItem()));
285 SetEventHandlers(caseInsensitive);
290 template<
typename TItems>
291 struct Wrapper<
cppxaml::xaml::Controls::ItemsControl, TItems> : WrapperT<cppxaml::xaml::Controls::ItemsControl> {
292 using items_t = TItems;
300 struct Wrapper<
cppxaml::xaml::Controls::MenuFlyoutItem> :
WrapperT<cppxaml::xaml::Controls::MenuFlyoutItem> {
305 cppxaml::xaml::Controls::IconElement
IconElement()
const {
return m_value.Icon(); }
311 auto IconElement(cppxaml::xaml::Controls::IconElement icon)
const {
312 m_value.Icon(icon);
return *
this;
314 winrt::event_token m_clickToken{};
327 auto Click(cppxaml::xaml::RoutedEventHandler handler) {
328 m_clickToken = m_value.Click(handler);
337 struct Wrapper<
cppxaml::xaml::Controls::MenuFlyout> :
WrapperT<cppxaml::xaml::Controls::MenuFlyout> {
346 if (m_eventHandlers.size() != 0) {
347 throw std::exception(
"Centralized handler already set");
350 for (
auto i : m_value.Items()) {
351 if (
auto mfi = i.try_as<cppxaml::xaml::Controls::MenuFlyoutItem>()) {
352 m_eventHandlers.push_back(mfi.Click([f](winrt::Windows::Foundation::IInspectable sender, cppxaml::xaml::RoutedEventArgs args) {
359 std::vector<winrt::event_token> m_eventHandlers{};
378 operator cppxaml::xaml::GridLength()
const {
return m_length; }
379 GridLength2(
double len) : m_length(
cppxaml::xaml::GridLengthHelper::FromPixels(len)) {}
380 GridLength2(std::wstring_view v) {
381 m_length = winrt::unbox_value<cppxaml::xaml::GridLength>(cppxaml::xaml::Markup::XamlBindingHelper::ConvertValue(winrt::xaml_typename<cppxaml::xaml::GridLength>(), winrt::box_value(v)));
383 GridLength2(std::string_view v) : GridLength2(winrt::to_hstring(v)) {}
385 cppxaml::xaml::GridLength m_length;
388 std::vector<cppxaml::xaml::GridLength> m_lengths;
389 GridLengths(std::initializer_list<GridLength2>&& ls) {
391 m_lengths.push_back(l);
394 GridLengths(std::string_view sv) {
395 std::string_view last;
396 for (std::string_view::size_type pos = 0; pos < sv.length(); ) {
397 auto nextDelimiter = sv.find(
",", pos);
398 last = sv.substr(pos, nextDelimiter - pos);
399 auto len = winrt::unbox_value<cppxaml::xaml::GridLength>(cppxaml::xaml::Markup::XamlBindingHelper::ConvertValue(winrt::xaml_typename<cppxaml::xaml::GridLength>(), winrt::box_value(winrt::to_hstring(last))));
400 m_lengths.push_back(len);
402 if (nextDelimiter != -1) {
403 pos = nextDelimiter + 1;
412 using GridRows = GridLengths;
413 using GridColumns = GridLengths;
415 struct UIElementInGrid {
418 cppxaml::xaml::UIElement m_element{
nullptr };
431 IF_ASSIGNABLE_CONTROL(ContentControl)
433 cppxaml::details::Wrapper<T> t;
445 IF_ASSIGNABLE_CONTROL(ContentControl)
447 cppxaml::details::Wrapper<T> t;
448 t->Content(winrt::box_value(v));
459 IF_ASSIGNABLE_CONTROL(Panel)
461 cppxaml::details::Wrapper<T> panel;
462 for (
auto e : elems) {
463 panel->Children().Append(e);
477 return MakeContentControl<cppxaml::xaml::Controls::ContentDialog>(i);
485 auto StackPanel(
const std::initializer_list<cppxaml::xaml::UIElement>& elems) {
486 return MakePanel<cppxaml::xaml::Controls::StackPanel>(elems);
508 template<
typename TElements>
509 DOXY_RT(cppxaml::details::Wrapper<cppxaml::xaml::Controls::Grid>)
510 Grid(details::GridRows gr,
cppxaml::details::GridColumns gc, TElements && elems) {
511 auto grid = cppxaml::details::Wrapper<cppxaml::xaml::Controls::Grid>();
512 for (
auto& r : gr.m_lengths) {
513 auto rd = cppxaml::xaml::Controls::RowDefinition();
515 grid->RowDefinitions().Append(rd);
517 for (
auto& c : gc.m_lengths) {
518 auto cd = cppxaml::xaml::Controls::ColumnDefinition();
520 grid->ColumnDefinitions().Append(cd);
523 for (
auto& e : elems) {
524 if constexpr (std::is_assignable_v<cppxaml::details::UIElementInGrid,
decltype(e)>) {
525 grid->Children().Append(e.m_element);
526 cppxaml::xaml::Controls::Grid::SetRow(e.m_element.as<cppxaml::xaml::FrameworkElement>(), e.m_row);
527 cppxaml::xaml::Controls::Grid::SetColumn(e.m_element.as<cppxaml::xaml::FrameworkElement>(), e.m_column);
530 grid->Children().Append(e);
542 cppxaml::details::Wrapper<cppxaml::xaml::Controls::TextBox> tb;
557 template<
typename T,
typename TItems>
558 IF_ASSIGNABLE_CONTROL_TITEMS(ItemsControl, TItems)
560 cppxaml::details::Wrapper<T, TItems> t(items);
561 for (
auto& i : items) {
562 if constexpr (std::is_assignable_v<winrt::Windows::Foundation::IInspectable,
decltype(i)>) {
563 t->Items().Append(i);
566 t->Items().Append(winrt::box_value(i));
579 template<
typename TItems>
581 return MakeItemsControl<cppxaml::xaml::Controls::AutoSuggestBox, TItems>(svs);
589 DOXY_RT(cppxaml::details::Wrapper<cppxaml::xaml::Controls::TextBlock>)
591 cppxaml::details::Wrapper<cppxaml::xaml::Controls::TextBlock> tb;
605 return MakeContentControl<cppxaml::xaml::Controls::Button>(c);
614 cppxaml::details::Wrapper<cppxaml::xaml::Controls::FontIcon> fi;
626 icon[0] = glyph & 0xffff;
627 icon[1] = (glyph >> 16) & 0xffff;
638 cppxaml::details::Wrapper<cppxaml::xaml::Controls::MenuFlyoutItem> mfi;
643 template<
typename T,
typename TArg>
644 void AddItems(T t, TArg&& first) {
645 t.Items().Append(first);
648 template<
typename T,
typename TArg,
typename... TArgs>
649 void AddItems(T t, TArg&& first, TArgs&&... rest) {
650 t.Items().Append(first);
651 if constexpr (
sizeof...(TArgs) > 0) {
652 AddItems(t, rest...);
661 template<
typename... TMenuFlyoutItemBase>
663 cppxaml::details::Wrapper<cppxaml::xaml::Controls::MenuFlyout> mf;
664 AddItems(*mf, items...);
auto tolower(std::wstring_view sv)
Definition: utils.h:34
The main CppXAML namespace.
MakeItemsControl(const TItems &items)
Creates a XAML element of a type that derives from ItemsControl
Definition: Controls.h:559
MakeContentControl(winrt::Windows::Foundation::IInspectable i)
Create a XAML element of a class that derives from ContentControl
Definition: Controls.h:432
auto Button(C c)
Creates a Button.
Definition: Controls.h:604
auto ContentDialog(C i)
Creates a ContentDialog
Definition: Controls.h:476
Grid(details::GridRows gr, cppxaml::details::GridColumns gc, TElements &&elems)
Creates a Grid with the specified rows, columns, and children.
Definition: Controls.h:510
auto StackPanel(const std::initializer_list< cppxaml::xaml::UIElement > &elems)
Creates a StackPanel.
Definition: Controls.h:485
auto TextBox(std::wstring_view text=L"")
Creates a TextBox
Definition: Controls.h:541
auto MenuFlyout(TMenuFlyoutItemBase &&... items)
Creates a MenuFlyout from a list of MenuFlyoutItems
Definition: Controls.h:662
MakePanel(const std::initializer_list< cppxaml::xaml::UIElement > &elems)
Creates a XAML element of a type that is a subclass of Panel.
Definition: Controls.h:460
auto FontIcon(std::wstring_view icon)
Creates a FontIcon from a string.
Definition: Controls.h:613
auto AutoSuggestBox(const TItems &svs)
Creates an AutoSuggestBox from a list of items.
Definition: Controls.h:580
auto MenuFlyoutItem(std::wstring_view text)
Creates a MenuFlyoutItem with the specified text.
Definition: Controls.h:637
TextBlock(std::wstring_view text)
Creates a TextBlock from its text content.
Definition: Controls.h:590
auto EnableDefaultSearch(bool caseInsensitive=true)
Enables a default search experience for the AutoSuggestBox. The list of items shown gets filtered as ...
Definition: Controls.h:284
Internal wrapper type that powers builder-style programming. This type is usually constructed and de...
Definition: Controls.h:40
auto Padding(double left, double top, double right, double bottom) const
Definition: Controls.h:116
auto Name(std::wstring_view n) const
Set the element's Name.
Definition: Controls.h:60
auto Name() const
Returns the element's Name.
Definition: Controls.h:54
auto Margin() const
Definition: Controls.h:66
auto Margin(double m) const
Definition: Controls.h:78
auto Margin(double left, double top, double right, double bottom) const
Definition: Controls.h:87
auto Set(cppxaml::xaml::DependencyProperty dp, TValue &&value)
Sets a property.
Definition: Controls.h:139
auto Margin(cppxaml::xaml::Thickness t) const
Definition: Controls.h:72
auto Padding() const
Definition: Controls.h:95
auto Padding(cppxaml::xaml::Thickness t) const
Definition: Controls.h:101
auto Padding(double m) const
Definition: Controls.h:107
auto VisualStates(const std::unordered_map< std::wstring, cppxaml::xaml::VisualStateChangedEventHandler > &map)
Sets up a visual state change listeners.
Definition: Controls.h:170