18 #include "Utilities.h" 36 std::string_view stateString;
53 return (value & semanticGesture.value) != 0;
58 result.value = value | other.value;
67 static constexpr
size_t AttachmentHint = 0;
68 static constexpr
size_t GridHint = 1;
70 enum class GridLayoutHint : int {
96 static constexpr
int RefIndexNone = std::numeric_limits<int>::max();
107 mHintClass = AttachmentHint;
108 mValueType =
static_cast<int>(attachment);
113 mHintClass = GridHint;
114 mValueType =
static_cast<int>(hint);
130 std::map<size_t, ValueMap> mHintsMap{};
149 mScreenRect = getScreenRectangle(containerPosition);
158 return Rectangle{containerPosition + mPos, mSize};
169 return containerPosition + mPadding.position();
179 mPreferredSize = size;
184 return mPreferredSize;
189 mPreferredPos = position;
194 return mPreferredPos;
205 mSize = screenRect.
size();
209 [[nodiscard]] constexpr
bool isVisible() const noexcept {
220 mHintsMap[hint.mHintClass][hint.mValueType] = hint.mValue;
229 if (
auto map = mHintsMap.find(LayoutHint::AttachmentHint); map != mHintsMap.end()) {
230 if (
auto att = (*map).second.find(static_cast<int>(attachment)); att != (*map).second.end()) {
231 return (*att).second;
242 std::optional<int>
getGridHint(LayoutHint::GridLayoutHint gridLayoutHint) {
243 if (
auto map = mHintsMap.find(LayoutHint::GridHint); map != mHintsMap.end()) {
244 if (
auto gridHint = (*map).second.find(static_cast<int>(gridLayoutHint)); gridHint != (*map).second.end()) {
245 return (*gridHint).second;
251 template<
size_t H
intClass>
252 [[nodiscard]] std::optional<const ValueMap> getHintMap()
const {
253 static_assert(HintClass == LayoutHint::AttachmentHint || HintClass == LayoutHint::GridHint,
254 "Supported maps are: LayoutHint::AttachmentHint, LayoutHint::GridHint.");
255 if (
auto map = mHintsMap.find(HintClass); map != mHintsMap.end()) {
256 return std::make_optional<const ValueMap>((*map).second);
276 ~
Screen()
override =
default;
278 static constexpr std::string_view
id =
"Screen";
279 std::string_view nodeId()
const noexcept
override {
287 void add(
const std::shared_ptr<Node> &node)
override {
288 if (
auto window = std::dynamic_pointer_cast<Window>(node); window)
289 Container::add(node);
291 throw NodeTypeError(
"A Screen may only contain Window objects.");
321 ~
Window()
override =
default;
323 static constexpr std::string_view
id =
"Window";
324 std::string_view nodeId()
const noexcept
override {
328 bool isModal()
const {
return mModalWindow; }
335 void add(
const std::shared_ptr<Node> &node)
override {
337 if (std::dynamic_pointer_cast<Manager>(node))
338 Container::add(node);
340 throw NodeTypeError(
"A Window may only contain one Manager object.");
342 throw NodeRangeError(
"A Window may only contain one Manager object.");
349 bool baseTextureNeeded(
const Position<int> &containerPosition) {
350 setScreenRectangle(containerPosition);
351 return !mBaseTexture || mBaseTexture.getSize() != mScreenRect.size();
371 std::shared_ptr<Widget> pointerWidget(
const Position<int>& position);
375 if (
auto screen = std::dynamic_pointer_cast<Screen>(container()))
382 if (
auto screen = std::dynamic_pointer_cast<Screen>(container()))
394 size_t mMaxContent{UnlimitedContent};
398 return Rectangle{visual->mPos, visual->mSize};
403 static constexpr
size_t UnlimitedContent = std::numeric_limits<size_t>::max();
406 using Itr = Container::iterator;
410 LayoutManager::Itr last) = 0;
416 template<
class Layout,
typename ... Args>
417 std::unique_ptr<Layout> makeLayout(Args ... args) {
418 static_assert(std::is_base_of_v<LayoutManager, Layout>,
"Layout must be derived from LayoutManager.");
419 return std::make_unique<Layout>(args ...);
432 LayoutManager::Itr last)
override;
478 KeyboardEventCallback mKeyboardEventCallback{};
483 ~
Widget()
override =
default;
493 static constexpr std::string_view
id =
"Widget";
494 std::string_view nodeId()
const noexcept
override {
528 if (
auto window = getWindow(); window) {
529 if (
auto screen = window->getScreen(); screen)
530 return screen->getApplication();
532 throw std::runtime_error(
"No path from Widget to Screen to Application.");
537 if (
auto window = getWindow(); window) {
538 if (
auto screen = window->getScreen(); screen)
539 return screen->getApplication();
541 throw std::runtime_error(
"No path from Widget to Screen to Application.");
549 auto c = container();
551 if (
auto window = std::dynamic_pointer_cast<Window>(c); window)
561 auto c = container();
563 if (
auto window = std::dynamic_pointer_cast<Window>(c); window)
576 if (mEnterEventCallback)
577 return mEnterEventCallback();
583 mEnterEventCallback = std::move(eventCallback);
591 if (mLeaveEventCallback)
592 return mLeaveEventCallback();
598 mLeaveEventCallback = std::move(eventCallback);
608 bool buttonEvent(
bool pressed, uint button, uint clicks,
bool passed);
612 mButtonEventCallback = std::move(buttonCallback);
625 bool mouseMotionEvent(
bool pressed, uint button,
const Position<int>& mousePos,
const Position<int>& relativePos,
bool passed);
629 mMouseMotionCallback = std::move(mouseMotionCallback);
638 bool mouseScrollEvent(
const Position<int>& deltaPos,
bool passed);
642 mMouseScrollCallback = std::move(scrollCallback);
649 bool keyboardShortcutEvent(uint32_t shortcutCode,
bool state, uint repeat);
653 mKeyboardShortcutCallback = std::move(keyboardShortcutCallback);
661 bool keyTextInputEvent(
const std::string& text);
665 mTextInputCallback = std::move(textInputCallback);
668 bool supportsKeyboardFocus()
const {
669 if (mTextInputCallback || mKeyboardFocusCallback || mKeyboardEventCallback)
679 bool keyboardFocusEvent(
bool hasFocus);
683 mKeyboardFocusCallback = std::move(keyboardFocusCallback);
686 bool keyboardEvent(
const SDL_KeyboardEvent &keyboardEvent);
688 void setKeyboardEvent(KeyboardEventCallback keyboardEventCallback) {
689 mKeyboardEventCallback = keyboardEventCallback;
700 std::unique_ptr<LayoutManager> mLayoutManager{};
715 static constexpr std::string_view
id =
"Manager";
716 std::string_view nodeId()
const noexcept
override {
724 void add(
const std::shared_ptr<Node> &node)
override {
725 if (mLayoutManager) {
727 if (std::dynamic_pointer_cast<Widget>(node) || std::dynamic_pointer_cast<
Manager>(node))
728 Container::add(node);
730 throw NodeTypeError(
"A Manager may only contain Manager or Widget objects.");
733 mLayoutManager->maximumContent()));
760 mLayoutManager = std::move(layoutManager);
788 template<
class WidgetClass,
typename ... Args>
789 inline std::shared_ptr<WidgetClass>
wdg(Args ... args) {
790 return std::make_shared<WidgetClass>(args ...);
802 template<
class W
idgetClass>
803 inline std::shared_ptr<WidgetClass>
operator >>(std::shared_ptr<WidgetClass> widget, std::shared_ptr<rose::Widget> &store) {
804 static_assert(std::is_base_of_v<rose::Widget,WidgetClass>,
"WidgetClass must be derived from rose::Widget." );
817 template<
class W
idgetClass>
818 inline std::shared_ptr<WidgetClass>
operator >>(std::shared_ptr<WidgetClass> widget, std::shared_ptr<WidgetClass> &store) {
819 static_assert(std::is_base_of_v<rose::Widget,WidgetClass>,
"WidgetClass must be derived from rose::Widget." );
837 template<
class W
idgetClass>
838 inline std::shared_ptr<rose::Manager> operator<<(std::shared_ptr<WidgetClass> widget,
const rose::Parent &) {
839 static_assert(std::is_base_of_v<rose::Widget, WidgetClass> || std::is_base_of_v<rose::Manager, WidgetClass>,
840 "WidgetClass must be derived from rose::Widget or rose::Manager.");
841 return std::dynamic_pointer_cast<
rose::Manager>(widget->container());
851 template<
class W
idgetClass>
852 inline std::shared_ptr<WidgetClass> operator<<(std::shared_ptr<WidgetClass> widget,
const rose::Size& size) {
853 static_assert(std::is_base_of_v<rose::Widget, WidgetClass> || std::is_base_of_v<rose::Manager, WidgetClass>,
854 "WidgetClass must be derived from rose::Widget or rose::Manager.");
855 widget->setSize(size);
866 template<
class W
idgetClass>
867 inline std::shared_ptr<WidgetClass> operator<<(std::shared_ptr<WidgetClass> widget,
const rose::Position<int>& position) {
868 static_assert(std::is_base_of_v<rose::Widget, WidgetClass> || std::is_base_of_v<rose::Manager, WidgetClass>,
869 "WidgetClass must be derived from rose::Widget or rose::Manager.");
870 widget->setPosition(position);
882 template<
class ContainerClass,
class W
idgetClass>
883 inline std::shared_ptr<WidgetClass> operator<<(std::shared_ptr<ContainerClass> container, std::shared_ptr<WidgetClass> widget) {
884 static_assert(std::is_base_of_v<rose::Visual, ContainerClass> && std::is_base_of_v<rose::Container, ContainerClass>,
885 "ContainerClass must be derived from both rose::Visual and rose::Container.");
886 static_assert(std::is_base_of_v<rose::Visual, WidgetClass> && std::is_base_of_v<rose::Node, WidgetClass>,
887 "WidgetClass must be derived from both rose::visual and rose::Node.");
888 container->add(widget);
899 template<
class W
idgetClass>
900 inline std::shared_ptr<WidgetClass> operator<<(std::shared_ptr<WidgetClass> widget, std::unique_ptr<rose::LayoutManager>&& layout) {
901 static_assert(std::is_base_of_v<rose::Manager,WidgetClass>,
"WidgetClass must be derived from rose::Manager.");
902 widget->setLayoutManager(std::move(layout));
913 template<
class W
idgetClass>
914 inline std::shared_ptr<WidgetClass> operator<<(std::shared_ptr<WidgetClass> widget,
const rose::Padding& padding) {
915 static_assert(std::is_base_of_v<rose::Visual, WidgetClass>,
"WidgetClass must be derived from rose::Visual.");
916 widget->setPadding(padding);
927 template<
class W
idgetClass>
928 inline std::shared_ptr<WidgetClass> operator<<(std::shared_ptr<WidgetClass> widget,
const rose::LayoutHint& hint) {
929 static_assert(std::is_base_of_v<rose::Visual, WidgetClass>,
"WidgetClass must be derived from rose::Visual.");
930 widget->setLayoutHint(hint);
Rectangle layoutPadding(const Rectangle &screenRect)
Pad the layout.
Definition: Visual.h:173
A pure virtual base class for layout managers.
Definition: Visual.h:392
Rectangle getScreenRectangle(const Position< int > &containerPosition) const
Get the rectangle occupied by the Visual.
Definition: Visual.h:157
Application & getApplication()
Get the Application object associated with the Screen.
Definition: Visual.h:301
A Widget which manages contained Widgets.
Definition: Visual.h:697
Definition: Application.h:169
std::unique_ptr< SDL_Window, WindowDestroy > Window
An SDL_Window unique pointer.
Definition: Renderer.h:57
std::string StringCompositor(Arg &&arg, Args &&... args)
Composite a pack of arguments that are streamable to a string.
Definition: Utilities.h:114
A container which holds the subordinate Node objects.
Definition: StructuredTypes.h:325
static Rectangle getScreenRectangle(std::shared_ptr< Visual > &visual)
Get the screen rectangle of a Visual.
Definition: Visual.h:397
void setScreenRectangle(const Rectangle &screenRect)
Set Screen Rectangle.
Definition: Visual.h:203
void setLayoutHint(const LayoutHint &hint)
Add a LayoutHint.
Definition: Visual.h:219
A Window is a visual abstraction of a number of related user interface objects.
Definition: Visual.h:315
std::function< bool(bool pressed, uint state, Position< int > mousePosition, Position< int > relativePosition)> MouseMotionCallback
Mouse motion callback.
Definition: Callbacks.h:61
void setLayoutManager(std::unique_ptr< LayoutManager > &&layoutManager)
Set the layout manager.
Definition: Visual.h:759
size_t maximumContent() const
Get the maximum content of the LayoutManager.
Definition: Visual.h:413
std::shared_ptr< WidgetClass > wdg(Args ... args)
Create a Widget.
Definition: Visual.h:789
Size getSize() const
Get the preferred size.
Definition: Visual.h:183
An abstraction of the available display screen.
Definition: Visual.h:271
std::function< bool()> EventCallback
Basic event callback with no argumetns.
Definition: Callbacks.h:37
std::function< bool(Position< int > deltaPos)> ScrollCallback
Mouse scroll wheel callback.
Definition: Callbacks.h:43
Position< int > getPosition() const
Get the preferred Position.
Definition: Visual.h:193
std::function< bool(bool pressed, uint button, uint clicks)> ButtonCallback
Mouse button callback.
Definition: Callbacks.h:51
void setScreenRectangle(const Position< int > &containerPosition)
Compute the screen rectangle from the Container screen Position.
Definition: Visual.h:148
std::function< void(bool hasFocus)> KeyboardFocusCallback
Keyboard focus callback.
Definition: Callbacks.h:102
Definitions to support callbacks.
Abstraction of space consumed around an object for space, borders, etc.
Definition: Types.h:454
Abstraction of SDL_Texture.
Definition: Texture.h:46
Context
Definition: GraphicsModel.h:76
Classes and functions used to implement structured data collections.
A type used to extract the parent from a Widget.
Definition: Visual.h:774
Bottom left corner of the board.
Definition: ConwayLife.h:32
void add(const std::shared_ptr< Node > &node) override
Add a Manager to the Window.
Definition: Visual.h:335
void add(const std::shared_ptr< Node > &node) override
Add a Node to the contents of the Manager.
Definition: Visual.h:724
Position< int > position() const noexcept
Get a Position from a Rectangle.
Definition: Types.h:346
std::map< int, int > ValueMap
The std::map type for each hint class.
Definition: Visual.h:129
The type of semantic gesture supported by a Widget.
Definition: Visual.h:43
void setVisible(bool visible) noexcept
Set visibility.
Definition: Visual.h:214
const Application & getApplication() const
Get the Application associated with a const Screen.
Definition: Visual.h:306
void add(const std::shared_ptr< Node > &node) override
Add a Window to the screen.
Definition: Visual.h:287
Top left corner of the board.
Definition: ConwayLife.h:31
std::optional< int > getAttachmentHint(LayoutHint::Attachment attachment)
Get an AttachmentHint value given a LayoutHint::Attachment.
Definition: Visual.h:228
std::function< void(uint32_t shortcutCode, bool state, uint repeat)> KeyboardShortcutCallback
Keyboard shortcut callback.
Definition: Callbacks.h:90
An exception to indicate runtime error during layout.
Definition: Visual.h:439
std::function< void(const std::string &text)> TextInputCallback
Text input callback.
Definition: Callbacks.h:96
constexpr bool isVisible() const noexcept
Check visibility.
Definition: Visual.h:209
std::shared_ptr< Screen > getScreen()
Get the Screen which supports the Window.
Definition: Visual.h:374
std::shared_ptr< Screen > getScreen() const
Get the Screen which support the const Window.
Definition: Visual.h:381
Position< int > drawPadding(const Position< int > &containerPosition)
Pad the drawing location.
Definition: Visual.h:168
A composite of a Position and a Size.
Definition: Types.h:307
The properties common to all visual objects on the screen.
Definition: Visual.h:125
void setPadding(const Padding &padding)
Set Padding.
Definition: Visual.h:198
Definition: StructuredTypes.h:21
std::unique_ptr< LayoutManager > & layoutManager()
Get the LayoutManager.
Definition: Visual.h:767
static constexpr size_t UnlimitedContent
The value for 'unlimited' managed objects.
Definition: Visual.h:403
A type to specify a state.
Definition: Visual.h:35
std::shared_ptr< WidgetClass > operator>>(std::shared_ptr< WidgetClass > widget, std::shared_ptr< rose::Widget > &store)
An extraction operator to store a Widget in a std::shared_ptr<Widget>.
Definition: Visual.h:803
Definition: StructuredTypes.h:28
A size in integer dimensions.
Definition: Types.h:230
ToDo: There is an issue that the initial scroll interaction is lost if the click/press lands on a Wid...
Definition: CelestialOverlay.cpp:13
A Simple layout manager.
Definition: Visual.h:426
void setSize(const Size &size)
Set preferred Size.
Definition: Visual.h:178
Attachment
Definition: Visual.h:76
void setPosition(const Position< int > &position)
Set preferred Position.
Definition: Visual.h:188
std::optional< int > getGridHint(LayoutHint::GridLayoutHint gridLayoutHint)
Get a GridLayoutHint value given a LayoutHint::GridLayoutHint.
Definition: Visual.h:242
SemanticGesture supportedSemanticGestures() const
Get supported SemanticGestures.
Definition: Visual.h:262
Size size() const noexcept
Get a Size from a Rectangle.
Definition: Types.h:351