Nui
delocalized.hpp
Go to the documentation of this file.
1 #pragma once
2 
10 
11 #include <memory>
12 #include <optional>
13 #include <string>
14 
15 namespace Nui
16 {
20  template <typename SlotId>
22  {
23  public:
25  : delocalizedElement_{[&renderer]() -> decltype(delocalizedElement_) {
26  if (renderer)
27  {
29  element->replaceElement(renderer);
30  return element;
31  }
32  else
33  {
34  return {};
35  }
36  }()}
37  , slotId_{std::make_unique<Nui::Observed<SlotId>>()}
38  {}
39  Delocalized(Delocalized const&) = delete;
40  Delocalized(Delocalized&&) = default;
41  Delocalized& operator=(Delocalized const&) = delete;
43 
44  std::shared_ptr<Dom::Element> element()
45  {
46  return delocalizedElement_;
47  }
49  {
50  delocalizedElement_ = Dom::Element::makeElement(HtmlElement{"div", &RegularHtmlElementBridge});
51  delocalizedElement_->replaceElement(renderer);
52  }
53  bool hasElement() const
54  {
55  return delocalizedElement_ != nullptr;
56  }
58  {
59  if (!hasElement())
60  element(std::move(renderer));
61  }
62 
63  void slot(SlotId slot)
64  {
65  *slotId_ = slot;
66  }
67  SlotId slot() const
68  {
69  return slotId_->value();
70  }
71 
72  template <typename SlotIdB>
74  SlotIdB slot,
75  Delocalized<SlotIdB>& delocalizedElement,
76  std::vector<Attribute> wrapperAttributes,
77  Nui::ElementRenderer alternative);
78 
79  private:
80  std::shared_ptr<Dom::Element> delocalizedElement_;
81  // Wrapped in a unique_ptr for pointer stability.
82  std::unique_ptr<Nui::Observed<SlotId>> slotId_;
83  };
84 
85  template <typename SlotId>
87  SlotId slot,
88  Delocalized<SlotId>& delocalizedElement,
89  std::vector<Attribute> wrapperAttributes = {},
90  ElementRenderer alternative = Elements::div{Attributes::style = "display: none"}())
91  {
92  using namespace Elements;
93  using namespace Attributes;
94 
95  auto element = delocalizedElement.delocalizedElement_;
96 
97  return Elements::div{std::move(wrapperAttributes)}(
98  observe(*delocalizedElement.slotId_),
99  [element, slot, &observedId = *delocalizedElement.slotId_, alternative]() mutable {
100  return [element, slot, &observedId, alternative](
101  Dom::Element& wrapper, Renderer const& gen) -> std::shared_ptr<Dom::Element> {
102  if (element && slot == observedId.value())
103  {
104  wrapper.val().call<void>("appendChild", element->val());
105  return nil()(wrapper, gen);
106  }
107  else
108  {
109  if (alternative)
110  return alternative(wrapper, gen);
111  else
112  return nil()(wrapper, gen);
113  }
114  };
115  });
116  }
117 
119  char const* slot,
120  Delocalized<std::string>& delocalizedElement,
121  std::vector<Attribute> wrapperAttributes = {},
122  ElementRenderer alternative = Elements::div{Attributes::style = "display: none"}())
123  {
124  return delocalizedSlot<std::string>(
125  std::string{slot}, delocalizedElement, std::move(wrapperAttributes), std::move(alternative));
126  }
127 }
A delocalized element can switch positions in several slots.
Definition: delocalized.hpp:22
Delocalized(Nui::ElementRenderer renderer={})
Definition: delocalized.hpp:24
Delocalized & operator=(Delocalized const &)=delete
Delocalized(Delocalized const &)=delete
SlotId slot() const
Definition: delocalized.hpp:67
Delocalized(Delocalized &&)=default
void slot(SlotId slot)
Definition: delocalized.hpp:63
std::shared_ptr< Dom::Element > element()
Definition: delocalized.hpp:44
friend ElementRenderer delocalizedSlot(SlotIdB slot, Delocalized< SlotIdB > &delocalizedElement, std::vector< Attribute > wrapperAttributes, Nui::ElementRenderer alternative)
void element(Nui::ElementRenderer renderer)
Definition: delocalized.hpp:48
bool hasElement() const
Definition: delocalized.hpp:53
void initializeIfEmpty(Nui::ElementRenderer renderer)
Definition: delocalized.hpp:57
Delocalized & operator=(Delocalized &&)=default
static std::shared_ptr< Element > makeElement(HtmlElement const &element)
Definition: element.hpp:87
Definition: html_element.hpp:60
struct Nui::Attributes::style_ style
Definition: file_dialog.hpp:6
static auto nil()
Definition: nil.hpp:7
constexpr auto RegularHtmlElementBridge
Definition: html_element_bridges.hpp:8
std::function< std::shared_ptr< Dom::Element >(Dom::Element &, Renderer const &)> ElementRenderer
Definition: element_renderer.hpp:11
ElementRenderer delocalizedSlot(SlotId slot, Delocalized< SlotId > &delocalizedElement, std::vector< Attribute > wrapperAttributes={}, ElementRenderer alternative=Elements::div{Attributes::style="display: none"}())
Definition: delocalized.hpp:86