Added IgnoreMouseEvents property to Picture and Label so that they can be placed in front of other widgets while the widgets behind the picture/label still receives the mouse events

0.8
Bruno Van de Velde 2017-09-05 23:28:21 +02:00
parent af77406789
commit 7b22bb4de0
8 changed files with 102 additions and 1 deletions

View File

@ -257,6 +257,24 @@ namespace tgui
float getMaximumTextWidth() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets whether the widget should completely ignore mouse events and let them pass to the widgets behind it
///
/// @param ignore Should mouse events be ignored by this widget?
///
/// By default, mouse events are NOT ignored.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ignoreMouseEvents(bool ignore = true);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the widget is ignoring mouse events and letting them pass to the widgets behind it
///
/// @return Are mouse events ignored by this widget?
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isIgnoringMouseEvents() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/// This function is called when the widget is added to a container.
@ -346,6 +364,8 @@ namespace tgui
float m_maximumTextWidth = 0;
bool m_ignoringMouseEvents = false;
// Will be set to true after the first click, but gets reset to false when the second click does not occur soon after
bool m_possibleDoubleClick = false;

View File

@ -130,6 +130,24 @@ namespace tgui
using Widget::setSize;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets whether the widget should completely ignore mouse events and let them pass to the widgets behind it
///
/// @param ignore Should mouse events be ignored by this widget?
///
/// By default, mouse events are NOT ignored.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ignoreMouseEvents(bool ignore = true);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the widget is ignoring mouse events and letting them pass to the widgets behind it
///
/// @return Are mouse events ignored by this widget?
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isIgnoringMouseEvents() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the mouse position (which is relative to the parent widget) lies on top of the widget
///
@ -208,6 +226,8 @@ namespace tgui
Sprite m_sprite;
bool m_ignoringMouseEvents = false;
// Set to true when clicks on transparent parts of the picture should go to the widgets behind the picture
bool m_ignoreTransparentParts = true;

View File

@ -718,6 +718,9 @@ namespace tgui
if (node->propertyValuePairs["autosize"])
label->setAutoSize(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["autosize"]->value).getBool());
if (node->propertyValuePairs["ignoremouseevents"])
label->ignoreMouseEvents(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["ignoremouseevents"]->value).getBool());
return label;
}
@ -865,6 +868,9 @@ namespace tgui
else
picture = Picture::create();
if (node->propertyValuePairs["ignoremouseevents"])
picture->ignoreMouseEvents(Deserializer::deserialize(ObjectConverter::Type::Bool, node->propertyValuePairs["ignoremouseevents"]->value).getBool());
loadWidget(node, picture);
return picture;

View File

@ -438,6 +438,9 @@ namespace tgui
if (label->getAutoSize())
SET_PROPERTY("AutoSize", "true");
if (label->isIgnoringMouseEvents())
SET_PROPERTY("IgnoreMouseEvents", Serializer::serialize(label->isIgnoringMouseEvents()));
SET_PROPERTY("TextSize", to_string(label->getTextSize()));
return node;
}
@ -534,6 +537,10 @@ namespace tgui
{
auto picture = std::static_pointer_cast<Picture>(widget);
auto node = WidgetSaver::getSaveFunction("widget")(picture);
if (picture->isIgnoringMouseEvents())
SET_PROPERTY("IgnoreMouseEvents", Serializer::serialize(picture->isIgnoringMouseEvents()));
return node;
}

View File

@ -190,6 +190,20 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Label::ignoreMouseEvents(bool ignore)
{
m_ignoringMouseEvents = ignore;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Label::isIgnoringMouseEvents() const
{
return m_ignoringMouseEvents;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Label::setParent(Container* parent)
{
const bool autoSize = getAutoSize();

View File

@ -77,12 +77,26 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Picture::ignoreMouseEvents(bool ignore)
{
m_ignoringMouseEvents = ignore;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Picture::isIgnoringMouseEvents() const
{
return m_ignoringMouseEvents;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Picture::mouseOnWidget(sf::Vector2f pos) const
{
pos -= getPosition();
// Check if the mouse is on top of the picture
if (sf::FloatRect{0, 0, getSize().x, getSize().y}.contains(pos))
if (!m_ignoringMouseEvents && (sf::FloatRect{0, 0, getSize().x, getSize().y}.contains(pos)))
{
// We sometimes want clicks to go through transparent parts of the picture
if (!m_ignoreTransparentParts && m_sprite.isTransparentPixel(pos))

View File

@ -128,6 +128,15 @@ TEST_CASE("[Label]")
REQUIRE(label->getMaximumTextWidth() == 500);
}
SECTION("IgnoreMouseEvents")
{
REQUIRE(!label->isIgnoringMouseEvents());
label->ignoreMouseEvents(true);
REQUIRE(label->isIgnoringMouseEvents());
label->ignoreMouseEvents(false);
REQUIRE(!label->isIgnoringMouseEvents());
}
SECTION("Events / Signals")
{
SECTION("ClickableWidget")
@ -219,6 +228,7 @@ TEST_CASE("[Label]")
label->setHorizontalAlignment(tgui::Label::HorizontalAlignment::Center);
label->setVerticalAlignment(tgui::Label::VerticalAlignment::Bottom);
label->setMaximumTextWidth(300);
label->ignoreMouseEvents(true);
testSavingWidget("Label", label);
}

View File

@ -74,6 +74,15 @@ TEST_CASE("[Picture]")
REQUIRE(picture->getWidgetOffset() == sf::Vector2f(0, 0));
}
SECTION("IgnoreMouseEvents")
{
REQUIRE(!picture->isIgnoringMouseEvents());
picture->ignoreMouseEvents(true);
REQUIRE(picture->isIgnoringMouseEvents());
picture->ignoreMouseEvents(false);
REQUIRE(!picture->isIgnoringMouseEvents());
}
SECTION("Events / Signals")
{
SECTION("ClickableWidget")
@ -148,6 +157,7 @@ TEST_CASE("[Picture]")
{
picture->getRenderer()->setTexture("resources/image.png");
picture->setSize(80, 60);
picture->ignoreMouseEvents(true);
testSavingWidget("Picture", picture, false);
}