26#ifndef TGUI_COMPONENTS_HPP
27#define TGUI_COMPONENTS_HPP
29#include <TGUI/Text.hpp>
30#include <TGUI/Sprite.hpp>
31#include <TGUI/Texture.hpp>
32#include <TGUI/Outline.hpp>
34#include <unordered_map>
42 class BackendRenderTarget;
51 enum class ComponentState : std::uint8_t
60 FocusedActiveHover = 7,
68 enum class AlignLayout
83 enum class PositionAlignment
99 class TGUI_API MessageBroker
103 static std::uint64_t createTopic();
105 static void destroyTopic(std::uint64_t topicId);
107 static std::uint64_t subscribe(std::uint64_t topicId, std::function<
void()> func);
109 static void unsubscribe(std::uint64_t callbackId);
111 static void sendEvent(std::uint64_t topicId);
114 static std::unordered_map<std::uint64_t, std::set<std::uint64_t>> m_topicIdToCallbackIds;
115 static std::unordered_map<std::uint64_t, std::uint64_t> m_callbackIdToTopicId;
116 static std::unordered_map<std::uint64_t, std::function<void()>> m_listeners;
119 static std::uint64_t m_lastId;
124 class TGUI_API StylePropertyBase
127 virtual ~StylePropertyBase() =
default;
132 template <
typename ValueType>
133 class TGUI_API StyleProperty :
public StylePropertyBase
139 m_messageTopicId{MessageBroker::createTopic()}
143 explicit StyleProperty(ValueType defaultValue) :
144 m_defaultValue {std::move(defaultValue)},
145 m_messageTopicId{MessageBroker::createTopic()}
149 StyleProperty(
const StyleProperty& other) :
150 m_defaultValue {other.m_defaultValue},
151 m_messageTopicId{MessageBroker::createTopic()},
152 m_globalValues {other.m_globalValues}
156 const std::uint64_t baseIndex = m_propertyData & 0xFFFFFFFFFFFF0000;
157 const std::uint64_t oldBaseIndex = other.m_propertyData & 0xFFFFFFFFFFFF0000;
158 const std::uint16_t oldStoredStates =
static_cast<std::uint16_t
>(other.m_propertyData & 0xFFFF);
160 std::uint16_t total = 0;
161 std::uint8_t bitIndex = 0;
162 while (total < oldStoredStates)
164 if (oldStoredStates & (1 << bitIndex))
166 m_globalValues[baseIndex + bitIndex] = m_globalValues[oldBaseIndex + bitIndex];
167 total +=
static_cast<std::uint16_t
>(1 << bitIndex);
172 m_propertyData = baseIndex | oldStoredStates;
175 StyleProperty(StyleProperty&& other) noexcept :
176 m_defaultValue {std::move(other.m_defaultValue)},
177 m_propertyData {std::move(other.m_propertyData)},
178 m_messageTopicId{std::move(other.m_messageTopicId)},
179 m_globalValues {std::move(other.m_globalValues)}
181 other.m_messageTopicId = 0;
184 ~StyleProperty()
override
186 if (m_messageTopicId)
187 MessageBroker::destroyTopic(m_messageTopicId);
191 StyleProperty& operator=(
const StyleProperty& other)
195 StyleProperty temp(other);
196 std::swap(m_defaultValue, temp.m_defaultValue);
197 std::swap(m_propertyData, temp.m_propertyData);
198 std::swap(m_messageTopicId, temp.m_messageTopicId);
199 std::swap(m_globalValues, temp.m_globalValues);
205 StyleProperty& operator=(StyleProperty&& other)
noexcept
209 m_defaultValue = std::move(other.m_defaultValue);
210 m_propertyData = std::move(other.m_propertyData);
211 m_messageTopicId = std::move(other.m_messageTopicId);
212 m_globalValues = std::move(other.m_globalValues);
214 other.m_messageTopicId = 0;
220 StyleProperty& operator=(
const ValueType& value)
223 setValue(value, ComponentState::Normal);
227 void setValue(
const ValueType& value, ComponentState state = ComponentState::Normal)
229 const std::uint64_t baseIndex = m_propertyData & 0xFFFFFFFFFFFF0000;
230 m_propertyData |=
static_cast<std::uint64_t
>(1) <<
static_cast<std::uint8_t
>(state);
231 m_globalValues[baseIndex +
static_cast<std::uint8_t
>(state)] = value;
233 MessageBroker::sendEvent(m_messageTopicId);
236 void unsetValue(ComponentState state)
238 const std::uint64_t baseIndex = m_propertyData & 0xFFFFFFFFFFFF0000;
239 m_propertyData &= ~(
static_cast<std::uint64_t
>(1) <<
static_cast<std::uint8_t
>(state));
240 m_globalValues.erase(baseIndex +
static_cast<std::uint8_t
>(state));
242 MessageBroker::sendEvent(m_messageTopicId);
248 MessageBroker::sendEvent(m_messageTopicId);
251 const ValueType& getValue(ComponentState state = ComponentState::Normal)
const
253 const std::uint64_t baseIndex = m_propertyData & 0xFFFFFFFFFFFF0000;
254 const std::uint16_t storedStates =
static_cast<std::uint16_t
>(m_propertyData & 0xFFFF);
257 if (storedStates == 0)
258 return m_defaultValue;
261 if (storedStates == 1)
262 return m_globalValues.at(baseIndex);
264 if (
static_cast<std::uint8_t
>(state) &
static_cast<std::uint8_t
>(ComponentState::Disabled))
266 if ((
static_cast<std::uint8_t
>(state) &
static_cast<std::uint8_t
>(ComponentState::Active)) && (storedStates & (1 <<
static_cast<std::uint8_t
>(ComponentState::DisabledActive))))
267 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::DisabledActive));
268 if (storedStates & (1 <<
static_cast<std::uint8_t
>(ComponentState::Disabled)))
269 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::Disabled));
272 if (
static_cast<std::uint8_t
>(state) &
static_cast<std::uint8_t
>(ComponentState::Active))
274 if (
static_cast<std::uint8_t
>(state) &
static_cast<std::uint8_t
>(ComponentState::Hover))
276 if ((
static_cast<std::uint8_t
>(state) &
static_cast<std::uint8_t
>(ComponentState::Focused)) && (storedStates & (1 <<
static_cast<std::uint8_t
>(ComponentState::FocusedActiveHover))))
277 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::FocusedActiveHover));
278 if (storedStates & (1 <<
static_cast<std::uint8_t
>(ComponentState::ActiveHover)))
279 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::ActiveHover));
282 if ((
static_cast<std::uint8_t
>(state) &
static_cast<std::uint8_t
>(ComponentState::Focused)) && (storedStates & (1 <<
static_cast<std::uint8_t
>(ComponentState::FocusedActive))))
283 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::FocusedActive));
284 if (storedStates & (1 <<
static_cast<std::uint8_t
>(ComponentState::Active)))
285 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::Active));
288 if (
static_cast<std::uint8_t
>(state) &
static_cast<std::uint8_t
>(ComponentState::Hover))
290 if ((
static_cast<std::uint8_t
>(state) &
static_cast<std::uint8_t
>(ComponentState::Focused)) && (storedStates & (1 <<
static_cast<std::uint8_t
>(ComponentState::FocusedHover))))
291 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::FocusedHover));
292 if (storedStates & (1 <<
static_cast<std::uint8_t
>(ComponentState::Hover)))
293 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::Hover));
296 if (
static_cast<std::uint8_t
>(state) &
static_cast<std::uint8_t
>(ComponentState::Focused))
298 if (storedStates & (1 <<
static_cast<std::uint8_t
>(ComponentState::Focused)))
299 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::Focused));
302 if (storedStates & 1)
306 return m_globalValues.at(baseIndex +
static_cast<std::uint8_t
>(ComponentState::Normal));
312 return m_defaultValue;
316 std::uint64_t connectCallback(std::function<
void()> func)
318 return MessageBroker::subscribe(m_messageTopicId, std::move(func));
321 void disconnectCallback(std::uint64_t
id)
323 return MessageBroker::unsubscribe(
id);
328 void unsetValueImpl()
330 const std::uint64_t baseIndex = m_propertyData & 0xFFFFFFFFFFFF0000;
331 const std::uint16_t storedStates =
static_cast<std::uint16_t
>(m_propertyData & 0xFFFF);
333 std::uint16_t total = 0;
334 std::uint8_t bitIndex = 0;
335 while (total < storedStates)
337 if (storedStates & (1 << bitIndex))
339 m_globalValues.erase(baseIndex + bitIndex);
340 total +=
static_cast<std::uint16_t
>(1 << bitIndex);
345 m_propertyData = baseIndex;
350 ValueType m_defaultValue;
354 std::uint64_t m_propertyData = 0;
357 std::uint64_t m_messageTopicId = 0;
367 std::unordered_map<std::uint64_t, ValueType> m_globalValues;
372 struct TGUI_API StylePropertyBackground
374 StyleProperty<Color> borderColor{Color::Black};
375 StyleProperty<Color> color{Color::White};
376 StyleProperty<Texture> texture;
377 StyleProperty<Outline> borders;
378 StyleProperty<Outline> padding;
380 float roundedBorderRadius = 0;
385 struct TGUI_API StylePropertyText
387 StyleProperty<Color> color{Color::Black};
388 StyleProperty<TextStyles> style;
393 class GroupComponent;
395 class TGUI_API Component
399 Component() =
default;
400 virtual ~Component() =
default;
402 Component(
const Component&);
403 Component& operator=(
const Component&);
405 Component(Component&&) =
default;
406 Component& operator=(Component&&) =
default;
408 void setPosition(Vector2f position);
410 Vector2f getPosition()
const;
412 Vector2f getSize()
const;
414 void setPositionAlignment(PositionAlignment alignment);
416 void setVisible(
bool visible);
418 bool isVisible()
const;
420 void setParent(GroupComponent* parent);
422 virtual void draw(BackendRenderTarget& target, RenderStates states)
const = 0;
424 virtual void updateLayout();
426 virtual std::shared_ptr<Component> clone()
const = 0;
430 friend void swap(Component& first, Component& second);
434 ComponentState m_state = ComponentState::Normal;
435 PositionAlignment m_positionAlignment = PositionAlignment::None;
438 bool m_visible =
true;
440 GroupComponent* m_parent =
nullptr;
443 class TGUI_API GroupComponent :
public Component
447 GroupComponent(
const GroupComponent&);
448 GroupComponent& operator=(
const GroupComponent&);
450 GroupComponent(GroupComponent&&) =
default;
451 GroupComponent& operator=(GroupComponent&&) =
default;
453 Vector2f getClientSize()
const;
455 void addComponent(
const std::shared_ptr<Component>& component);
457 const std::vector<std::shared_ptr<Component>>& getComponents()
const;
459 void draw(BackendRenderTarget& target, RenderStates states)
const override;
461 void updateLayout()
override;
463 std::shared_ptr<Component> clone()
const override;
465 friend void swap(GroupComponent& first, GroupComponent& second);
469 GroupComponent() =
default;
472 std::vector<std::shared_ptr<Component>> m_children;
473 Vector2f m_clientSize;
478 class TGUI_API BackgroundComponent :
public GroupComponent
482 BackgroundComponent(StylePropertyBackground* backgroundStyle);
484 ~BackgroundComponent()
override;
486 BackgroundComponent(
const BackgroundComponent& other, StylePropertyBackground* backgroundStyle =
nullptr);
487 BackgroundComponent& operator=(
const BackgroundComponent& other);
491 void setSize(Vector2f size);
493 void setBorders(
const Outline& border);
495 const Outline& getBorders()
const;
497 void setPadding(
const Outline& padding);
499 const Outline& getPadding()
const;
501 void setOpacity(
float opacity);
503 void setComponentState(ComponentState state);
505 bool isTransparentPixel(Vector2f pos,
bool transparentTexture)
const;
507 void draw(BackendRenderTarget& target, RenderStates states)
const override;
509 Vector2f getSizeWithoutBorders()
const;
511 void updateLayout()
override;
513 std::shared_ptr<Component> clone()
const override;
523 StylePropertyBackground* m_backgroundStyle;
525 ColorRect m_background{Color::White, {}};
526 Color m_borderColor = Color::Black;
531 std::uint64_t m_borderColorCallbackId = 0;
532 std::uint64_t m_backgroundColorCallbackId = 0;
533 std::uint64_t m_textureCallbackId = 0;
534 std::uint64_t m_bordersCallbackId = 0;
535 std::uint64_t m_paddingCallbackId = 0;
540 class TGUI_API TextComponent :
public Component
544 TextComponent(StylePropertyText* textStyle);
546 ~TextComponent()
override;
548 TextComponent(
const TextComponent& other, StylePropertyText* textStyle =
nullptr);
549 TextComponent& operator=(
const TextComponent& other);
553 void setString(
const String& caption);
555 const String& getString()
const;
557 void setCharacterSize(
unsigned int size);
559 unsigned int getCharacterSize()
const;
561 void setFont(
const Font& font);
563 Font getFont()
const;
565 void setOutlineColor(Color color);
567 Color getOutlineColor()
const;
569 void setOutlineThickness(
float thickness);
571 float getOutlineThickness()
const;
573 float getLineHeight()
const;
575 void setOpacity(
float opacity);
577 void updateLayout()
override;
579 void setComponentState(ComponentState state);
581 void draw(BackendRenderTarget& target, RenderStates states)
const override;
583 std::shared_ptr<Component> clone()
const override;
587 StylePropertyText* m_textStyle;
589 Color m_color = Color::Black;
590 TextStyles m_style = TextStyle::Regular;
592 std::uint64_t m_colorCallbackId = 0;
593 std::uint64_t m_styleCallbackId = 0;
598 class TGUI_API ImageComponent :
public Component
602 ImageComponent(StyleProperty<Texture>* textureStyle);
604 ~ImageComponent()
override;
606 ImageComponent(
const ImageComponent& other, StyleProperty<Texture>* textureStyle =
nullptr);
607 ImageComponent& operator=(
const ImageComponent& other);
611 void setSize(Vector2f size);
613 void setOpacity(
float opacity);
615 void setComponentState(ComponentState state);
617 bool isTransparentPixel(Vector2f pos,
bool transparentTexture)
const;
619 void draw(BackendRenderTarget& target, RenderStates states)
const override;
621 std::shared_ptr<Component> clone()
const override;
625 StyleProperty<Texture>* m_textureStyle;
628 std::uint64_t m_textureCallbackId = 0;
633 inline ComponentState getStateFromFlags(
bool hover,
bool active,
bool focused =
false,
bool enabled =
true)
638 return ComponentState::DisabledActive;
640 return ComponentState::Disabled;
647 return ComponentState::FocusedActiveHover;
649 return ComponentState::FocusedActive;
652 return ComponentState::FocusedHover;
654 return ComponentState::Focused;
659 return ComponentState::ActiveHover;
661 return ComponentState::Active;
664 return ComponentState::Hover;
666 return ComponentState::Normal;
671 inline void setOptionalPropertyValue(StyleProperty<Color>& property,
const Color& color, ComponentState state)
674 property.setValue(color, state);
676 property.unsetValue(state);
681 inline void setOptionalPropertyValue(StyleProperty<TextStyles>& property,
const TextStyles& style, ComponentState state)
684 property.setValue(style, state);
686 property.unsetValue(state);
691 inline void setOptionalPropertyValue(StyleProperty<Texture>& property,
const Texture& texture, ComponentState state)
693 if (texture.getData())
694 property.setValue(texture, state);
696 property.unsetValue(state);
Namespace that contains all TGUI functions and classes.
Definition: AbsoluteOrRelativeValue.hpp:36