Skip to content

Commit

Permalink
Added CloseBehavior property to ChildWindow
Browse files Browse the repository at this point in the history
  • Loading branch information
texus committed Sep 8, 2024
1 parent 5d6628a commit 1672dbd
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 6 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
TGUI 1.6 (TBD)
--------------

- Added CloseBehavior property to ChildWindow
- Fixed crash on exit when tool tip was visible


Expand Down
4 changes: 4 additions & 0 deletions include/TGUI/Backend/Renderer/BackendRenderTarget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ TGUI_MODULE_EXPORT namespace tgui
/// This function should always be called prior to drawTextWithoutOutline. It exists to allow rendering the outline of
/// multiple texts before rendering all these texts, which is done by calling drawTextOutline for each text before
/// calling drawTextWithoutOutline on all the same text objects.
///
/// @since TGUI 1.6
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void drawTextOutline(const RenderStates& states, const Text& text);

Expand All @@ -174,6 +176,8 @@ TGUI_MODULE_EXPORT namespace tgui
/// This function should always be called after drawTextOutline. It exists to allow rendering the outline of
/// multiple texts before rendering all these texts, which is done by calling drawTextOutline for each text before
/// calling drawTextWithoutOutline on all the same text objects.
///
/// @since TGUI 1.6
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void drawTextWithoutOutline(const RenderStates& states, const Text& text);

Expand Down
1 change: 0 additions & 1 deletion include/TGUI/Duration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ TGUI_MODULE_EXPORT namespace tgui

constexpr Duration& operator-=(Duration& lhs, const Duration& rhs)
{

return lhs = lhs - rhs;
}

Expand Down
37 changes: 34 additions & 3 deletions include/TGUI/Widgets/ChildWindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ TGUI_MODULE_EXPORT namespace tgui
Minimize = 1 << 2 //!< Include a minimize button
};

/// Defines what the child window should do inside its close() function (which is called when the close button is pressed)
/// @since TGUI 1.6
enum class CloseBehavior
{
None, //!< Nothing should happen after the onClose callback is called. The window remains visible (unless the onClose callback did something).
Hide, //!< childWindow->setVisible(false) is called after the onClose callback is called
Remove //!< parent->remove(childWindow) is called after the onClose callback is called
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/// @brief Constructor
Expand Down Expand Up @@ -271,13 +280,34 @@ TGUI_MODULE_EXPORT namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TGUI_NODISCARD unsigned int getTitleButtons() const;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the behavior of closing the window
/// @param behavior Defines what the close() function does after calling the onClose callback
///
/// The default close behavior is Remove.
///
/// @since TGUI 1.6
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setCloseBehavior(CloseBehavior behavior);

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the behavior of closing the window
/// @return What the close() function does after calling the onClose callback
///
/// The default close behavior is Remove.
///
/// @since TGUI 1.6
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TGUI_NODISCARD CloseBehavior getCloseBehavior() const;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Try to close the window
///
/// This will trigger the onClosing signal. If a callback function for this signal sets the abort parameter to true then
/// the window will remain open. Otherwise the onClose signal is triggered and the window is removed from its parent.
/// the window will remain open. Otherwise the onClose signal is triggered and the chosen closing behavior is executed.
///
/// If you want to close the window without those callbacks being triggered then you need to use the destroy() function.
/// If you want to "close" the window without those callbacks being triggered then you should just remove the child
/// window from the parent to which it was added (i.e. parent->remove(childWindow)).
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void close();

Expand All @@ -287,7 +317,7 @@ TGUI_MODULE_EXPORT namespace tgui
/// This function is equivalent to removing the window from its parent. If you want to be receive a callback and have
/// the ability to abort the operation then you should use the close() function instead.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void destroy();
TGUI_DEPRECATED("Use parent->remove(childWindow) instead") void destroy();

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes whether the child window can be resized by dragging its borders or not
Expand Down Expand Up @@ -530,6 +560,7 @@ TGUI_MODULE_EXPORT namespace tgui
unsigned int m_titleButtons = TitleButton::Close;
unsigned int m_titleTextSize = 0;
Cursor::Type m_currentChildWindowMouseCursor = Cursor::Type::Arrow;
CloseBehavior m_closeBehavior = CloseBehavior::Remove;

CopiedSharedPtr<Button> m_closeButton;
CopiedSharedPtr<Button> m_minimizeButton;
Expand Down
2 changes: 1 addition & 1 deletion include/TGUI/Widgets/Tabs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ TGUI_MODULE_EXPORT namespace tgui
/// @brief Selects the tab with a given text
/// @param text The text of the tab to select
/// @return Whether a tab was selected, false is returned if tab doesn't exist or is invisible or disabled
/// @see select(int)
/// @see select(std::size_t)
///
/// If there are multiple tabs with the same text then the first one will be selected.
/// When false is returned, the selected tab will still be deselected.
Expand Down
42 changes: 41 additions & 1 deletion src/Widgets/ChildWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,20 @@ namespace tgui

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ChildWindow::setCloseBehavior(CloseBehavior behavior)
{
m_closeBehavior = behavior;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

ChildWindow::CloseBehavior ChildWindow::getCloseBehavior() const
{
return m_closeBehavior;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ChildWindow::close()
{
bool abort = false;
Expand All @@ -570,7 +584,14 @@ namespace tgui
return;

onClose.emit(this);
destroy();

if (m_closeBehavior == CloseBehavior::Remove)
{
if (m_parent)
m_parent->remove(shared_from_this());
}
else if (m_closeBehavior == CloseBehavior::Hide)
setVisible(false);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1259,6 +1280,13 @@ namespace tgui

node->propertyValuePairs[U"TitleButtons"] = std::make_unique<DataIO::ValueNode>(serializedTitleButtons);

if (m_closeBehavior == CloseBehavior::None)
node->propertyValuePairs[U"CloseBehavior"] = std::make_unique<DataIO::ValueNode>("None");
else if (m_closeBehavior == CloseBehavior::Hide)
node->propertyValuePairs[U"CloseBehavior"] = std::make_unique<DataIO::ValueNode>("Hide");
else if (m_closeBehavior == CloseBehavior::Remove)
node->propertyValuePairs[U"CloseBehavior"] = std::make_unique<DataIO::ValueNode>("Remove");

return node;
}

Expand Down Expand Up @@ -1317,6 +1345,18 @@ namespace tgui

if (node->propertyValuePairs[U"MaximumSize"])
setMaximumSize(Vector2f{node->propertyValuePairs[U"MaximumSize"]->value});

if (node->propertyValuePairs[U"CloseBehavior"])
{
if (node->propertyValuePairs[U"CloseBehavior"]->value == U"None")
setCloseBehavior(CloseBehavior::None);
else if (node->propertyValuePairs[U"CloseBehavior"]->value == U"Hide")
setCloseBehavior(CloseBehavior::Hide);
else if (node->propertyValuePairs[U"CloseBehavior"]->value == U"Remove")
setCloseBehavior(CloseBehavior::Remove);
else
throw Exception{U"Failed to parse CloseBehavior property. Only the values None, Hide and Remove are correct."};
}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
37 changes: 37 additions & 0 deletions tests/Widgets/ChildWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,43 @@ TEST_CASE("[ChildWindow]")
REQUIRE(childWindow->getKeepInParent() == false);
}

SECTION("CloseBehavior")
{
auto parent = tgui::Panel::create({300, 200});
parent->add(childWindow);

unsigned int onCloseCount = 0;
unsigned int onClosingCount = 0;
childWindow->onClose(&genericCallback, std::ref(onCloseCount));
childWindow->onClosing(&genericCallback, std::ref(onClosingCount));

REQUIRE(parent->getWidgets().size() == 1);
REQUIRE(childWindow->isVisible());

childWindow->setCloseBehavior(tgui::ChildWindow::CloseBehavior::Remove);
REQUIRE(childWindow->getCloseBehavior() == tgui::ChildWindow::CloseBehavior::Remove);
childWindow->close();
REQUIRE(parent->getWidgets().size() == 0);
REQUIRE(childWindow->isVisible());
parent->add(childWindow);

childWindow->setCloseBehavior(tgui::ChildWindow::CloseBehavior::Hide);
REQUIRE(childWindow->getCloseBehavior() == tgui::ChildWindow::CloseBehavior::Hide);
childWindow->close();
REQUIRE(parent->getWidgets().size() == 1);
REQUIRE(!childWindow->isVisible());
childWindow->setVisible(true);

childWindow->setCloseBehavior(tgui::ChildWindow::CloseBehavior::None);
REQUIRE(childWindow->getCloseBehavior() == tgui::ChildWindow::CloseBehavior::None);
childWindow->close();
REQUIRE(parent->getWidgets().size() == 1);
REQUIRE(childWindow->isVisible());

REQUIRE(onClosingCount == 3);
REQUIRE(onCloseCount == 3);
}

SECTION("Events / Signals")
{
childWindow->setPosition(40, 30);
Expand Down

0 comments on commit 1672dbd

Please sign in to comment.