Rewrote code for focusing widgets

0.8
Bruno Van de Velde 2018-03-22 19:45:25 +01:00
parent a14760aef0
commit 7461aff68e
50 changed files with 1296 additions and 1138 deletions

View File

@ -65,14 +65,22 @@ namespace tgui
Fade = 4
};
// Move constructor has to be explicitly declared since this class has a destructor
Animation() = default;
Animation(const Animation&) = default;
Animation(Animation&&) = default;
Animation& operator=(const Animation&) = default;
Animation& operator=(Animation&&) = default;
virtual ~Animation() = default;
Type getType() const;
virtual bool update(sf::Time elapsedTime) = 0;
virtual void finish();
protected:
Animation(Type type, Widget::Ptr widget, sf::Time duration, std::function<void()> finishedCallback);
protected:
Type m_type = Type::None;
Widget::Ptr m_widget;

View File

@ -202,44 +202,6 @@ namespace tgui
std::string getWidgetName(const Widget::ConstPtr& widget) const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focuses a widget
///
/// The previously focused widget will be unfocused.
///
/// @param widget The widget that has to be focused
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void focusWidget(const Widget::Ptr& widget);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focuses the next widget
///
/// The currently focused widget will be unfocused, even if it was the only widget.
/// When no widget was focused, the first widget in the container will be focused.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void focusNextWidget();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focuses the previous widget
///
/// The currently focused widget will be unfocused, even if it was the only widget.
/// When no widget was focused, the last widget in the container will be focused.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void focusPreviousWidget();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Unfocuses all the widgets
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void unfocusWidgets();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Unchecks all the radio buttons
///
@ -318,6 +280,33 @@ namespace tgui
void moveWidgetToBack(const Widget::Ptr& widget);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focuses the next widget in this container
/// @return Whether a new widget was focused
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool focusNextWidget();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focuses the previous widget in this container
/// @return Whether a new widget was focused
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool focusPreviousWidget();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Unfocus the widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void unfocus() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/// Called when one of the child widgets of this container gains focus.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void childWidgetFocused(const Widget::Ptr& child);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -358,11 +347,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseNoLongerDown() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetUnfocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
@ -405,42 +389,11 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// When this function is called then all the widgets receive the event (if there are widgets).
// The function returns true when the event is consumed and false when the event was ignored by all widgets.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool handleEvent(sf::Event& event);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Focuses the previous widget in the container. If the first widget was focused then all widgets will be unfocused and
// this function will return false.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool focusPrevWidgetInContainer();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Focuses the next widget in the container. If the last widget was focused then all widgets will be unfocused and
// this function will return false.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool focusNextWidgetInContainer();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// When the tab key is pressed then this function is called. The focus will move to the next widget (if there is one).
// This function will only work when tabKeyUsageEnabled is true.
// The function will return true when another widget was focused.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool tabKeyPressed();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// When pressing shift+tab then this function is called. The focus will move to the previous widget (if there is one).
// This function will only work when tabKeyUsageEnabled is true.
// The function will return true when another widget was focused.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool shiftTabKeyPressed();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Checks above which widget the mouse is standing.
// If there is no widget below the mouse then this function will return a null pointer.
@ -460,6 +413,12 @@ namespace tgui
std::size_t getFocusedWidgetIndex() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Try to focus the given child widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool tryFocusWidget(const tgui::Widget::Ptr &widget, bool reverseWidgetOrder);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected:
@ -472,6 +431,9 @@ namespace tgui
// Did we enter handleEvent directly or because we got a MouseReleased event?
bool m_handingMouseReleased = false;
// Does focusing the next widget always keep a widget from this container focused (e.g. in a ChildWindow)?
bool m_isolatedFocus = false;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
@ -507,6 +469,13 @@ namespace tgui
using Widget::setSize;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Unfocus the widget
/// The gui container can't be unfocused.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void unfocus() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the mouse position (which is relative to the parent widget) lies on top of the widget
///

View File

@ -87,24 +87,6 @@ namespace tgui
TGUI_API const Font& getInternalGlobalFont();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief While tab key usage is enabled (default), pressing tab will focus another widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TGUI_API void enableTabKeyUsage();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief When disabling the tab key usage, pressing tab will no longer focus another widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TGUI_API void disableTabKeyUsage();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the tab key usage is enabled (if so, pressing tab will focus another widget)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TGUI_API bool isTabKeyUsageEnabled();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the double-click time for the mouse
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -145,6 +145,24 @@ namespace tgui
bool handleEvent(sf::Event event);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief While tab key usage is enabled (default), pressing tab will focus another widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void enableTabKeyUsage();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief When disabling the tab key usage, pressing tab will no longer focus another widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void disableTabKeyUsage();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the tab key usage is enabled (if so, pressing tab will focus another widget)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isTabKeyUsageEnabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Draws all the widgets that were added to the gui
///
@ -290,42 +308,22 @@ namespace tgui
std::string getWidgetName(const Widget::Ptr& widget) const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focuses a widget
///
/// The previously focused widget will be unfocused.
///
/// @param widget The widget that has to be focused
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void focusWidget(const Widget::Ptr& widget);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focuses the next widget
///
/// The currently focused widget will be unfocused, even if it was the only widget.
/// When no widget was focused, the first widget in the container will be focused.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void focusNextWidget();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focuses the previous widget
///
/// The currently focused widget will be unfocused, even if it was the only widget.
/// When no widget was focused, the last widget in the container will be focused.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void focusPreviousWidget();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Unfocus all the widgets
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void unfocusWidgets();
void unfocusAllWidgets();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -423,6 +421,7 @@ namespace tgui
// The sfml render target to draw on
sf::RenderTarget* m_target;
bool m_windowFocused = true;
#if SFML_VERSION_MAJOR == 2 && SFML_VERSION_MINOR < 5
// Does m_target contains a sf::RenderWindow?
@ -439,6 +438,8 @@ namespace tgui
sf::View m_view;
bool m_TabKeyUsageEnabled = true;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};

View File

@ -130,6 +130,20 @@ namespace tgui
Color getTextColorDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text that is used when the button is focused (while not hovered)
/// @param color New text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColorFocused(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the text color that is used when the button is focused
/// @return text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getTextColorFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the background
///
@ -210,6 +224,22 @@ namespace tgui
Color getBackgroundColorDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the background that is used when the button is focused (while not hovered)
/// @param color New background color
///
/// Note that this color is ignored when you set an image as background.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBackgroundColorFocused(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the background color that is used when the button is focused
/// @return background color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getBackgroundColorFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the borders
///
@ -282,6 +312,20 @@ namespace tgui
Color getBorderColorDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the borders that is used when the button is focused (while not hovered)
/// @param color New border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBorderColorFocused(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the borders that is used when the button is focused
/// @return Border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getBorderColorFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Change the image that is displayed
///
@ -357,19 +401,15 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Change the image that is drawn on top of the button image when the button is focused
///
/// @brief Change the image that is drawn on top of the button image when the button is focused (while not hovered)
/// @param texture The new focus texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureFocused(const Texture& texture);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the image that is drawn on top of the button image when the button is focused
///
/// @return focused texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture& getTextureFocused() const;
@ -446,6 +486,20 @@ namespace tgui
TextStyle getTextStyleDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the text style that is used when the button is focused (while not hovered)
/// @param style New text style
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextStyleFocused(TextStyle style);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns text style used when the button is focused
/// @return Style of the text
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TextStyle getTextStyleFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};

View File

@ -175,6 +175,20 @@ namespace tgui
Color getTextColorDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the text color that will be used inside the edit box when the edit box is focused
/// @param textColor The new text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColorFocused(Color textColor);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the text color that will be used inside the edit box when the edit box is focused
/// @return Text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getTextColorFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the text color of the selected text that will be used inside the edit box
///
@ -289,6 +303,22 @@ namespace tgui
Color getBackgroundColorDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the background when the edit box is focused
/// @param color New background color
///
/// Note that this color is ignored when you set an image as background.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBackgroundColorFocused(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the background when the edit box is focused
/// @return Background color in disabled state
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getBackgroundColorFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the color that will be used inside the edit box for the blinking caret
///
@ -326,21 +356,17 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the color that will be used for the blinking caret when the edit box is disabled
///
/// @brief Sets the color that will be used for the blinking caret when the edit box is focused
/// @param caretColor The color of the blinking caret
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setCaretColorDisabled(Color caretColor);
void setCaretColorFocused(Color caretColor);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color that will be used for the blinking caret when the edit box is disabled
///
/// @brief Returns the color that will be used for the blinking caret when the edit box is focused
/// @return The color of the blinking caret
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getCaretColorDisabled() const;
Color getCaretColorFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -397,6 +423,20 @@ namespace tgui
Color getBorderColorDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the borders used when the edit box is focused
/// @param color New border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBorderColorFocused(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the borders used when the edit box is focused
/// @return border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getBorderColorFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the image that is displayed
///

View File

@ -353,6 +353,20 @@ namespace tgui
Color getBorderColorDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the borders that is used when the radio button is focused (while not hovered)
/// @param color New border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBorderColorFocused(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the borders that is used when the radio button is focused
/// @return Border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getBorderColorFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the border color used when the radio button is checked
///
@ -407,6 +421,20 @@ namespace tgui
Color getBorderColorCheckedDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the borders that is used when the radio button is checked and focused (while not hovered)
/// @param color New border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBorderColorCheckedFocused(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the borders that is used when the radio button is checked and focused
/// @return Border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getBorderColorCheckedFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color that is used to fill the radio button when it is checked
///
@ -584,24 +612,37 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the image that is displayed on top of the checkbox when it is focused
///
/// @brief Changes the image that is displayed on top of the checkbox when it is unchecked and focused
/// @param texture The new focused texture
///
/// This only has effect when the normal checked and unchecked images are also set.
/// Pass an empty texture to unset the image.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureFocused(const Texture& texture);
void setTextureUncheckedFocused(const Texture& texture);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the image that is displayed on top of the checkbox when it is focused
///
/// @brief Returns the image that is displayed on top of the checkbox when it is unchecked and focused
/// @return focused texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture& getTextureFocused() const;
Texture& getTextureUncheckedFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the image that is displayed on top of the checkbox when it is checked and focused
/// @param texture The new focused texture
///
/// This only has effect when the normal checked and unchecked images are also set.
/// Pass an empty texture to unset the image.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureCheckedFocused(const Texture& texture);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the image that is displayed on top of the checkbox when it is checked and focused
/// @return focused texture
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture& getTextureCheckedFocused() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -365,15 +365,13 @@ namespace tgui
///
/// The previously focused widget will be unfocused.
///
/// @warning This function only has an effect when the widget was already added to its parent (e.g. the Gui).
/// @warning This function only works properly when the widget was already added to its parent (e.g. the Gui).
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void focus();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Unfocus the widget
///
/// @warning This function only has an effect when the widget was already added to its parent (e.g. the Gui).
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void unfocus();
@ -501,6 +499,13 @@ namespace tgui
Widget::Ptr getToolTip() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the widget can gain focus
/// @return Can the widget be focused?
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual bool canGainFocus() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the widget is a container widget or not
/// @return Does the widget inherit from the Container class, giving it the ability to have child widgets?
@ -570,16 +575,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void mouseWheelScrolled(float delta, Vector2f pos);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void widgetFocused();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void widgetUnfocused();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -754,10 +749,10 @@ namespace tgui
SignalVector2f onPositionChange = {"PositionChanged"}; ///< The position of the widget changed. Optional parameter: new position
SignalVector2f onSizeChange = {"SizeChanged"}; ///< The size of the widget changed. Optional parameter: new size
Signal onFocus = {"Focused"}; ///< The widget was focused
Signal onUnfocus = {"Unfocused"}; ///< The widget was unfocused
Signal onMouseEnter = {"MouseEntered"}; ///< The mouse entered the widget
Signal onMouseLeave = {"MouseLeft"}; ///< The mouse left the widget
Signal onFocus = {"Focused"}; ///< The widget was focused
Signal onUnfocus = {"Unfocused"}; ///< The widget was unfocused
Signal onMouseEnter = {"MouseEntered"}; ///< The mouse entered the widget
Signal onMouseLeave = {"MouseLeft"}; ///< The mouse left the widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -790,12 +785,9 @@ namespace tgui
bool m_mouseHover = false;
bool m_mouseDown = false;
// Are you focused on the widget?
// Is the widget focused?
bool m_focused = false;
// Can the widget be focused?
bool m_allowFocus = false;
// Keep track of the elapsed time.
sf::Time m_animationTimeElapsed;
@ -833,7 +825,7 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
friend class Container; // Container changes widget properties of its child widgets
friend class Container; // Container accesses m_mouseDown, m_draggableWidget, save and load
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -172,11 +172,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void keyPressed(const sf::Event::KeyEvent& event) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetFocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Draw the widget to a render target
@ -302,10 +297,12 @@ namespace tgui
Color m_borderColorHoverCached;
Color m_borderColorDownCached;
Color m_borderColorDisabledCached;
Color m_borderColorFocusedCached;
Color m_backgroundColorCached;
Color m_backgroundColorHoverCached;
Color m_backgroundColorDownCached;
Color m_backgroundColorDisabledCached;
Color m_backgroundColorFocusedCached;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -165,6 +165,15 @@ namespace tgui
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the widget can gain focus
/// @return Can the widget be focused?
///
/// This function returns false for Canvas widgets.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool canGainFocus() const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected:

View File

@ -399,6 +399,22 @@ namespace tgui
const std::string& getInputValidator() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focus the widget
///
/// The previously focused widget will be unfocused.
///
/// @warning This function only works properly when the widget was already added to its parent (e.g. the Gui).
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void focus() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Unfocus the widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void unfocus() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -419,16 +435,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void textEntered(std::uint32_t Key) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetFocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetUnfocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Draw the widget to a render target
@ -519,6 +525,12 @@ namespace tgui
void updateSelection();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Update the color of the Text objects
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void updateTextColor();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This function is called every frame with the time passed since the last frame.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -608,12 +620,14 @@ namespace tgui
Color m_borderColorCached;
Color m_borderColorHoverCached;
Color m_borderColorDisabledCached;
Color m_borderColorFocusedCached;
Color m_backgroundColorCached;
Color m_backgroundColorHoverCached;
Color m_backgroundColorDisabledCached;
Color m_backgroundColorFocusedCached;
Color m_caretColorCached;
Color m_caretColorHoverCached;
Color m_caretColorDisabledCached;
Color m_caretColorFocusedCached;
Color m_selectedTextBackgroundColorCached;

View File

@ -263,11 +263,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseMoved(Vector2f pos) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetFocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Draw the widget to a render target

View File

@ -287,6 +287,15 @@ namespace tgui
void setParent(Container* parent) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the widget can gain focus
/// @return Can the widget be focused?
///
/// This function returns false for Label widgets.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool canGainFocus() const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -152,6 +152,15 @@ namespace tgui
bool isIgnoringMouseEvents() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the widget can gain focus
/// @return Can the widget be focused?
///
/// This function returns false for Picture widgets.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool canGainFocus() const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the mouse position (which is relative to the parent widget) lies on top of the widget
///

View File

@ -221,11 +221,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void keyPressed(const sf::Event::KeyEvent& event) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetFocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Draw the widget to a render target
@ -358,7 +353,8 @@ namespace tgui
Sprite m_spriteCheckedHover;
Sprite m_spriteUncheckedDisabled;
Sprite m_spriteCheckedDisabled;
Sprite m_spriteFocused;
Sprite m_spriteUncheckedFocused;
Sprite m_spriteCheckedFocused;
// Cached renderer properties
Borders m_bordersCached;
@ -370,9 +366,11 @@ namespace tgui
Color m_borderColorCached;
Color m_borderColorHoverCached;
Color m_borderColorDisabledCached;
Color m_borderColorFocusedCached;
Color m_borderColorCheckedCached;
Color m_borderColorCheckedHoverCached;
Color m_borderColorCheckedDisabledCached;
Color m_borderColorCheckedFocusedCached;
Color m_backgroundColorCached;
Color m_backgroundColorHoverCached;
Color m_backgroundColorDisabledCached;

View File

@ -255,11 +255,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseMoved(Vector2f pos) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetFocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -232,11 +232,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseWheelScrolled(float delta, Vector2f pos) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetFocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -200,11 +200,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseMoved(Vector2f pos) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetFocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Draw the widget to a render target

View File

@ -264,6 +264,22 @@ namespace tgui
std::size_t getLinesCount() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Focus the widget
///
/// The previously focused widget will be unfocused.
///
/// @warning This function only works properly when the widget was already added to its parent (e.g. the Gui).
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void focus() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Unfocus the widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void unfocus() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the mouse position (which is relative to the parent widget) lies on top of the widget
///
@ -312,16 +328,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseNoLongerDown() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetFocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void widgetUnfocused() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected:

View File

@ -48,14 +48,21 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MoveAnimation::MoveAnimation(Widget::Ptr widget, Vector2f start, Vector2f end, sf::Time duration, std::function<void()> finishedCallback)
Animation::Animation(Type type, Widget::Ptr widget, sf::Time duration, std::function<void()> finishedCallback) :
m_type {type},
m_widget {widget},
m_totalDuration {duration},
m_finishedCallback{finishedCallback}
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MoveAnimation::MoveAnimation(Widget::Ptr widget, Vector2f start, Vector2f end, sf::Time duration, std::function<void()> finishedCallback) :
Animation {Type::Move, widget, duration, finishedCallback},
m_startPos{start},
m_endPos {end}
{
m_type = Type::Move;
m_widget = widget;
m_startPos = start;
m_endPos = end;
m_totalDuration = duration;
m_finishedCallback = finishedCallback;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -83,14 +90,11 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ResizeAnimation::ResizeAnimation(Widget::Ptr widget, Vector2f start, Vector2f end, sf::Time duration, std::function<void()> finishedCallback)
ResizeAnimation::ResizeAnimation(Widget::Ptr widget, Vector2f start, Vector2f end, sf::Time duration, std::function<void()> finishedCallback) :
Animation {Type::Resize, widget, duration, finishedCallback},
m_startSize{start},
m_endSize {end}
{
m_type = Type::Resize;
m_widget = widget;
m_startSize = start;
m_endSize = end;
m_totalDuration = duration;
m_finishedCallback = finishedCallback;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -118,14 +122,11 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FadeAnimation::FadeAnimation(Widget::Ptr widget, float start, float end, sf::Time duration, std::function<void()> finishedCallback)
FadeAnimation::FadeAnimation(Widget::Ptr widget, float start, float end, sf::Time duration, std::function<void()> finishedCallback) :
Animation {Type::Fade, widget, duration, finishedCallback},
m_startOpacity{std::max(0.f, std::min(1.f, start))},
m_endOpacity {std::max(0.f, std::min(1.f, end))}
{
m_type = Type::Fade;
m_widget = widget;
m_startOpacity = std::max(0.f, std::min(1.f, start));
m_endOpacity = std::max(0.f, std::min(1.f, end));
m_totalDuration = duration;
m_finishedCallback = finishedCallback;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -31,12 +31,6 @@
#include <cassert>
#include <fstream>
#ifdef SFML_SYSTEM_WINDOWS
#include <direct.h> // _getcwd
#else
#include <unistd.h> // getcwd
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
@ -47,102 +41,6 @@ namespace tgui
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::string getWorkingDirectory()
{
const std::string resourcePath = getResourcePath();
std::string workingDirectory;
#ifdef SFML_SYSTEM_WINDOWS
if ((resourcePath[0] == '/') || (resourcePath[0] == '\\') || ((resourcePath.size() > 1) && (resourcePath[1] == ':')))
#else
if (resourcePath[0] == '/')
#endif
{
// The resource path is already an absolute path, we don't even need to find out the current working directory
workingDirectory = resourcePath;
}
else
{
// Get the current working directory (used for turning absolute into relative paths in saveWidget)
#ifdef SFML_SYSTEM_WINDOWS
char* buffer = _getcwd(nullptr, 0);
#else
char* buffer = getcwd(nullptr, 0);
#endif
if (buffer)
{
workingDirectory = buffer;
free(buffer);
if (!workingDirectory.empty() && (workingDirectory[workingDirectory.size() - 1] != '/') && (workingDirectory[workingDirectory.size() - 1] != '\\'))
workingDirectory.push_back('/');
workingDirectory += resourcePath;
}
}
return workingDirectory;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sf::String tryRemoveAbsolutePath(const sf::String& value, const std::string& workingDirectory)
{
if (!value.isEmpty() && (value != "null") && (value != "nullptr"))
{
if (value[0] != '"')
{
#ifdef SFML_SYSTEM_WINDOWS
if ((value[0] == '/') || (value[0] == '\\') || ((value.getSize() > 1) && (value[1] == ':')))
#else
if (value[0] == '/')
#endif
{
if ((value.getSize() > workingDirectory.size()) && (value.substring(0, workingDirectory.size()) == workingDirectory))
{
if ((value[workingDirectory.size()] != '/') && (value[workingDirectory.size()] != '\\'))
return value.substring(workingDirectory.size());
else
return value.substring(workingDirectory.size() + 1);
}
}
}
else // The filename is between quotes
{
if (value.getSize() <= 1)
return value;
#ifdef SFML_SYSTEM_WINDOWS
if ((value[1] == '/') || (value[1] == '\\') || ((value.getSize() > 2) && (value[2] == ':')))
#else
if (value[1] == '/')
#endif
{
if ((value.getSize() + 1 > workingDirectory.size()) && (value.substring(1, workingDirectory.size()) == workingDirectory))
return '"' + value.substring(workingDirectory.size() + 1);
}
}
}
return value;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void recursiveTryRemoveAbsolutePath(std::unique_ptr<DataIO::Node>& node, const std::string& workingDirectory)
{
for (auto& pair : node->propertyValuePairs)
{
if (((pair.first.size() >= 7) && (toLower(pair.first.substr(0, 7)) == "texture")) || (pair.first == "font"))
pair.second->value = tryRemoveAbsolutePath(pair.second->value, workingDirectory);
}
for (auto& child : node->children)
recursiveTryRemoveAbsolutePath(child, workingDirectory);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void getAllRenderers(std::map<RendererData*, std::vector<const Widget*>>& renderers, const Container* container)
{
for (const auto& child : container->getWidgets())
@ -160,7 +58,7 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<DataIO::Node> saveRenderer(RendererData* renderer, const std::string& name, const std::string& workingDirectory)
std::unique_ptr<DataIO::Node> saveRenderer(RendererData* renderer, const std::string& name)
{
auto node = make_unique<DataIO::Node>();
node->name = name;
@ -170,31 +68,20 @@ namespace tgui
if (pair.first == "font" && ObjectConverter{pair.second}.getString() == "null")
continue;
sf::String value = ObjectConverter{pair.second}.getString();
// Turn absolute paths (which were likely caused by loading from a theme) into relative paths if the first part of the path matches the current working directory
if (!workingDirectory.empty())
{
if ((pair.second.getType() == ObjectConverter::Type::Font) || (pair.second.getType() == ObjectConverter::Type::Texture))
value = tryRemoveAbsolutePath(value, workingDirectory);
}
if (pair.second.getType() == ObjectConverter::Type::RendererData)
{
std::stringstream ss{value};
std::stringstream ss{ObjectConverter{pair.second}.getString()};
auto rendererRootNode = DataIO::parse(ss);
// If there are braces around the renderer string, then the child node is the one we need
if (rendererRootNode->propertyValuePairs.empty() && (rendererRootNode->children.size() == 1))
rendererRootNode = std::move(rendererRootNode->children[0]);
recursiveTryRemoveAbsolutePath(rendererRootNode, workingDirectory);
rendererRootNode->name = pair.first;
node->children.push_back(std::move(rendererRootNode));
}
else
node->propertyValuePairs[pair.first] = make_unique<DataIO::ValueNode>(value);
node->propertyValuePairs[pair.first] = make_unique<DataIO::ValueNode>(ObjectConverter{pair.second}.getString());
}
return node;
@ -208,7 +95,6 @@ namespace tgui
Container::Container()
{
m_containerWidget = true;
m_allowFocus = true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -354,7 +240,10 @@ namespace tgui
}
if (widget == m_focusedWidget)
unfocusWidgets();
{
m_focusedWidget = nullptr;
widget->unfocus();
}
// Remove the widget
widget->setParent(nullptr);
@ -412,169 +301,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Container::focusWidget(const Widget::Ptr& widget)
{
// Loop all the widgets
for (std::size_t i = 0; i < m_widgets.size(); ++i)
{
// Search for the widget that has to be focused
if (m_widgets[i] == widget)
{
// Only continue when the widget wasn't already focused
if (widget != m_focusedWidget)
{
// Unfocus the currently focused widget
if (m_focusedWidget)
{
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
m_focusedWidget = nullptr;
}
// Focus the new widget
if (widget->isEnabled())
{
m_focusedWidget = widget;
widget->m_focused = true;
widget->widgetFocused();
}
}
break;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Container::focusNextWidget()
{
const std::size_t focusedWidgetIndex = getFocusedWidgetIndex();
// Loop all widgets behind the focused one
for (std::size_t i = focusedWidgetIndex; i < m_widgets.size(); ++i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i]->isVisible()) && (m_widgets[i]->isEnabled()))
{
if (m_focusedWidget)
{
// unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
}
// Focus on the new widget
m_focusedWidget = m_widgets[i];
m_widgets[i]->m_focused = true;
m_widgets[i]->widgetFocused();
return;
}
}
}
// None of the widgets behind the focused one could be focused, so loop the ones before it
if (m_focusedWidget)
{
for (std::size_t i = 0; i < focusedWidgetIndex - 1; ++i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i]->isVisible()) && (m_widgets[i]->isEnabled()))
{
// unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
// Focus on the new widget
m_focusedWidget = m_widgets[i];
m_widgets[i]->m_focused = true;
m_widgets[i]->widgetFocused();
return;
}
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Container::focusPreviousWidget()
{
const std::size_t focusedWidgetIndex = getFocusedWidgetIndex();
// Loop the widgets before the focused one
if (m_focusedWidget)
{
for (std::size_t i = focusedWidgetIndex - 1; i > 0; --i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i-1]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i-1]->isVisible()) && (m_widgets[i-1]->isEnabled()))
{
// unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
// Focus on the new widget
m_focusedWidget = m_widgets[i-1];
m_widgets[i-1]->m_focused = true;
m_widgets[i-1]->widgetFocused();
return;
}
}
}
}
// None of the widgets before the focused one could be focused, so loop all widgets behind the focused one
for (std::size_t i = m_widgets.size(); i > focusedWidgetIndex; --i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i-1]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i-1]->isVisible()) && (m_widgets[i-1]->isEnabled()))
{
if (m_focusedWidget)
{
// unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
}
// Focus on the new widget
m_focusedWidget = m_widgets[i-1];
m_widgets[i-1]->m_focused = true;
m_widgets[i-1]->widgetFocused();
return;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Container::unfocusWidgets()
{
if (m_focusedWidget)
{
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
m_focusedWidget = nullptr;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Container::uncheckRadioButtons()
{
// Loop through all radio buttons and uncheck them
@ -664,8 +390,6 @@ namespace tgui
void Container::saveWidgetsToStream(std::stringstream& stream) const
{
const std::string workingDirectory = getWorkingDirectory();
auto node = make_unique<DataIO::Node>();
std::map<RendererData*, std::vector<const Widget*>> renderers;
@ -678,14 +402,14 @@ namespace tgui
// The renderer can remain inside the widget if it is not shared, so provide the node to be included inside the widget
if (renderer.second.size() == 1)
{
renderersMap[renderer.second[0]] = {saveRenderer(renderer.first, "Renderer", workingDirectory), ""};
renderersMap[renderer.second[0]] = {saveRenderer(renderer.first, "Renderer"), ""};
continue;
}
// When the widget is shared, only provide the id instead of the node itself
++id;
const std::string idStr = to_string(id);
node->children.push_back(saveRenderer(renderer.first, "Renderer." + idStr, workingDirectory));
node->children.push_back(saveRenderer(renderer.first, "Renderer." + idStr));
for (const auto& child : renderer.second)
renderersMap[child] = std::make_pair(nullptr, idStr); // Did not compile with VS2015 Update 2 when using braces
}
@ -703,19 +427,17 @@ namespace tgui
// Loop through all widgets
for (std::size_t i = 0; i < m_widgets.size(); ++i)
{
// Check if the widget is found
if (m_widgets[i] == widget)
{
// Copy the widget
m_widgets.push_back(m_widgets[i]);
m_widgetNames.push_back(m_widgetNames[i]);
if (m_widgets[i] != widget)
continue;
// Remove the old widget
m_widgets.erase(m_widgets.begin() + i);
m_widgetNames.erase(m_widgetNames.begin() + i);
// Copy the widget
m_widgets.push_back(m_widgets[i]);
m_widgetNames.push_back(m_widgetNames[i]);
break;
}
// Remove the old widget
m_widgets.erase(m_widgets.begin() + i);
m_widgetNames.erase(m_widgetNames.begin() + i);
break;
}
}
@ -726,26 +448,134 @@ namespace tgui
// Loop through all widgets
for (std::size_t i = 0; i < m_widgets.size(); ++i)
{
// Check if the widget is found
if (m_widgets[i] == widget)
{
// Copy the widget
const Widget::Ptr obj = m_widgets[i];
const std::string name = m_widgetNames[i];
m_widgets.insert(m_widgets.begin(), obj);
m_widgetNames.insert(m_widgetNames.begin(), name);
if (m_widgets[i] != widget)
continue;
// Remove the old widget
m_widgets.erase(m_widgets.begin() + i + 1);
m_widgetNames.erase(m_widgetNames.begin() + i + 1);
// Copy the widget
const Widget::Ptr obj = m_widgets[i];
const std::string name = m_widgetNames[i];
m_widgets.insert(m_widgets.begin(), obj);
m_widgetNames.insert(m_widgetNames.begin(), name);
break;
}
// Remove the old widget
m_widgets.erase(m_widgets.begin() + i + 1);
m_widgetNames.erase(m_widgetNames.begin() + i + 1);
break;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Container::focusNextWidget()
{
// If the focused widget is a container then try to focus the next widget inside it
if (m_focusedWidget && m_focusedWidget->isContainer())
{
auto focusedContainer = std::static_pointer_cast<Container>(m_focusedWidget);
if (focusedContainer->focusNextWidget())
return true;
}
// Loop all widgets behind the focused one
const std::size_t focusedWidgetIndex = getFocusedWidgetIndex();
for (std::size_t i = focusedWidgetIndex; i < m_widgets.size(); ++i)
{
if (tryFocusWidget(m_widgets[i], false))
return true;
}
// If we are not an isolated focus group then the focus will be given to the group behind us
if (!m_isolatedFocus)
return false;
// None of the widgets behind the focused one could be focused, so loop the ones before it
if (!m_focusedWidget)
return false;
// Also include the focused widget since it may be a container that didn't have its first widget focused
for (std::size_t i = 0; i < focusedWidgetIndex; ++i)
{
if (tryFocusWidget(m_widgets[i], false))
return true;
}
// No other widget could be focused
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Container::focusPreviousWidget()
{
// If the focused widget is a container then try to focus the previous widget inside it
if (m_focusedWidget && m_focusedWidget->isContainer())
{
auto focusedContainer = std::static_pointer_cast<Container>(m_focusedWidget);
if (focusedContainer->focusPreviousWidget())
return true;
}
// Loop all widgets before the focused one
const std::size_t focusedWidgetIndex = getFocusedWidgetIndex();
if (focusedWidgetIndex > 0)
{
for (std::size_t i = focusedWidgetIndex - 1; i > 0; --i)
{
if (tryFocusWidget(m_widgets[i-1], true))
return true;
}
// If we are not an isolated focus group then the focus will be given to the group before us
if (!m_isolatedFocus)
return false;
}
// None of the widgets before the focused one could be focused, so loop the ones after it.
for (std::size_t i = m_widgets.size(); i > focusedWidgetIndex; --i)
{
if (tryFocusWidget(m_widgets[i-1], true))
return true;
}
// Also include the focused widget since it may be a container that didn't have its last widget focused.
if (focusedWidgetIndex > 0)
{
if (tryFocusWidget(m_widgets[focusedWidgetIndex-1], true))
return true;
}
// No other widget could be focused
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Container::unfocus()
{
if (m_focused && m_focusedWidget)
m_focusedWidget->unfocus();
Widget::unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Container::childWidgetFocused(const Widget::Ptr& child)
{
if (m_focusedWidget != child)
{
if (m_focusedWidget)
m_focusedWidget->unfocus();
m_focusedWidget = child;
}
if (!isFocused())
focus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Container::leftMousePressed(Vector2f pos)
{
sf::Event event;
@ -851,13 +681,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Container::widgetUnfocused()
{
unfocusWidgets();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Widget::Ptr Container::askToolTip(Vector2f mousePos)
{
if (mouseOnWidget(mousePos))
@ -1009,21 +832,16 @@ namespace tgui
// Check if the mouse is on top of a widget
Widget::Ptr widget = mouseOnWhichWidget(mousePos);
if (widget != nullptr)
if (widget)
{
// Focus the widget
focusWidget(widget);
// Unfocus the previously focused widget
if (m_focusedWidget && (m_focusedWidget != widget))
m_focusedWidget->unfocus();
if (widget->isContainer())
{
// If another widget was focused then unfocus it now
if (m_focusedWidget && (widget != m_focusedWidget))
{
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
m_focusedWidget = nullptr;
}
}
// Focus the widget unless it is a container, in which case it will get focused when the event is handled by the bottom widget
m_focusedWidget = widget;
if (!widget->isContainer())
widget->focus();
if (((event.type == sf::Event::MouseButtonPressed) && (event.mouseButton.button == sf::Mouse::Left))
|| ((event.type == sf::Event::TouchBegan) && (event.touch.finger == 0)))
@ -1037,8 +855,14 @@ namespace tgui
return true;
}
}
else // The mouse did not went down on a widget, so unfocus the focused widget
unfocusWidgets();
else // The mouse did not went down on a widget, so unfocus the focused child widget, but keep ourselves focused
{
if (m_focusedWidget)
m_focusedWidget->unfocus();
m_focusedWidget = nullptr;
focus();
}
return false;
}
@ -1080,7 +904,7 @@ namespace tgui
if (event.key.code != sf::Keyboard::Unknown)
{
// Check if there is a focused widget
if (m_focusedWidget)
if (m_focusedWidget && m_focusedWidget->isFocused())
{
#ifdef SFML_SYSTEM_ANDROID
// Map delete to backspace on android
@ -1097,21 +921,6 @@ namespace tgui
return false;
}
// Check if a key was released
else if (event.type == sf::Event::KeyReleased)
{
// Change the focus to another widget when the tab key was pressed
if (event.key.code == sf::Keyboard::Tab)
{
if (event.key.shift)
return shiftTabKeyPressed();
else
return tabKeyPressed();
}
else
return false;
}
// Also check if text was entered (not a special key)
else if (event.type == sf::Event::TextEntered)
{
@ -1119,7 +928,7 @@ namespace tgui
if ((event.text.unicode >= 32) && (event.text.unicode != 127))
{
// Tell the widget that the key was pressed
if (m_focusedWidget)
if (m_focusedWidget && m_focusedWidget->isFocused())
{
m_focusedWidget->textEntered(event.text.unicode);
return true;
@ -1149,261 +958,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Container::focusPrevWidgetInContainer()
{
// Don't do anything when the tab key usage is disabled
if (!isTabKeyUsageEnabled())
return false;
// If the focused widget is a container then try to focus the previous widget inside it
if (m_focusedWidget && m_focusedWidget->isContainer() && std::static_pointer_cast<Container>(m_focusedWidget)->focusPrevWidgetInContainer())
return true;
for (std::size_t i = getFocusedWidgetIndex() - 1; i > 0; ++i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i-1]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i-1]->isVisible()) && (m_widgets[i-1]->isEnabled()))
{
// Container widgets can only be focused it they contain focusable widgets
if ((!m_widgets[i-1]->isContainer()) || (std::static_pointer_cast<Container>(m_widgets[i-1])->focusPrevWidgetInContainer()))
{
if (m_focusedWidget)
{
// Unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
}
// Focus on the new widget
m_focusedWidget = m_widgets[i-1];
m_widgets[i-1]->m_focused = true;
m_widgets[i-1]->widgetFocused();
return true;
}
}
}
}
// We have the lowest id
unfocusWidgets();
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Container::focusNextWidgetInContainer()
{
// Don't do anything when the tab key usage is disabled
if (!isTabKeyUsageEnabled())
return false;
// If the focused widget is a container then try to focus the next widget inside it
if (m_focusedWidget && m_focusedWidget->isContainer() && std::static_pointer_cast<Container>(m_focusedWidget)->focusNextWidgetInContainer())
return true;
// Loop through all widgets
for (std::size_t i = getFocusedWidgetIndex(); i < m_widgets.size(); ++i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i]->isVisible()) && (m_widgets[i]->isEnabled()))
{
// Container widgets can only be focused it they contain focusable widgets
if ((!m_widgets[i]->isContainer()) || (std::static_pointer_cast<Container>(m_widgets[i])->focusNextWidgetInContainer()))
{
if (m_focusedWidget)
{
// Unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
}
// Focus on the new widget
m_focusedWidget = m_widgets[i];
m_widgets[i]->m_focused = true;
m_widgets[i]->widgetFocused();
return true;
}
}
}
}
// We have the highest id
unfocusWidgets();
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Container::tabKeyPressed()
{
// Don't do anything when the tab key usage is disabled
if (!isTabKeyUsageEnabled())
return false;
// Check if a container is focused
if (m_focusedWidget)
{
if (m_focusedWidget->isContainer())
{
// Focus the next widget in container
if (std::static_pointer_cast<Container>(m_focusedWidget)->focusNextWidgetInContainer())
return true;
}
}
const std::size_t focusedWidgetIndex = getFocusedWidgetIndex();
// Loop all widgets behind the focused one
for (std::size_t i = focusedWidgetIndex; i < m_widgets.size(); ++i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i]->isVisible()) && (m_widgets[i]->isEnabled()))
{
if (m_focusedWidget)
{
// unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
}
// Focus on the new widget
m_focusedWidget = m_widgets[i];
m_widgets[i]->m_focused = true;
m_widgets[i]->widgetFocused();
return true;
}
}
}
// None of the widgets behind the focused one could be focused, so loop the ones before it
if (m_focusedWidget)
{
for (std::size_t i = 0; i < focusedWidgetIndex-1; ++i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i]->isVisible()) && (m_widgets[i]->isEnabled()))
{
// unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
// Focus on the new widget
m_focusedWidget = m_widgets[i];
m_widgets[i]->m_focused = true;
m_widgets[i]->widgetFocused();
return true;
}
}
}
}
// If the currently focused container widget is the only widget to focus, then focus its next child widget
if (m_focusedWidget && (m_focusedWidget->isContainer()))
{
std::static_pointer_cast<Container>(m_focusedWidget)->tabKeyPressed();
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Container::shiftTabKeyPressed()
{
// Don't do anything when the tab key usage is disabled
if (!isTabKeyUsageEnabled())
return false;
const std::size_t focusedWidgetIndex = getFocusedWidgetIndex();
if (m_focusedWidget)
{
// Check if a container is focused
if (m_focusedWidget->isContainer())
{
// Focus the previous widget in container
if (std::static_pointer_cast<Container>(m_focusedWidget)->focusPrevWidgetInContainer())
return true;
}
// Loop all widgets before the focused one
for (std::size_t i = focusedWidgetIndex - 1; i > 0; --i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i-1]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i-1]->isVisible()) && (m_widgets[i-1]->isEnabled()))
{
if (m_focusedWidget)
{
// Unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
}
// Focus on the new widget
m_focusedWidget = m_widgets[i-1];
m_widgets[i-1]->m_focused = true;
m_widgets[i-1]->widgetFocused();
return true;
}
}
}
}
// None of the widgets before the focused one could be focused, so loop the ones behind it
for (std::size_t i = m_widgets.size(); i > focusedWidgetIndex; --i)
{
// If you are not allowed to focus the widget, then skip it
if (m_widgets[i-1]->m_allowFocus)
{
// Make sure that the widget is visible and enabled
if ((m_widgets[i-1]->isVisible()) && (m_widgets[i-1]->isEnabled()))
{
if (m_focusedWidget)
{
// Unfocus the current widget
m_focusedWidget->m_focused = false;
m_focusedWidget->widgetUnfocused();
}
// Focus on the new widget
m_focusedWidget = m_widgets[i-1];
m_widgets[i-1]->m_focused = true;
m_widgets[i-1]->widgetFocused();
return true;
}
}
}
// If the currently focused container widget is the only widget to focus, then focus its previous child widget
if (m_focusedWidget && (m_focusedWidget->isContainer()))
{
std::static_pointer_cast<Container>(m_focusedWidget)->shiftTabKeyPressed();
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Widget::Ptr Container::mouseOnWhichWidget(Vector2f mousePos)
{
Widget::Ptr widget = nullptr;
@ -1454,12 +1008,53 @@ namespace tgui
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Container::tryFocusWidget(const tgui::Widget::Ptr &widget, bool reverseWidgetOrder)
{
// If you are not allowed to focus the widget, then skip it
if (!widget->canGainFocus() || !widget->isVisible() || !widget->isEnabled())
return false;
if (widget->isContainer())
{
auto container = std::static_pointer_cast<Container>(widget);
// Also skip isolated containers (e.g. ChildWindow)
if (container->m_isolatedFocus)
return false;
// Try to focus the first focusable widget in the container
auto oldUnfocusedWidget = container->m_focusedWidget;
container->m_focusedWidget = nullptr;
bool childWidgetFocused = reverseWidgetOrder ? container->focusPreviousWidget() : container->focusNextWidget();
if (oldUnfocusedWidget && (oldUnfocusedWidget != container->m_focusedWidget))
oldUnfocusedWidget->unfocus();
if (!childWidgetFocused)
return false;
}
if (m_focusedWidget == widget)
return true;
if (m_focusedWidget)
m_focusedWidget->unfocus();
m_focusedWidget = widget;
m_focusedWidget->focus();
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
GuiContainer::GuiContainer()
{
m_type = "GuiContainer";
m_focused = true;
m_isolatedFocus = true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1470,6 +1065,14 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void GuiContainer::unfocus()
{
Container::unfocus();
m_focused = true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool GuiContainer::mouseOnWidget(Vector2f) const
{
return true;

View File

@ -39,7 +39,6 @@ namespace tgui
namespace
{
unsigned int globalTextSize = 13;
bool globalTabKeyUsageEnabled = true;
unsigned int globalDoubleClickTime = 500;
std::string globalResourcePath = "";
Font globalFont = nullptr;
@ -85,27 +84,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void enableTabKeyUsage()
{
globalTabKeyUsageEnabled = true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void disableTabKeyUsage()
{
globalTabKeyUsageEnabled = false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isTabKeyUsageEnabled()
{
return globalTabKeyUsageEnabled;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setDoubleClickTime(unsigned int milliseconds)
{
globalDoubleClickTime = milliseconds;

View File

@ -53,8 +53,6 @@ namespace tgui
m_accessToWindow(false)
#endif
{
m_container->m_focused = true;
init();
}
@ -65,8 +63,6 @@ namespace tgui
m_target (&window),
m_accessToWindow(true)
{
m_container->m_focused = true;
Clipboard::setWindowHandle(window.getSystemHandle());
setView(window.getDefaultView());
@ -85,8 +81,6 @@ namespace tgui
m_accessToWindow(false)
#endif
{
m_container->m_focused = true;
setView(target.getDefaultView());
init();
@ -224,32 +218,66 @@ namespace tgui
m_lastMousePos = mouseCoords;
}
// Handle tab key presses
else if (event.type == sf::Event::KeyPressed)
{
if (isTabKeyUsageEnabled() && (event.key.code == sf::Keyboard::Tab))
{
if (event.key.shift)
focusPreviousWidget();
else
focusNextWidget();
return true;
}
}
// Keep track of whether the window is focused or not
else if (event.type == sf::Event::LostFocus)
{
m_container->m_focused = false;
m_windowFocused = false;
}
else if (event.type == sf::Event::GainedFocus)
{
m_container->m_focused = true;
m_windowFocused = true;
#if SFML_VERSION_MAJOR == 2 && SFML_VERSION_MINOR < 5
if (m_accessToWindow)
Clipboard::setWindowHandle(static_cast<sf::RenderWindow*>(m_target)->getSystemHandle());
#endif
}
// Let the event manager handle the event
return m_container->handleEvent(event);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Gui::enableTabKeyUsage()
{
m_TabKeyUsageEnabled = true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Gui::disableTabKeyUsage()
{
m_TabKeyUsageEnabled = false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Gui::isTabKeyUsageEnabled() const
{
return m_TabKeyUsageEnabled;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Gui::draw()
{
assert(m_target != nullptr);
// Update the time
if (m_container->m_focused)
if (m_windowFocused)
updateTime(m_clock.restart());
else
m_clock.restart();
@ -344,13 +372,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Gui::focusWidget(const Widget::Ptr& widget)
{
m_container->focusWidget(widget);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Gui::focusNextWidget()
{
m_container->focusNextWidget();
@ -365,9 +386,9 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Gui::unfocusWidgets()
void Gui::unfocusAllWidgets()
{
m_container->unfocusWidgets();
m_container->unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -42,12 +42,16 @@ namespace tgui
{"bordercolor", Color{60, 60, 60}},
{"bordercolorhover", Color::Black},
{"bordercolordown", Color::Black},
{"bordercolorfocused", Color{30, 30, 180}},
{"bordercolordisabled", Color{125, 125, 125}},
{"textcolor", Color{60, 60, 60}},
{"textcolorhover", Color::Black},
{"textcolordown", Color::Black},
{"textcolordisabled", Color{125, 125, 125}},
{"backgroundcolor", Color{245, 245, 245}},
{"backgroundcolorhover", Color::White},
{"backgroundcolordown", Color{235, 235, 235}}})}, ///TODO: Define default disabled colors
{"backgroundcolordown", Color{235, 235, 235}},
{"backgroundcolordisabled", Color{230, 230, 230}}})},
{"chatbox", RendererData::create({{"borders", Borders{1}},
{"padding", Padding{0}},
{"bordercolor", Color::Black},
@ -55,6 +59,7 @@ namespace tgui
{"checkbox", RendererData::create({{"borders", Borders{1}},
{"bordercolor", Color{60, 60, 60}},
{"bordercolorhover", Color::Black},
{"bordercolorfocused", Color{30, 30, 180}},
{"textcolor", Color{60, 60, 60}},
{"textcolorhover", Color::Black},
{"backgroundcolor", Color{245, 245, 245}},
@ -147,6 +152,7 @@ namespace tgui
{"radiobutton", RendererData::create({{"borders", Borders{1}},
{"bordercolor", Color{60, 60, 60}},
{"bordercolorhover", Color::Black},
{"bordercolorfocused", Color{30, 30, 180}},
{"textcolor", Color{60, 60, 60}},
{"textcolorhover", Color::Black},
{"backgroundcolor", Color{245, 245, 245}},

View File

@ -28,7 +28,6 @@
#include <TGUI/Loading/DataIO.hpp>
#include <TGUI/Global.hpp>
#include <stdlib.h> // _fullpath/realpath
#include <cassert>
#include <sstream>
#include <fstream>
@ -59,8 +58,8 @@ namespace tgui
namespace
{
// Turns texture and font filenames into absolute paths
void injectAbsolutePath(std::set<const DataIO::Node*>& handledSections, const std::unique_ptr<DataIO::Node>& node, const std::string& path)
// Turns texture and font filenames into paths relative to the theme file
void injectThemePath(std::set<const DataIO::Node*>& handledSections, const std::unique_ptr<DataIO::Node>& node, const std::string& path)
{
for (const auto& pair : node->propertyValuePairs)
{
@ -99,7 +98,7 @@ namespace tgui
if (handledSections.find(child.get()) == handledSections.end())
{
handledSections.insert(child.get());
injectAbsolutePath(handledSections, child, path);
injectThemePath(handledSections, child, path);
}
}
}
@ -181,33 +180,11 @@ namespace tgui
if (root->propertyValuePairs.size() != 0)
throw Exception{"Unexpected result while loading theme file '" + filename + "'. Root property-value pair found."};
// Turn texture and font filenames into absolute paths
// Turn texture and font filenames into paths relative to the theme file
if (!resourcePath.empty())
{
#ifdef SFML_SYSTEM_WINDOWS
if ((resourcePath[0] != '/') && (resourcePath[0] != '\\') && ((resourcePath.size() <= 1) || (resourcePath[1] != ':')))
resourcePath = getResourcePath() + resourcePath;
char* buffer = _fullpath(nullptr, resourcePath.c_str(), 512);
#else
if (resourcePath[0] != '/')
resourcePath = getResourcePath() + resourcePath;
char* buffer = realpath(resourcePath.c_str(), nullptr);
#endif
std::string absoluteResourcePath;
if (buffer != nullptr)
{
absoluteResourcePath = buffer;
free(buffer);
if (!absoluteResourcePath.empty() && (absoluteResourcePath[absoluteResourcePath.length()-1] != '/'))
absoluteResourcePath.push_back('/');
}
std::set<const DataIO::Node*> handledSections;
injectAbsolutePath(handledSections, root, absoluteResourcePath);
injectThemePath(handledSections, root, resourcePath);
}
// Get a list of section names and map them to their nodes (needed for resolving references)

View File

@ -36,25 +36,29 @@ namespace tgui
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, TextColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, TextColorDown, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, TextColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, TextColorFocused, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BackgroundColor, Color::White)
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BackgroundColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BackgroundColorDown, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BackgroundColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BackgroundColorFocused, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BorderColor, Color::Black)
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BorderColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BorderColorDown, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BorderColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(ButtonRenderer, BorderColorFocused, {})
TGUI_RENDERER_PROPERTY_TEXTURE(ButtonRenderer, Texture)
TGUI_RENDERER_PROPERTY_TEXTURE(ButtonRenderer, TextureHover)
TGUI_RENDERER_PROPERTY_TEXTURE(ButtonRenderer, TextureDown)
TGUI_RENDERER_PROPERTY_TEXTURE(ButtonRenderer, TextureDisabled)
TGUI_RENDERER_PROPERTY_TEXTURE(ButtonRenderer, TextureFocused) /// TODO
TGUI_RENDERER_PROPERTY_TEXTURE(ButtonRenderer, TextureFocused)
TGUI_RENDERER_PROPERTY_TEXT_STYLE(ButtonRenderer, TextStyle, sf::Text::Regular)
TGUI_RENDERER_PROPERTY_TEXT_STYLE(ButtonRenderer, TextStyleHover, {})
TGUI_RENDERER_PROPERTY_TEXT_STYLE(ButtonRenderer, TextStyleDown, {})
TGUI_RENDERER_PROPERTY_TEXT_STYLE(ButtonRenderer, TextStyleDisabled, {})
TGUI_RENDERER_PROPERTY_TEXT_STYLE(ButtonRenderer, TextStyleFocused, {})
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -37,18 +37,21 @@ namespace tgui
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, TextColor, Color::Black)
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, TextColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, TextColorFocused, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, SelectedTextColor, Color::White)
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, SelectedTextBackgroundColor, Color(0, 110, 255))
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, DefaultTextColor, Color(160, 160, 160))
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, BackgroundColor, Color::White)
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, BackgroundColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, BackgroundColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, BackgroundColorFocused, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, CaretColor, Color::Black)
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, CaretColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, CaretColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, CaretColorFocused, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, BorderColor, Color::Black)
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, BorderColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, BorderColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(EditBoxRenderer, BorderColorFocused, {})
TGUI_RENDERER_PROPERTY_TEXTURE(EditBoxRenderer, Texture)
TGUI_RENDERER_PROPERTY_TEXTURE(EditBoxRenderer, TextureHover)

View File

@ -49,9 +49,11 @@ namespace tgui
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, BorderColor, Color::Black)
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, BorderColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, BorderColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, BorderColorFocused, {})
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, BorderColorChecked, {})
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, BorderColorCheckedHover, {})
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, BorderColorCheckedDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, BorderColorCheckedFocused, {})
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, CheckColor, Color::Black)
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, CheckColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(RadioButtonRenderer, CheckColorDisabled, {})
@ -59,10 +61,11 @@ namespace tgui
TGUI_RENDERER_PROPERTY_TEXTURE(RadioButtonRenderer, TextureUnchecked)
TGUI_RENDERER_PROPERTY_TEXTURE(RadioButtonRenderer, TextureUncheckedHover)
TGUI_RENDERER_PROPERTY_TEXTURE(RadioButtonRenderer, TextureUncheckedDisabled)
TGUI_RENDERER_PROPERTY_TEXTURE(RadioButtonRenderer, TextureUncheckedFocused)
TGUI_RENDERER_PROPERTY_TEXTURE(RadioButtonRenderer, TextureChecked)
TGUI_RENDERER_PROPERTY_TEXTURE(RadioButtonRenderer, TextureCheckedHover)
TGUI_RENDERER_PROPERTY_TEXTURE(RadioButtonRenderer, TextureCheckedDisabled)
TGUI_RENDERER_PROPERTY_TEXTURE(RadioButtonRenderer, TextureFocused) /// TODO
TGUI_RENDERER_PROPERTY_TEXTURE(RadioButtonRenderer, TextureCheckedFocused)
TGUI_RENDERER_PROPERTY_TEXT_STYLE(RadioButtonRenderer, TextStyle, sf::Text::Regular)
TGUI_RENDERER_PROPERTY_TEXT_STYLE(RadioButtonRenderer, TextStyleChecked, {})

View File

@ -95,7 +95,6 @@ namespace tgui
m_enabled {other.m_enabled},
m_visible {other.m_visible},
m_parent {nullptr},
m_allowFocus {other.m_allowFocus},
m_draggableWidget {other.m_draggableWidget},
m_containerWidget {other.m_containerWidget},
m_toolTip {other.m_toolTip ? other.m_toolTip->clone() : nullptr},
@ -134,7 +133,6 @@ namespace tgui
m_mouseHover {std::move(other.m_mouseHover)},
m_mouseDown {std::move(other.m_mouseDown)},
m_focused {std::move(other.m_focused)},
m_allowFocus {std::move(other.m_allowFocus)},
m_animationTimeElapsed {std::move(other.m_animationTimeElapsed)},
m_draggableWidget {std::move(other.m_draggableWidget)},
m_containerWidget {std::move(other.m_containerWidget)},
@ -184,7 +182,6 @@ namespace tgui
m_mouseHover = false;
m_mouseDown = false;
m_focused = false;
m_allowFocus = other.m_allowFocus;
m_animationTimeElapsed = {};
m_draggableWidget = other.m_draggableWidget;
m_containerWidget = other.m_containerWidget;
@ -235,7 +232,6 @@ namespace tgui
m_mouseDown = std::move(other.m_mouseDown);
m_focused = std::move(other.m_focused);
m_animationTimeElapsed = std::move(other.m_animationTimeElapsed);
m_allowFocus = std::move(other.m_allowFocus);
m_draggableWidget = std::move(other.m_draggableWidget);
m_containerWidget = std::move(other.m_containerWidget);
m_toolTip = std::move(other.m_toolTip);
@ -578,16 +574,25 @@ namespace tgui
void Widget::focus()
{
if (m_parent)
m_parent->focusWidget(shared_from_this());
if (!m_focused && canGainFocus())
{
m_focused = true;
onFocus.emit(this);
if (m_parent)
m_parent->childWidgetFocused(shared_from_this());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Widget::unfocus()
{
if (m_focused && m_parent)
m_parent->unfocusWidgets();
if (m_focused)
{
m_focused = false;
onUnfocus.emit(this);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -659,6 +664,13 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Widget::canGainFocus() const
{
return m_enabled && m_visible;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Widget::isContainer() const
{
return m_containerWidget;
@ -744,24 +756,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Widget::widgetFocused()
{
onFocus.emit(this);
// Make sure the parent is also focused
if (m_parent)
m_parent->focus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Widget::widgetUnfocused()
{
onUnfocus.emit(this);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Widget::mouseNoLongerOnWidget()
{
if (m_mouseHover)

View File

@ -90,8 +90,6 @@ namespace tgui
{
Group::add(widget, widgetName);
unfocusWidgets();
m_widgets.pop_back();
m_widgetNames.pop_back();

View File

@ -231,17 +231,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Button::widgetFocused()
{
// We can't be focused when we don't have a focus image
if (m_spriteFocused.getTexture().getData())
Widget::widgetFocused();
else
unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Button::mouseEnteredWidget()
{
Widget::mouseEnteredWidget();
@ -275,8 +264,8 @@ namespace tgui
m_bordersCached = getSharedRenderer()->getBorders();
updateSize();
}
else if ((property == "textcolor") || (property == "textcolorhover") || (property == "textcolordown") || (property == "textcolordisabled")
|| (property == "textstyle") || (property == "textstylehover") || (property == "textstyledown") || (property == "textstyledisabled"))
else if ((property == "textcolor") || (property == "textcolorhover") || (property == "textcolordown") || (property == "textcolordisabled") || (property == "textcolorfocused")
|| (property == "textstyle") || (property == "textstylehover") || (property == "textstyledown") || (property == "textstyledisabled") || (property == "textstylefocused"))
{
updateTextColorAndStyle();
}
@ -299,7 +288,6 @@ namespace tgui
else if (property == "texturefocused")
{
m_spriteFocused.setTexture(getSharedRenderer()->getTextureFocused());
m_allowFocus = m_spriteFocused.isSet();
}
else if (property == "bordercolor")
{
@ -317,6 +305,10 @@ namespace tgui
{
m_borderColorDisabledCached = getSharedRenderer()->getBorderColorDisabled();
}
else if (property == "bordercolorfocused")
{
m_borderColorFocusedCached = getSharedRenderer()->getBorderColorFocused();
}
else if (property == "backgroundcolor")
{
m_backgroundColorCached = getSharedRenderer()->getBackgroundColor();
@ -333,6 +325,10 @@ namespace tgui
{
m_backgroundColorDisabledCached = getSharedRenderer()->getBackgroundColorDisabled();
}
else if (property == "backgroundcolorfocused")
{
m_backgroundColorFocusedCached = getSharedRenderer()->getBackgroundColorFocused();
}
else if (property == "opacity")
{
Widget::rendererChanged(property);
@ -400,6 +396,8 @@ namespace tgui
return m_backgroundColorDownCached;
else if (m_mouseHover && m_backgroundColorHoverCached.isSet())
return m_backgroundColorHoverCached;
else if (m_focused && m_backgroundColorFocusedCached.isSet())
return m_backgroundColorFocusedCached;
else
return m_backgroundColorCached;
}
@ -414,6 +412,8 @@ namespace tgui
return m_borderColorDownCached;
else if (m_mouseHover && m_borderColorHoverCached.isSet())
return m_borderColorHoverCached;
else if (m_focused && m_borderColorFocusedCached.isSet())
return m_borderColorFocusedCached;
else
return m_borderColorCached;
}
@ -428,6 +428,8 @@ namespace tgui
m_text.setStyle(getSharedRenderer()->getTextStyleDown());
else if (m_mouseHover && getSharedRenderer()->getTextStyleHover().isSet())
m_text.setStyle(getSharedRenderer()->getTextStyleHover());
else if (m_focused && getSharedRenderer()->getTextStyleFocused().isSet())
m_text.setStyle(getSharedRenderer()->getTextStyleFocused());
else
m_text.setStyle(getSharedRenderer()->getTextStyle());
@ -437,6 +439,8 @@ namespace tgui
m_text.setColor(getSharedRenderer()->getTextColorDown());
else if (m_mouseHover && getSharedRenderer()->getTextColorHover().isSet())
m_text.setColor(getSharedRenderer()->getTextColorHover());
else if (m_focused && getSharedRenderer()->getTextColorFocused().isSet())
m_text.setColor(getSharedRenderer()->getTextColorFocused());
else
m_text.setColor(getSharedRenderer()->getTextColor());
}
@ -484,21 +488,14 @@ namespace tgui
{
if (!m_enabled && m_spriteDisabled.isSet())
m_spriteDisabled.draw(target, states);
else if (m_mouseHover)
{
if (m_mouseDown && m_spriteDown.isSet())
m_spriteDown.draw(target, states);
else if (m_spriteHover.isSet())
m_spriteHover.draw(target, states);
else
m_sprite.draw(target, states);
}
else if (m_mouseHover && m_mouseDown && m_spriteDown.isSet())
m_spriteDown.draw(target, states);
else if (m_mouseHover && m_spriteHover.isSet())
m_spriteHover.draw(target, states);
else if (m_focused && m_spriteFocused.isSet())
m_spriteFocused.draw(target, states);
else
m_sprite.draw(target, states);
// When the edit box is focused then draw an extra image
if (m_focused && m_spriteFocused.isSet())
m_spriteFocused.draw(target, states);
}
else // There is no background texture
{

View File

@ -163,6 +163,13 @@ namespace tgui
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Canvas::canGainFocus() const
{
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -187,7 +187,8 @@ namespace tgui
m_spriteUncheckedDisabled.setSize(m_spriteUnchecked.getSize());
m_spriteCheckedDisabled.setSize(m_spriteChecked.getSize());
m_spriteFocused.setSize(m_spriteUnchecked.getSize());
m_spriteUncheckedFocused.setSize(m_spriteUnchecked.getSize());
m_spriteCheckedFocused.setSize(m_spriteChecked.getSize());
}
}
@ -211,6 +212,8 @@ namespace tgui
checkedSprite = &m_spriteCheckedDisabled;
else if (m_mouseHover && m_spriteCheckedHover.isSet())
checkedSprite = &m_spriteCheckedHover;
else if (m_focused && m_spriteCheckedFocused.isSet())
checkedSprite = &m_spriteCheckedFocused;
else
checkedSprite = &m_spriteChecked;
@ -232,13 +235,11 @@ namespace tgui
m_spriteUncheckedDisabled.draw(target, states);
else if (m_mouseHover && m_spriteUncheckedHover.isSet())
m_spriteUncheckedHover.draw(target, states);
else if (m_focused && m_spriteUncheckedFocused.isSet())
m_spriteUncheckedFocused.draw(target, states);
else
m_spriteUnchecked.draw(target, states);
}
// When the radio button is focused then draw an extra image
if (m_focused && m_spriteFocused.isSet())
m_spriteFocused.draw(target, states);
}
else // There are no images
{

View File

@ -51,6 +51,7 @@ namespace tgui
ChildWindow::ChildWindow(const sf::String& title, unsigned int titleButtons)
{
m_type = "ChildWindow";
m_isolatedFocus = true;
m_titleText.setFont(m_fontCached);
m_renderer = aurora::makeCopied<ChildWindowRenderer>();

View File

@ -55,7 +55,6 @@ namespace tgui
m_defaultText.setFont(m_fontCached);
m_draggableWidget = true;
m_allowFocus = true;
m_renderer = aurora::makeCopied<EditBoxRenderer>();
setRenderer(Theme::getDefault()->getRendererNoThrow(m_type));
@ -140,9 +139,7 @@ namespace tgui
void EditBox::enable()
{
Widget::enable();
m_textBeforeSelection.setColor(getSharedRenderer()->getTextColor());
m_textAfterSelection.setColor(getSharedRenderer()->getTextColor());
updateTextColor();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -150,12 +147,7 @@ namespace tgui
void EditBox::disable()
{
Widget::disable();
if (getSharedRenderer()->getTextColorDisabled().isSet())
{
m_textBeforeSelection.setColor(getSharedRenderer()->getTextColorDisabled());
m_textAfterSelection.setColor(getSharedRenderer()->getTextColorDisabled());
}
updateTextColor();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -462,6 +454,35 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EditBox::focus()
{
Widget::focus();
m_caretVisible = true;
m_animationTimeElapsed = {};
#if defined (SFML_SYSTEM_ANDROID) || defined (SFML_SYSTEM_IOS)
sf::Keyboard::setVirtualKeyboardVisible(true);
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EditBox::unfocus()
{
// If there is a selection then undo it now
if (m_selChars)
setCaretPosition(m_selEnd);
#if defined (SFML_SYSTEM_ANDROID) || defined (SFML_SYSTEM_IOS)
sf::Keyboard::setVirtualKeyboardVisible(false);
#endif
Widget::unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EditBox::leftMousePressed(Vector2f pos)
{
pos -= getPosition();
@ -922,35 +943,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EditBox::widgetFocused()
{
#if defined (SFML_SYSTEM_ANDROID) || defined (SFML_SYSTEM_IOS)
sf::Keyboard::setVirtualKeyboardVisible(true);
#endif
Widget::widgetFocused();
m_caretVisible = true;
m_animationTimeElapsed = {};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EditBox::widgetUnfocused()
{
// If there is a selection then undo it now
if (m_selChars)
setCaretPosition(m_selEnd);
#if defined (SFML_SYSTEM_ANDROID) || defined (SFML_SYSTEM_IOS)
sf::Keyboard::setVirtualKeyboardVisible(false);
#endif
Widget::widgetUnfocused();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Signal& EditBox::getSignal(std::string signalName)
{
if (signalName == toLower(onTextChange.getName()))
@ -984,18 +976,9 @@ namespace tgui
m_caret.setPosition({m_caret.getPosition().x + ((m_caret.getSize().x - getSharedRenderer()->getCaretWidth()) / 2.0f), m_caret.getPosition().y});
m_caret.setSize({getSharedRenderer()->getCaretWidth(), getInnerSize().y - m_paddingCached.getBottom() - m_paddingCached.getTop()});
}
else if ((property == "textcolor") || (property == "textcolordisabled"))
else if ((property == "textcolor") || (property == "textcolordisabled") || (property == "textcolorfocused"))
{
if (m_enabled || !getSharedRenderer()->getTextColorDisabled().isSet())
{
m_textBeforeSelection.setColor(getSharedRenderer()->getTextColor());
m_textAfterSelection.setColor(getSharedRenderer()->getTextColor());
}
else
{
m_textBeforeSelection.setColor(getSharedRenderer()->getTextColorDisabled());
m_textAfterSelection.setColor(getSharedRenderer()->getTextColorDisabled());
}
updateTextColor();
}
else if (property == "selectedtextcolor")
{
@ -1020,7 +1003,6 @@ namespace tgui
else if (property == "texturefocused")
{
m_spriteFocused.setTexture(getSharedRenderer()->getTextureFocused());
m_allowFocus = m_spriteFocused.isSet();
}
else if (property == "textstyle")
{
@ -1046,6 +1028,10 @@ namespace tgui
{
m_borderColorDisabledCached = getSharedRenderer()->getBorderColorDisabled();
}
else if (property == "bordercolorfocused")
{
m_borderColorFocusedCached = getSharedRenderer()->getBorderColorFocused();
}
else if (property == "backgroundcolor")
{
m_backgroundColorCached = getSharedRenderer()->getBackgroundColor();
@ -1058,6 +1044,10 @@ namespace tgui
{
m_backgroundColorDisabledCached = getSharedRenderer()->getBackgroundColorDisabled();
}
else if (property == "backgroundcolorfocused")
{
m_backgroundColorFocusedCached = getSharedRenderer()->getBackgroundColorFocused();
}
else if (property == "caretcolor")
{
m_caretColorCached = getSharedRenderer()->getCaretColor();
@ -1066,9 +1056,9 @@ namespace tgui
{
m_caretColorHoverCached = getSharedRenderer()->getCaretColorHover();
}
else if (property == "caretcolordisabled")
else if (property == "caretcolorfocused")
{
m_caretColorDisabledCached = getSharedRenderer()->getCaretColorDisabled();
m_caretColorFocusedCached = getSharedRenderer()->getCaretColorFocused();
}
else if (property == "selectedtextbackgroundcolor")
{
@ -1431,6 +1421,27 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EditBox::updateTextColor()
{
if (!m_enabled && getSharedRenderer()->getTextColorDisabled().isSet())
{
m_textBeforeSelection.setColor(getSharedRenderer()->getTextColorDisabled());
m_textAfterSelection.setColor(getSharedRenderer()->getTextColorDisabled());
}
else if (m_focused && getSharedRenderer()->getTextColorFocused().isSet())
{
m_textBeforeSelection.setColor(getSharedRenderer()->getTextColorFocused());
m_textAfterSelection.setColor(getSharedRenderer()->getTextColorFocused());
}
else
{
m_textBeforeSelection.setColor(getSharedRenderer()->getTextColor());
m_textAfterSelection.setColor(getSharedRenderer()->getTextColor());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EditBox::update(sf::Time elapsedTime)
{
Widget::update(elapsedTime);
@ -1462,6 +1473,8 @@ namespace tgui
drawBorders(target, states, m_bordersCached, getSize(), m_borderColorDisabledCached);
else if (m_mouseHover && m_borderColorHoverCached.isSet())
drawBorders(target, states, m_bordersCached, getSize(), m_borderColorHoverCached);
else if (m_focused && m_borderColorFocusedCached.isSet())
drawBorders(target, states, m_bordersCached, getSize(), m_borderColorFocusedCached);
else
drawBorders(target, states, m_bordersCached, getSize(), m_borderColorCached);
@ -1471,19 +1484,14 @@ namespace tgui
// Draw the background
if (m_sprite.isSet())
{
if (m_spriteDisabled.isSet())
if (!m_enabled && m_spriteDisabled.isSet())
m_spriteDisabled.draw(target, states);
else if (m_mouseHover && m_spriteHover.isSet())
m_spriteHover.draw(target, states);
else if (m_focused && m_spriteFocused.isSet())
m_spriteFocused.draw(target, states);
else
{
if (m_mouseHover && m_spriteHover.isSet())
m_spriteHover.draw(target, states);
else
m_sprite.draw(target, states);
// When the edit box is focused then draw an extra image
if (m_focused && m_spriteFocused.isSet())
m_spriteFocused.draw(target, states);
}
m_sprite.draw(target, states);
}
else // There is no background texture
{
@ -1491,6 +1499,8 @@ namespace tgui
drawRectangleShape(target, states, getInnerSize(), m_backgroundColorDisabledCached);
else if (m_mouseHover && m_backgroundColorHoverCached.isSet())
drawRectangleShape(target, states, getInnerSize(), m_backgroundColorHoverCached);
else if (m_focused && m_backgroundColorFocusedCached.isSet())
drawRectangleShape(target, states, getInnerSize(), m_backgroundColorFocusedCached);
else
drawRectangleShape(target, states, getInnerSize(), m_backgroundColorCached);
}
@ -1521,12 +1531,12 @@ namespace tgui
// Draw the caret
states.transform.translate(m_caret.getPosition());
if (m_focused && m_caretVisible)
if (m_enabled && m_focused && m_caretVisible)
{
if (!m_enabled && m_caretColorDisabledCached.isSet())
drawRectangleShape(target, states, m_caret.getSize(), m_caretColorDisabledCached);
else if (m_mouseHover && m_caretColorHoverCached.isSet())
if (m_mouseHover && m_caretColorHoverCached.isSet())
drawRectangleShape(target, states, m_caret.getSize(), m_caretColorHoverCached);
else if (m_focused && m_caretColorFocusedCached.isSet())
drawRectangleShape(target, states, m_caret.getSize(), m_caretColorFocusedCached);
else
drawRectangleShape(target, states, m_caret.getSize(), m_caretColorCached);
}

View File

@ -425,14 +425,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Knob::widgetFocused()
{
// A knob can't be focused
unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Knob::recalculateRotation()
{
// Calculate the difference in degrees between the start and end rotation

View File

@ -239,6 +239,13 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Label::canGainFocus() const
{
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Label::leftMouseReleased(Vector2f pos)
{
const bool mouseDown = m_mouseDown;

View File

@ -35,6 +35,7 @@ namespace tgui
Panel::Panel(const Layout2d& size)
{
m_type = "Panel";
m_isolatedFocus = true;
m_renderer = aurora::makeCopied<PanelRenderer>();
setRenderer(Theme::getDefault()->getRendererNoThrow(m_type));

View File

@ -119,6 +119,13 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Picture::canGainFocus() const
{
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Picture::mouseOnWidget(Vector2f pos) const
{
pos -= getPosition();

View File

@ -262,17 +262,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RadioButton::widgetFocused()
{
// We can't be focused when we don't have a focus image
if (m_spriteFocused.isSet())
Widget::widgetFocused();
else
unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RadioButton::mouseEnteredWidget()
{
Widget::mouseEnteredWidget();
@ -358,10 +347,13 @@ namespace tgui
{
m_spriteCheckedDisabled.setTexture(getSharedRenderer()->getTextureCheckedDisabled());
}
else if (property == "texturefocused")
else if (property == "textureuncheckedfocused")
{
m_spriteFocused.setTexture(getSharedRenderer()->getTextureFocused());
m_allowFocus = m_spriteFocused.isSet();
m_spriteUncheckedFocused.setTexture(getSharedRenderer()->getTextureUncheckedFocused());
}
else if (property == "texturecheckedfocused")
{
m_spriteCheckedFocused.setTexture(getSharedRenderer()->getTextureCheckedFocused());
}
else if (property == "checkcolor")
{
@ -387,6 +379,10 @@ namespace tgui
{
m_borderColorDisabledCached = getSharedRenderer()->getBorderColorDisabled();
}
else if (property == "bordercolorfocused")
{
m_borderColorFocusedCached = getSharedRenderer()->getBorderColorFocused();
}
else if (property == "bordercolorchecked")
{
m_borderColorCheckedCached = getSharedRenderer()->getBorderColorChecked();
@ -399,6 +395,10 @@ namespace tgui
{
m_borderColorCheckedDisabledCached = getSharedRenderer()->getBorderColorCheckedDisabled();
}
else if (property == "bordercolorcheckedfocused")
{
m_borderColorCheckedFocusedCached = getSharedRenderer()->getBorderColorCheckedFocused();
}
else if (property == "backgroundcolor")
{
m_backgroundColorCached = getSharedRenderer()->getBackgroundColor();
@ -437,7 +437,8 @@ namespace tgui
m_spriteCheckedHover.setOpacity(m_opacityCached);
m_spriteUncheckedDisabled.setOpacity(m_opacityCached);
m_spriteCheckedDisabled.setOpacity(m_opacityCached);
m_spriteFocused.setOpacity(m_opacityCached);
m_spriteUncheckedFocused.setOpacity(m_opacityCached);
m_spriteCheckedFocused.setOpacity(m_opacityCached);
m_text.setOpacity(m_opacityCached);
}
@ -564,15 +565,23 @@ namespace tgui
return m_borderColorCheckedHoverCached;
else if (m_borderColorCheckedCached.isSet())
return m_borderColorCheckedCached;
else if (m_focused && m_borderColorCheckedFocusedCached.isSet())
return m_borderColorCheckedFocusedCached;
else if (m_borderColorHoverCached.isSet())
return m_borderColorHoverCached;
else if (m_focused && m_borderColorFocusedCached.isSet())
return m_borderColorFocusedCached;
else
return m_borderColorCached;
}
else
{
if (m_borderColorCheckedCached.isSet())
if (m_focused && m_borderColorCheckedFocusedCached.isSet())
return m_borderColorCheckedFocusedCached;
else if (m_borderColorCheckedCached.isSet())
return m_borderColorCheckedCached;
else if (m_focused && m_borderColorFocusedCached.isSet())
return m_borderColorFocusedCached;
else
return m_borderColorCached;
}
@ -583,6 +592,8 @@ namespace tgui
return m_borderColorDisabledCached;
else if (m_mouseHover && m_borderColorHoverCached.isSet())
return m_borderColorHoverCached;
else if (m_focused && m_borderColorFocusedCached.isSet())
return m_borderColorFocusedCached;
else
return m_borderColorCached;
}
@ -598,7 +609,8 @@ namespace tgui
m_spriteCheckedHover.setSize(getInnerSize());
m_spriteUncheckedDisabled.setSize(getInnerSize());
m_spriteCheckedDisabled.setSize(getInnerSize());
m_spriteFocused.setSize(getInnerSize());
m_spriteUncheckedFocused.setSize(getInnerSize());
m_spriteCheckedFocused.setSize(getInnerSize());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -668,6 +680,8 @@ namespace tgui
m_spriteCheckedDisabled.draw(target, states);
else if (m_mouseHover && m_spriteCheckedHover.isSet())
m_spriteCheckedHover.draw(target, states);
else if (m_focused && m_spriteCheckedFocused.isSet())
m_spriteCheckedFocused.draw(target, states);
else
m_spriteChecked.draw(target, states);
}
@ -677,13 +691,11 @@ namespace tgui
m_spriteUncheckedDisabled.draw(target, states);
else if (m_mouseHover && m_spriteUncheckedHover.isSet())
m_spriteUncheckedHover.draw(target, states);
else if (m_focused && m_spriteUncheckedFocused.isSet())
m_spriteUncheckedFocused.draw(target, states);
else
m_spriteUnchecked.draw(target, states);
}
// When the radio button is focused then draw an extra image
if (m_focused && m_spriteFocused.isSet())
m_spriteFocused.draw(target, states);
}
else // There are no images
{

View File

@ -326,6 +326,10 @@ namespace tgui
void RangeSlider::setStep(float step)
{
m_step = step;
// Reset the values in case it does not match the step
setSelectionStart(m_selectionStart);
setSelectionEnd(m_selectionEnd);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -459,14 +463,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RangeSlider::widgetFocused()
{
// A slider can't be focused (yet)
unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RangeSlider::mouseNoLongerDown()
{
// The thumb might have been dragged between two values

View File

@ -664,14 +664,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Scrollbar::widgetFocused()
{
// A scrollbar can't be focused (yet)
unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Scrollbar::mouseNoLongerDown()
{
// The thumb might have been dragged between two values

View File

@ -303,14 +303,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void SpinButton::widgetFocused()
{
// A spin button can't be focused
unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Signal& SpinButton::getSignal(std::string signalName)
{
if (signalName == toLower(onValueChange.getName()))

View File

@ -301,6 +301,35 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TextBox::focus()
{
Widget::focus();
#if defined (SFML_SYSTEM_ANDROID) || defined (SFML_SYSTEM_IOS)
sf::Keyboard::setVirtualKeyboardVisible(true);
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TextBox::unfocus()
{
// If there is a selection then undo it now
if (m_selStart != m_selEnd)
{
m_selStart = m_selEnd;
updateSelectionTexts();
}
#if defined (SFML_SYSTEM_ANDROID) || defined (SFML_SYSTEM_IOS)
sf::Keyboard::setVirtualKeyboardVisible(false);
#endif
Widget::unfocus();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool TextBox::mouseOnWidget(Vector2f pos) const
{
return FloatRect{getPosition().x, getPosition().y, getSize().x, getSize().y}.contains(pos);
@ -954,35 +983,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TextBox::widgetFocused()
{
#if defined (SFML_SYSTEM_ANDROID) || defined (SFML_SYSTEM_IOS)
sf::Keyboard::setVirtualKeyboardVisible(true);
#endif
Widget::widgetFocused();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TextBox::widgetUnfocused()
{
// If there is a selection then undo it now
if (m_selStart != m_selEnd)
{
m_selStart = m_selEnd;
updateSelectionTexts();
}
#if defined (SFML_SYSTEM_ANDROID) || defined (SFML_SYSTEM_IOS)
sf::Keyboard::setVirtualKeyboardVisible(false);
#endif
Widget::widgetUnfocused();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sf::Vector2<std::size_t> TextBox::findCaretPosition(Vector2f position) const
{
position.x -= m_bordersCached.getLeft() + m_paddingCached.getLeft();

View File

@ -8,6 +8,7 @@ set(TEST_SOURCES
Clipping.cpp
Color.cpp
Container.cpp
Focus.cpp
Font.cpp
Layouts.cpp
Outline.cpp

View File

@ -221,7 +221,7 @@ TEST_CASE("[Container]")
container->add(editBox2);
container->add(editBox3);
container->focusWidget(editBox2);
editBox2->focus();
REQUIRE(!editBox1->isFocused());
REQUIRE(editBox2->isFocused());
REQUIRE(!editBox3->isFocused());
@ -246,7 +246,7 @@ TEST_CASE("[Container]")
REQUIRE(editBox2->isFocused());
REQUIRE(!editBox3->isFocused());
container->unfocusWidgets();
container->unfocusAllWidgets();
REQUIRE(!editBox1->isFocused());
REQUIRE(!editBox2->isFocused());
REQUIRE(!editBox3->isFocused());

445
tests/Focus.cpp Normal file
View File

@ -0,0 +1,445 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2017 Bruno Van de Velde (vdv_b@tgui.eu)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "Tests.hpp"
#include <TGUI/Widgets/RadioButtonGroup.hpp>
#include <TGUI/Widgets/ChildWindow.hpp>
#include <TGUI/Widgets/RadioButton.hpp>
#include <TGUI/Widgets/CheckBox.hpp>
#include <TGUI/Widgets/TextBox.hpp>
#include <TGUI/Widgets/EditBox.hpp>
#include <TGUI/Widgets/Button.hpp>
#include <TGUI/Widgets/Group.hpp>
#include <TGUI/Widgets/Panel.hpp>
#include <TGUI/Widgets/Label.hpp>
#include <set>
static tgui::Container::Ptr rootContainer;
static bool noWidgetsFocused(tgui::Container::Ptr root)
{
for (auto& widget : root->getWidgets())
{
if (widget->isFocused())
return false;
tgui::Container::Ptr container = std::dynamic_pointer_cast<tgui::Container>(widget);
if (container != nullptr)
{
if (!noWidgetsFocused(container))
return false;
}
}
return true;
}
static bool widgetFocused(tgui::Widget::Ptr widget)
{
if (!widget->isFocused())
return false;
std::set<tgui::Container*> parents;
tgui::Container* parent = widget->getParent();
while (parent)
{
parents.insert(parent);
parent = parent->getParent();
}
std::stack<tgui::Container::Ptr> containers;
containers.push(rootContainer);
while (!containers.empty())
{
const tgui::Container::Ptr container = containers.top();
containers.pop();
for (auto& child : container->getWidgets())
{
if (child == widget)
continue;
tgui::Container::Ptr childContainer = std::dynamic_pointer_cast<tgui::Container>(child);
if (childContainer)
{
containers.push(childContainer);
// Parent of widget has to be focused, all other containers have to be unfocused
if (parents.find(childContainer.get()) != parents.end())
{
if (!child->isFocused())
return false;
}
else // Not a parent
{
if (child->isFocused())
return false;
}
}
else // Not a container
{
if (child->isFocused())
return false;
}
}
}
return true;
}
/// Widgets hierarchy:
//
// Button
// Group
// CheckBox
// Panel
// Group
// RadioButtonGroup
// RadioButton
// RadioButton
// EditBox
// TextBox
// CheckBox
// Panel
// EditBox
// EditBox
// Label
// Button (invisible)
// Button (disabled)
// Button
// ChildWindow
// Button
// ChildWindow
TEST_CASE("[Focussing widgets]")
{
tgui::Gui gui;
rootContainer = gui.getContainer();
auto button = tgui::Button::create("Click me");
button->setPosition({20, 10});
button->setSize({80, 25});
rootContainer->add(button);
auto outerGroup = tgui::Group::create();
outerGroup->setPosition({20, 50});
outerGroup->setSize({220, 270});
rootContainer->add(outerGroup);
auto checkBox1 = tgui::CheckBox::create("Check 1");
checkBox1->setPosition({10, 10});
outerGroup->add(checkBox1);
auto panel = tgui::Panel::create();
panel->getRenderer()->setBackgroundColor(sf::Color::Yellow);
panel->setPosition({10, 40});
panel->setSize({200, 130});
outerGroup->add(panel);
auto group = tgui::Group::create();
group->setPosition({10, 10});
group->setSize({180, 110});
panel->add(group);
auto radioButtonGroup = tgui::RadioButtonGroup::create();
group->add(radioButtonGroup);
auto radioButton1 = tgui::RadioButton::create();
radioButton1->setPosition({10, 10});
radioButton1->setText("Option 1");
radioButtonGroup->add(radioButton1);
auto radioButton2 = tgui::RadioButton::create();
radioButton2->setPosition({10, 40});
radioButton2->setText("Option 2");
radioButton2->check();
radioButtonGroup->add(radioButton2);
auto editBox = tgui::EditBox::create();
editBox->setPosition({10, 80});
editBox->setSize({150, 20});
editBox->setText("Some text");
panel->add(editBox);
auto textBox = tgui::TextBox::create();
textBox->setSize({160, 60});
textBox->setPosition({10, 180});
textBox->setText("TextBox\nFilled with text");
outerGroup->add(textBox);
auto checkBox2 = tgui::CheckBox::create("Check 2");
checkBox2->setPosition({10, 250});
outerGroup->add(checkBox2);
auto outerPanel = tgui::Panel::create();
outerPanel->getRenderer()->setBackgroundColor(sf::Color::Green);
outerPanel->setPosition({20, 330});
outerPanel->setSize({200, 130});
rootContainer->add(outerPanel);
auto editBoxUsername = tgui::EditBox::create();
editBoxUsername->setPosition({10, 10});
editBoxUsername->setSize({180, 20});
editBoxUsername->setDefaultText("Username");
outerPanel->add(editBoxUsername);
auto editBoxPassword = tgui::EditBox::create();
editBoxPassword->setPosition({10, 40});
editBoxPassword->setSize({180, 20});
editBoxPassword->setDefaultText("Password");
outerPanel->add(editBoxPassword);
auto label = tgui::Label::create("Hidden button:");
label->setPosition({10, 70});
outerPanel->add(label);
auto invisibleButton = tgui::Button::create("Hidden");
invisibleButton->setPosition({120, 70});
invisibleButton->setSize({60, 20});
invisibleButton->hide();
outerPanel->add(invisibleButton);
auto buttonLogin = tgui::Button::create("Log in");
buttonLogin->setPosition({10, 100});
buttonLogin->setSize({85, 20});
outerPanel->add(buttonLogin);
auto buttonRegister = tgui::Button::create("Register");
buttonRegister->setPosition({105, 100});
buttonRegister->setSize({85, 20});
buttonRegister->disable();
outerPanel->add(buttonRegister);
auto childWindow = tgui::ChildWindow::create("Window 1");
childWindow->setSize({100, 30});
childWindow->setPosition({10, 470});
rootContainer->add(childWindow);
auto childButton = tgui::Button::create("Button");
childButton->setSize({90, 20});
childButton->setPosition({5, 5});
childWindow->add(childButton);
auto emptyChildWindow = tgui::ChildWindow::create("Window 2");
emptyChildWindow->setSize({100, 30});
emptyChildWindow->setPosition({120, 470});
rootContainer->add(emptyChildWindow);
SECTION("Focus method")
{
REQUIRE(noWidgetsFocused(rootContainer));
button->focus();
REQUIRE(widgetFocused(button));
outerPanel->focus();
REQUIRE(widgetFocused(outerPanel));
radioButton2->focus();
REQUIRE(widgetFocused(radioButton2));
editBoxPassword->focus();
REQUIRE(widgetFocused(editBoxPassword));
// Invisible widget can't be focused
invisibleButton->focus();
REQUIRE(widgetFocused(editBoxPassword));
// Disabled widget can't be focused
buttonRegister->focus();
REQUIRE(widgetFocused(editBoxPassword));
// Some widgets, like Label, can't be focused
label->focus();
REQUIRE(widgetFocused(editBoxPassword));
// Unfocusing container unfocuses all child widgets
rootContainer->unfocus();
REQUIRE(noWidgetsFocused(rootContainer));
}
SECTION("focusNextWidget")
{
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(button));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(checkBox1));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(textBox));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(checkBox2));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(button));
radioButton2->focus();
REQUIRE(widgetFocused(radioButton2));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(editBox));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(radioButton1));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(radioButton2));
editBoxUsername->focus();
REQUIRE(widgetFocused(editBoxUsername));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(editBoxPassword));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(buttonLogin));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(editBoxUsername));
childButton->focus();
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(childButton));
outerPanel->focus();
REQUIRE(widgetFocused(outerPanel));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(editBoxPassword)); // editBoxUsername was focused last time the panel was focused
emptyChildWindow->focus();
REQUIRE(widgetFocused(emptyChildWindow));
rootContainer->focusNextWidget();
REQUIRE(widgetFocused(button));
}
SECTION("focusPreviousWidget")
{
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(checkBox2));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(textBox));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(checkBox1));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(button));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(checkBox2));
radioButton2->focus();
REQUIRE(widgetFocused(radioButton2));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(radioButton1));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(editBox));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(radioButton2));
editBoxPassword->focus();
REQUIRE(widgetFocused(editBoxPassword));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(editBoxUsername));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(buttonLogin));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(editBoxPassword));
childButton->focus();
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(childButton));
outerPanel->focus();
REQUIRE(widgetFocused(outerPanel));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(editBoxUsername)); // editBoxPassword was focused last time the panel was focused
emptyChildWindow->focus();
REQUIRE(widgetFocused(emptyChildWindow));
rootContainer->focusPreviousWidget();
REQUIRE(widgetFocused(checkBox2));
}
SECTION("Gui interaction")
{
sf::RenderTexture target;
target.create(250, 530);
gui.setTarget(target);
sf::Event event;
event.type = sf::Event::MouseButtonPressed;
event.mouseButton = sf::Event::MouseButtonEvent();
event.mouseButton.button = sf::Mouse::Left;
event.mouseButton.x = 55;
event.mouseButton.y = 145;
gui.handleEvent(event);
REQUIRE(widgetFocused(radioButton2));
event.type = sf::Event::MouseButtonReleased;
gui.handleEvent(event);
REQUIRE(widgetFocused(radioButton2));
event.type = sf::Event::KeyPressed;
event.key = sf::Event::KeyEvent();
event.key.control = false;
event.key.alt = false;
event.key.shift = false;
event.key.system = false;
event.key.code = sf::Keyboard::Tab;
gui.handleEvent(event);
REQUIRE(widgetFocused(editBox));
event.type = sf::Event::KeyReleased;
gui.handleEvent(event);
REQUIRE(widgetFocused(editBox));
event.type = sf::Event::KeyPressed;
event.key.shift = true;
gui.handleEvent(event);
event.type = sf::Event::KeyReleased;
gui.handleEvent(event);
REQUIRE(widgetFocused(radioButton2));
event.type = sf::Event::KeyPressed;
gui.handleEvent(event);
event.type = sf::Event::KeyReleased;
gui.handleEvent(event);
REQUIRE(widgetFocused(radioButton1));
}
}

View File

@ -418,7 +418,6 @@ TEST_CASE("[EditBox]")
REQUIRE_NOTHROW(renderer->setProperty("DefaultTextColor", "rgb(50, 60, 70)"));
REQUIRE_NOTHROW(renderer->setProperty("CaretColor", "rgb(60, 70, 80)"));
REQUIRE_NOTHROW(renderer->setProperty("CaretColorHover", "rgb(110, 120, 130)"));
REQUIRE_NOTHROW(renderer->setProperty("CaretColorDisabled", "rgb(130, 140, 150)"));
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColor", "rgb(70, 80, 90)"));
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColorHover", "rgb(80, 90, 100)"));
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColorDisabled", "rgb(140, 150, 160)"));
@ -441,7 +440,6 @@ TEST_CASE("[EditBox]")
REQUIRE_NOTHROW(renderer->setProperty("DefaultTextColor", sf::Color{50, 60, 70}));
REQUIRE_NOTHROW(renderer->setProperty("CaretColor", sf::Color{60, 70, 80}));
REQUIRE_NOTHROW(renderer->setProperty("CaretColorHover", sf::Color{110, 120, 130}));
REQUIRE_NOTHROW(renderer->setProperty("CaretColorDisabled", sf::Color{130, 140, 150}));
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColor", sf::Color{70, 80, 90}));
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColorHover", sf::Color{80, 90, 100}));
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColorDisabled", sf::Color{140, 150, 160}));
@ -464,7 +462,6 @@ TEST_CASE("[EditBox]")
renderer->setDefaultTextColor({50, 60, 70});
renderer->setCaretColor({60, 70, 80});
renderer->setCaretColorHover({110, 120, 130});
renderer->setCaretColorDisabled({130, 140, 150});
renderer->setBackgroundColor({70, 80, 90});
renderer->setBackgroundColorHover({80, 90, 100});
renderer->setBackgroundColorDisabled({140, 150, 160});
@ -485,7 +482,6 @@ TEST_CASE("[EditBox]")
REQUIRE(renderer->getProperty("DefaultTextColor").getColor() == sf::Color(50, 60, 70));
REQUIRE(renderer->getProperty("CaretColor").getColor() == sf::Color(60, 70, 80));
REQUIRE(renderer->getProperty("CaretColorHover").getColor() == sf::Color(110, 120, 130));
REQUIRE(renderer->getProperty("CaretColorDisabled").getColor() == sf::Color(130, 140, 150));
REQUIRE(renderer->getProperty("BackgroundColor").getColor() == sf::Color(70, 80, 90));
REQUIRE(renderer->getProperty("BackgroundColorHover").getColor() == sf::Color(80, 90, 100));
REQUIRE(renderer->getProperty("BackgroundColorDisabled").getColor() == sf::Color(140, 150, 160));
@ -505,7 +501,6 @@ TEST_CASE("[EditBox]")
REQUIRE(renderer->getDefaultTextColor() == sf::Color(50, 60, 70));
REQUIRE(renderer->getCaretColor() == sf::Color(60, 70, 80));
REQUIRE(renderer->getCaretColorHover() == sf::Color(110, 120, 130));
REQUIRE(renderer->getCaretColorDisabled() == sf::Color(130, 140, 150));
REQUIRE(renderer->getBackgroundColor() == sf::Color(70, 80, 90));
REQUIRE(renderer->getBackgroundColorHover() == sf::Color(80, 90, 100));
REQUIRE(renderer->getBackgroundColorDisabled() == sf::Color(140, 150, 160));
@ -610,7 +605,6 @@ TEST_CASE("[EditBox]")
auto setDisabledRenderer = [&](bool textured){
renderer.setTextColorDisabled({0, 0, 80});
renderer.setCaretColorDisabled({0, 80, 80});
renderer.setBackgroundColorDisabled({80, 80, 0});
renderer.setBorderColorDisabled({80, 0, 0});
if (textured)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -2,6 +2,7 @@ Button {
Texture = "Black.png" Part( 0, 64, 45, 50) Middle(10, 0, 25, 50);
TextureHover = "Black.png" Part(45, 64, 45, 50) Middle(10, 0, 25, 50);
TextureDown = "Black.png" Part(90, 64, 45, 50) Middle(10, 0, 25, 50);
TextureFocused = "Black.png" Part(135, 64, 45, 50) Middle(10, 0, 25, 50);
TextColor = rgb(190, 190, 190);
TextColorHover = rgb(250, 250, 250);
}
@ -13,12 +14,14 @@ ChatBox {
}
Checkbox {
TextureUnchecked = "Black.png" Part(124, 0, 32, 32);
TextureChecked = "Black.png" Part(156, 0, 32, 32);
TextureUncheckedHover = "Black.png" Part(188, 0, 32, 32);
TextureCheckedHover = "Black.png" Part(220, 0, 32, 32);
TextColor = rgb(190, 190, 190);
TextColorHover = rgb(250, 250, 250);
TextureUnchecked = "Black.png" Part(92, 0, 32, 32);
TextureChecked = "Black.png" Part(124, 0, 32, 32);
TextureUncheckedHover = "Black.png" Part(156, 0, 32, 32);
TextureCheckedHover = "Black.png" Part(188, 0, 32, 32);
TextureUncheckedFocused = "Black.png" Part(220, 0, 32, 32);
TextureCheckedFocused = "Black.png" Part(252, 0, 32, 32);
TextColor = rgb(190, 190, 190);
TextColorHover = rgb(250, 250, 250);
}
ChildWindow {
@ -57,8 +60,9 @@ ComboBox {
}
EditBox {
Texture = "Black.png" Part(0, 114, 60, 40) Middle(15, 0, 30, 40);
TextureHover = "Black.png" Part(0, 114, 60, 40) Middle(15, 0, 30, 40);
Texture = "Black.png" Part(0, 114, 60, 40) Middle(15, 0, 30, 40);
TextureHover = "Black.png" Part(60, 114, 60, 40) Middle(15, 0, 30, 40);
TextureFocused = "Black.png" Part(120, 114, 60, 40) Middle(15, 0, 30, 40);
TextColor = rgb(190, 190, 190);
SelectedTextColor = White;
@ -122,12 +126,14 @@ ProgressBar {
}
RadioButton {
TextureUnchecked = "Black.png" Part(124, 32, 32, 32);
TextureChecked = "Black.png" Part(156, 32, 32, 32);
TextureUncheckedHover = "Black.png" Part(188, 32, 32, 32);
TextureCheckedHover = "Black.png" Part(220, 32, 32, 32);
TextColor = rgb(190, 190, 190);
TextColorHover = rgb(250, 250, 250);
TextureUnchecked = "Black.png" Part(92, 32, 32, 32);
TextureChecked = "Black.png" Part(124, 32, 32, 32);
TextureUncheckedHover = "Black.png" Part(156, 32, 32, 32);
TextureCheckedHover = "Black.png" Part(188, 32, 32, 32);
TextureUncheckedFocused = "Black.png" Part(220, 32, 32, 32);
TextureCheckedFocused = "Black.png" Part(252, 32, 32, 32);
TextColor = rgb(190, 190, 190);
TextColorHover = rgb(250, 250, 250);
}
Scrollbar {