Added setTabVisible and setTabEnabled functions to Tabs widget

0.8
Bruno Van de Velde 2018-04-07 10:57:35 +02:00
parent 0239b8a1d4
commit 7d0c56f72f
6 changed files with 375 additions and 101 deletions

View File

@ -96,6 +96,20 @@ namespace tgui
Color getBackgroundColorHover() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background color of a disabled tab
/// @param backgroundColor The new disabled background color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBackgroundColorDisabled(Color backgroundColor);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the background color of a disabled tab
/// @return Disabled background color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getBackgroundColorDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background color of the selected tab
///
@ -168,6 +182,20 @@ namespace tgui
Color getTextColorHover() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text of a disabled tab
/// @param textColor The new disabled text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColorDisabled(Color textColor);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the text of a disabled tab
/// @return Disabled text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getTextColorDisabled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text from the selected tab
///
@ -262,6 +290,22 @@ namespace tgui
Texture& getTextureSelectedTab() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Change the image of a disabled tab
/// @param texture The new disabled tab texture
///
/// The disabled texture is only used when a normal and selected tab texture are also set.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureDisabledTab(const Texture& texture);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the image of a disabled tab
/// @return disabled tab texture
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture& getTextureDisabledTab() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the distance between the text and the side of the tab
///

View File

@ -103,6 +103,16 @@ namespace tgui
using Widget::setSize;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Enables or disables the widget
/// @param enabled Is the widget enabled?
///
/// The disabled widget will no longer receive events and thus no longer send callbacks.
/// All widgets are enabled by default.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setEnabled(bool enabled) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes whether the tabs are auto-sized or not
///
@ -263,6 +273,38 @@ namespace tgui
int getSelectedIndex() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes whether a tab is visible
/// @param index The index of the tab to show or hide
/// @param visible Is the tab shown?
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTabVisible(std::size_t index, bool visible);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the tab is shown or hidden
/// @param index The index of the tab
/// @return Whether the tab is visible
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool getTabVisible(std::size_t index) const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes whether a tab is enabled
/// @param index The index of the tab to enable or disable
/// @param visible Is the tab enabled?
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTabEnabled(std::size_t index, bool enabled);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the tab is enabled or disabled
/// @param index The index of the tab
/// @return Whether the tab is enabled
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool getTabEnabled(std::size_t index) const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the character size of the text
///
@ -463,21 +505,31 @@ namespace tgui
int m_selectedTab = -1;
int m_hoveringTab = -1;
bool m_autoSize = true;
std::vector<float> m_tabWidth;
std::vector<Text> m_tabTexts;
struct Tab
{
bool visible;
bool enabled;
float width;
Text text;
};
std::vector<Tab> m_tabs;
Sprite m_spriteTab;
Sprite m_spriteSelectedTab;
Sprite m_spriteDisabledTab;
// Cached renderer properties
Borders m_bordersCached;
Color m_borderColorCached;
Color m_backgroundColorCached;
Color m_backgroundColorHoverCached;
Color m_backgroundColorDisabledCached;
Color m_selectedBackgroundColorCached;
Color m_selectedBackgroundColorHoverCached;
Color m_textColorCached;
Color m_textColorHoverCached;
Color m_textColorDisabledCached;
Color m_selectedTextColorCached;
Color m_selectedTextColorHoverCached;
float m_distanceToSideCached = 0;

View File

@ -194,9 +194,11 @@ namespace tgui
{"bordercolor", Color::Black},
{"textcolor", Color{60, 60, 60}},
{"textcolorhover", Color::Black},
{"textcolordisabled", Color{125, 125, 125}},
{"selectedtextcolor", Color::White},
{"backgroundcolor", Color{245, 245, 245}},
{"backgroundcolorhover", Color::White},
{"backgroundcolordisabled", Color{230, 230, 230}},
{"selectedbackgroundcolor", Color{0, 110, 255}},
{"selectedbackgroundcolorhover", Color{30, 150, 255}}})},
{"textbox", RendererData::create({{"borders", Borders{1}},

View File

@ -34,16 +34,19 @@ namespace tgui
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, BackgroundColor, Color::White)
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, BackgroundColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, BackgroundColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, SelectedBackgroundColor, Color(0, 110, 255))
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, SelectedBackgroundColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, TextColor, Color::Black)
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, TextColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, TextColorDisabled, {})
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, SelectedTextColor, Color::White)
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, SelectedTextColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(TabsRenderer, BorderColor, Color::Black)
TGUI_RENDERER_PROPERTY_TEXTURE(TabsRenderer, TextureTab)
TGUI_RENDERER_PROPERTY_TEXTURE(TabsRenderer, TextureSelectedTab)
TGUI_RENDERER_PROPERTY_TEXTURE(TabsRenderer, TextureDisabledTab)
TGUI_RENDERER_PROPERTY_NUMBER(TabsRenderer, DistanceToSide, 0)
}

View File

@ -106,6 +106,18 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Tabs::setEnabled(bool enabled)
{
Widget::setEnabled(enabled);
if (!enabled)
deselect();
updateTextColors();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Tabs::setAutoSize(bool autoSize)
{
if (m_autoSize != autoSize)
@ -127,10 +139,10 @@ namespace tgui
std::size_t Tabs::add(const sf::String& text, bool selectTab)
{
// Use the insert function to put the tab in the right place
insert(m_tabTexts.size(), text, selectTab);
insert(m_tabs.size(), text, selectTab);
// Return the index of the new tab
return m_tabTexts.size()-1;
return m_tabs.size()-1;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -138,23 +150,26 @@ namespace tgui
void Tabs::insert(std::size_t index, const sf::String& text, bool selectTab)
{
// If the index is too high then just insert at the end
if (index > m_tabWidth.size())
index = m_tabWidth.size();
if (index > m_tabs.size())
index = m_tabs.size();
// Create the new tab
Text newTab;
newTab.setFont(m_fontCached);
newTab.setColor(m_textColorCached);
newTab.setOpacity(m_opacityCached);
newTab.setCharacterSize(getTextSize());
newTab.setString(text);
Tab newTab;
newTab.visible = true;
newTab.enabled = true;
newTab.width = 0;
newTab.text.setFont(m_fontCached);
newTab.text.setColor(m_textColorCached);
newTab.text.setOpacity(m_opacityCached);
newTab.text.setCharacterSize(getTextSize());
newTab.text.setString(text);
m_tabWidth.insert(m_tabWidth.begin() + index, 0);
m_tabTexts.insert(m_tabTexts.begin() + index, std::move(newTab));
m_tabs.insert(m_tabs.begin() + index, std::move(newTab));
recalculateTabsWidth();
if (m_hoveringTab >= static_cast<int>(index))
m_hoveringTab++;
// New hovered tab depends on several factors, we keep it simple and just remove the hover state
m_hoveringTab = -1;
if (m_selectedTab >= static_cast<int>(index))
m_selectedTab++;
@ -167,20 +182,20 @@ namespace tgui
sf::String Tabs::getText(std::size_t index) const
{
if (index >= m_tabTexts.size())
if (index >= m_tabs.size())
return "";
else
return m_tabTexts[index].getString();
return m_tabs[index].text.getString();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Tabs::changeText(std::size_t index, const sf::String& text)
{
if (index >= m_tabTexts.size())
if (index >= m_tabs.size())
return false;
m_tabTexts[index].setString(text);
m_tabs[index].text.setString(text);
recalculateTabsWidth();
return true;
@ -190,9 +205,9 @@ namespace tgui
void Tabs::select(const sf::String& text)
{
for (unsigned int i = 0; i < m_tabTexts.size(); ++i)
for (unsigned int i = 0; i < m_tabs.size(); ++i)
{
if (m_tabTexts[i].getString() == text)
if (m_tabs[i].text.getString() == text)
{
select(i);
return;
@ -205,22 +220,26 @@ namespace tgui
void Tabs::select(std::size_t index)
{
// If the index is too big then do nothing
if (index > m_tabTexts.size() - 1)
if (index > m_tabs.size() - 1)
return;
// Don't select a tab that is already selected
if (m_selectedTab == static_cast<int>(index))
return;
// Don't select an invisible or disabled tab
if (!m_enabled || !m_tabs[index].visible || !m_tabs[index].enabled)
return;
if (m_selectedTab >= 0)
m_tabTexts[m_selectedTab].setColor(m_textColorCached);
m_tabs[m_selectedTab].text.setColor(m_textColorCached);
// Select the tab
m_selectedTab = static_cast<int>(index);
m_tabTexts[m_selectedTab].setColor(m_selectedTextColorCached);
m_tabs[m_selectedTab].text.setColor(m_selectedTextColorCached);
// Send the callback
onTabSelect.emit(this, m_tabTexts[index].getString());
onTabSelect.emit(this, m_tabs[index].text.getString());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -228,7 +247,7 @@ namespace tgui
void Tabs::deselect()
{
if (m_selectedTab >= 0)
m_tabTexts[m_selectedTab].setColor(m_textColorCached);
m_tabs[m_selectedTab].text.setColor(m_textColorCached);
m_selectedTab = -1;
}
@ -237,9 +256,9 @@ namespace tgui
void Tabs::remove(const sf::String& text)
{
for (unsigned int i = 0; i < m_tabTexts.size(); ++i)
for (unsigned int i = 0; i < m_tabs.size(); ++i)
{
if (m_tabTexts[i].getString() == text)
if (m_tabs[i].text.getString() == text)
{
remove(i);
break;
@ -252,12 +271,11 @@ namespace tgui
void Tabs::remove(std::size_t index)
{
// The index can't be too high
if (index > m_tabTexts.size() - 1)
if (index > m_tabs.size() - 1)
return;
// Remove the tab
m_tabTexts.erase(m_tabTexts.begin() + index);
m_tabWidth.erase(m_tabWidth.begin() + index);
m_tabs.erase(m_tabs.begin() + index);
// Check if the selected tab should be updated
if (m_selectedTab == static_cast<int>(index))
@ -273,8 +291,7 @@ namespace tgui
void Tabs::removeAll()
{
m_tabTexts.clear();
m_tabWidth.clear();
m_tabs.clear();
m_selectedTab = -1;
m_hoveringTab = -1;
@ -286,7 +303,7 @@ namespace tgui
sf::String Tabs::getSelected() const
{
if (m_selectedTab >= 0)
return m_tabTexts[m_selectedTab].getString();
return m_tabs[m_selectedTab].text.getString();
else
return "";
}
@ -300,6 +317,48 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Tabs::setTabVisible(std::size_t index, bool visible)
{
if (index >= m_tabs.size())
return;
m_tabs[index].visible = visible;
recalculateTabsWidth();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Tabs::getTabVisible(std::size_t index) const
{
if (index >= m_tabs.size())
return false;
return m_tabs[index].visible;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Tabs::setTabEnabled(std::size_t index, bool enabled)
{
if (index >= m_tabs.size())
return;
m_tabs[index].enabled = enabled;
updateTextColors();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Tabs::getTabEnabled(std::size_t index) const
{
if (index >= m_tabs.size())
return false;
return m_tabs[index].enabled;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Tabs::setTextSize(unsigned int size)
{
if ((size == 0) || (m_requestedTextSize != size))
@ -311,8 +370,8 @@ namespace tgui
else
m_textSize = size;
for (auto& text : m_tabTexts)
text.setCharacterSize(m_textSize);
for (auto& tab : m_tabs)
tab.text.setCharacterSize(m_textSize);
recalculateTabsWidth();
}
@ -373,7 +432,7 @@ namespace tgui
std::size_t Tabs::getTabsCount() const
{
return m_tabTexts.size();
return m_tabs.size();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -390,12 +449,13 @@ namespace tgui
pos -= getPosition();
float width = m_bordersCached.getLeft() / 2.f;
// Loop through all tabs
for (unsigned int i = 0; i < m_tabWidth.size(); ++i)
for (unsigned int i = 0; i < m_tabs.size(); ++i)
{
if (!m_tabs[i].visible)
continue;
// Append the width of the tab
width += (m_bordersCached.getLeft() / 2.f) + m_tabWidth[i] + (m_bordersCached.getRight() / 2.0f);
width += (m_bordersCached.getLeft() / 2.f) + m_tabs[i].width + (m_bordersCached.getRight() / 2.0f);
// If the mouse went down on this tab then select it
if (pos.x < width)
@ -416,16 +476,20 @@ namespace tgui
m_hoveringTab = -1;
float width = m_bordersCached.getLeft() / 2.f;
// Loop through all tabs
for (unsigned int i = 0; i < m_tabWidth.size(); ++i)
for (unsigned int i = 0; i < m_tabs.size(); ++i)
{
if (!m_tabs[i].visible)
continue;
// Append the width of the tab
width += (m_bordersCached.getLeft() / 2.f) + m_tabWidth[i] + (m_bordersCached.getRight() / 2.0f);
width += (m_bordersCached.getLeft() / 2.f) + m_tabs[i].width + (m_bordersCached.getRight() / 2.0f);
// If the mouse is on top of this tab then remember it
if (pos.x < width)
{
m_hoveringTab = i;
if (m_tabs[i].enabled)
m_hoveringTab = i;
break;
}
}
@ -444,34 +508,44 @@ namespace tgui
void Tabs::recalculateTabsWidth()
{
unsigned int visibleTabs = 0;
for (unsigned int i = 0; i < m_tabs.size(); ++i)
{
if (m_tabs[i].visible)
visibleTabs++;
}
if (m_autoSize)
{
if (m_tabWidth.empty())
if (m_tabs.empty())
Widget::setSize({m_bordersCached.getLeft() + m_bordersCached.getRight(), getSizeLayout().y});
else
{
// First calculate the width of the tabs as if there aren't any borders
float totalWidth = 0;
for (unsigned int i = 0; i < m_tabWidth.size(); ++i)
for (unsigned int i = 0; i < m_tabs.size(); ++i)
{
m_tabWidth[i] = m_tabTexts[i].getSize().x + std::max(m_minimumTabWidth, 2 * m_distanceToSideCached);
if ((m_maximumTabWidth > 0) && (m_maximumTabWidth < m_tabWidth[i]))
m_tabWidth[i] = m_maximumTabWidth;
if (!m_tabs[i].visible)
continue;
totalWidth += m_tabWidth[i];
m_tabs[i].width = m_tabs[i].text.getSize().x + std::max(m_minimumTabWidth, 2 * m_distanceToSideCached);
if ((m_maximumTabWidth > 0) && (m_maximumTabWidth < m_tabs[i].width))
m_tabs[i].width = m_maximumTabWidth;
totalWidth += m_tabs[i].width;
}
// Now add the borders to the tabs
totalWidth += (m_tabWidth.size() + 1) * ((m_bordersCached.getLeft() + m_bordersCached.getRight()) / 2.f);
totalWidth += (visibleTabs + 1) * ((m_bordersCached.getLeft() + m_bordersCached.getRight()) / 2.f);
Widget::setSize({totalWidth, getSizeLayout().y});
}
}
else // A size was provided
{
const float tabWidth = (getSize().x - ((m_tabWidth.size() + 1) * ((m_bordersCached.getLeft() + m_bordersCached.getRight()) / 2.f))) / m_tabWidth.size();
for (unsigned int i = 0; i < m_tabWidth.size(); ++i)
m_tabWidth[i] = tabWidth;
const float tabWidth = (getSize().x - ((visibleTabs + 1) * ((m_bordersCached.getLeft() + m_bordersCached.getRight()) / 2.f))) / visibleTabs;
for (unsigned int i = 0; i < m_tabs.size(); ++i)
m_tabs[i].width = tabWidth;
}
m_bordersCached.updateParentSize(getSize());
@ -506,6 +580,11 @@ namespace tgui
m_textColorHoverCached = getSharedRenderer()->getTextColorHover();
updateTextColors();
}
else if (property == "textcolordisabled")
{
m_textColorDisabledCached = getSharedRenderer()->getTextColorDisabled();
updateTextColors();
}
else if (property == "selectedtextcolor")
{
m_selectedTextColorCached = getSharedRenderer()->getSelectedTextColor();
@ -524,6 +603,10 @@ namespace tgui
{
m_spriteSelectedTab.setTexture(getSharedRenderer()->getTextureSelectedTab());
}
else if (property == "texturedisabledtab")
{
m_spriteDisabledTab.setTexture(getSharedRenderer()->getTextureDisabledTab());
}
else if (property == "distancetoside")
{
m_distanceToSideCached = getSharedRenderer()->getDistanceToSide();
@ -537,6 +620,10 @@ namespace tgui
{
m_backgroundColorHoverCached = getSharedRenderer()->getBackgroundColorHover();
}
else if (property == "backgroundcolordisabled")
{
m_backgroundColorDisabledCached = getSharedRenderer()->getBackgroundColorDisabled();
}
else if (property == "selectedbackgroundcolor")
{
m_selectedBackgroundColorCached = getSharedRenderer()->getSelectedBackgroundColor();
@ -556,15 +643,15 @@ namespace tgui
m_spriteTab.setOpacity(m_opacityCached);
m_spriteSelectedTab.setOpacity(m_opacityCached);
for (auto& tabText : m_tabTexts)
tabText.setOpacity(m_opacityCached);
for (auto& tab : m_tabs)
tab.text.setOpacity(m_opacityCached);
}
else if (property == "font")
{
Widget::rendererChanged(property);
for (auto& tab : m_tabTexts)
tab.setFont(m_fontCached);
for (auto& tab : m_tabs)
tab.text.setFont(m_fontCached);
// Recalculate the size when the text is auto sizing
if (m_requestedTextSize == 0)
@ -582,14 +669,34 @@ namespace tgui
{
auto node = Widget::save(renderers);
if (getTabsCount() > 0)
if (m_tabs.size() > 0)
{
bool allTabsVisible = true;
bool allTabsEnabled = true;
std::string tabList = "[" + Serializer::serialize(getText(0));
for (std::size_t i = 1; i < getTabsCount(); ++i)
std::string tabVisibleList = "[" + Serializer::serialize(getTabVisible(0));
std::string tabEnabledList = "[" + Serializer::serialize(getTabEnabled(0));
for (std::size_t i = 1; i < m_tabs.size(); ++i)
{
tabList += ", " + Serializer::serialize(getText(i));
tabVisibleList += ", " + Serializer::serialize(getTabVisible(i));
tabEnabledList += ", " + Serializer::serialize(getTabEnabled(i));
if (!getTabVisible(i))
allTabsVisible = false;
if (!getTabEnabled(i))
allTabsEnabled = false;
}
tabList += "]";
tabVisibleList += "]";
tabEnabledList += "]";
node->propertyValuePairs["Tabs"] = make_unique<DataIO::ValueNode>(tabList);
if (!allTabsVisible)
node->propertyValuePairs["TabsVisible"] = make_unique<DataIO::ValueNode>(tabVisibleList);
if (!allTabsEnabled)
node->propertyValuePairs["TabsEnabled"] = make_unique<DataIO::ValueNode>(tabEnabledList);
}
if (getSelectedIndex() >= 0)
@ -625,6 +732,26 @@ namespace tgui
add(Deserializer::deserialize(ObjectConverter::Type::String, tabText).getString());
}
if (node->propertyValuePairs["tabsvisible"])
{
if (!node->propertyValuePairs["tabsvisible"]->listNode)
throw Exception{"Failed to parse 'TabsVisible' property, expected a list as value"};
const auto& values = node->propertyValuePairs["tabsvisible"]->valueList;
for (unsigned int i = 0; i < values.size(); ++i)
setTabVisible(i, Deserializer::deserialize(ObjectConverter::Type::Bool, values[i]).getBool());
}
if (node->propertyValuePairs["tabsenabled"])
{
if (!node->propertyValuePairs["tabsenabled"]->listNode)
throw Exception{"Failed to parse 'TabsEnabled' property, expected a list as value"};
const auto& values = node->propertyValuePairs["tabsenabled"]->valueList;
for (unsigned int i = 0; i < values.size(); ++i)
setTabEnabled(i, Deserializer::deserialize(ObjectConverter::Type::Bool, values[i]).getBool());
}
if (node->propertyValuePairs["maximumtabwidth"])
setMaximumTabWidth(tgui::stof(node->propertyValuePairs["maximumtabwidth"]->value));
if (node->propertyValuePairs["textsize"])
@ -639,21 +766,26 @@ namespace tgui
void Tabs::updateTextColors()
{
for (auto& tabText : m_tabTexts)
tabText.setColor(m_textColorCached);
for (auto& tab : m_tabs)
{
if ((!m_enabled || !tab.enabled) && m_textColorDisabledCached.isSet())
tab.text.setColor(m_textColorDisabledCached);
else
tab.text.setColor(m_textColorCached);
}
if (m_selectedTab >= 0)
{
if ((m_selectedTab == m_hoveringTab) && m_selectedTextColorHoverCached.isSet())
m_tabTexts[m_selectedTab].setColor(m_selectedTextColorHoverCached);
m_tabs[m_selectedTab].text.setColor(m_selectedTextColorHoverCached);
else if (m_selectedTextColorCached.isSet())
m_tabTexts[m_selectedTab].setColor(m_selectedTextColorCached);
m_tabs[m_selectedTab].text.setColor(m_selectedTextColorCached);
}
if ((m_hoveringTab >= 0) && (m_selectedTab != m_hoveringTab))
{
if (m_textColorHoverCached.isSet())
m_tabTexts[m_hoveringTab].setColor(m_textColorHoverCached);
m_tabs[m_hoveringTab].text.setColor(m_textColorHoverCached);
}
}
@ -672,67 +804,67 @@ namespace tgui
}
const float usableHeight = getSize().y - m_bordersCached.getTop() - m_bordersCached.getBottom();
for (unsigned int i = 0; i < m_tabTexts.size(); ++i)
for (unsigned int i = 0; i < m_tabs.size(); ++i)
{
if (!m_tabs[i].visible)
continue;
sf::RenderStates textStates = states;
// Draw the background of the tab
if (m_selectedTab == static_cast<int>(i))
if (m_spriteTab.isSet() && m_spriteSelectedTab.isSet())
{
if (m_spriteSelectedTab.isSet())
{
Sprite spriteSelectedTab = m_spriteSelectedTab;
spriteSelectedTab.setSize({m_tabWidth[i], usableHeight});
spriteSelectedTab.draw(target, states);
}
else // No texture was loaded
Sprite spriteTab;
if ((!m_enabled || !m_tabs[i].enabled) && m_spriteDisabledTab.isSet())
spriteTab = m_spriteDisabledTab;
else if (m_selectedTab == static_cast<int>(i))
spriteTab = m_spriteSelectedTab;
else
spriteTab = m_spriteTab;
spriteTab.setSize({m_tabs[i].width, usableHeight});
spriteTab.draw(target, states);
}
else // No texture was loaded
{
if ((!m_enabled || !m_tabs[i].enabled) && m_backgroundColorDisabledCached.isSet())
drawRectangleShape(target, states, {m_tabs[i].width, usableHeight}, m_backgroundColorDisabledCached);
else if (m_selectedTab == static_cast<int>(i))
{
if ((m_hoveringTab == static_cast<int>(i)) && m_selectedBackgroundColorHoverCached.isSet())
drawRectangleShape(target, states, {m_tabWidth[i], usableHeight}, m_selectedBackgroundColorHoverCached);
drawRectangleShape(target, states, {m_tabs[i].width, usableHeight}, m_selectedBackgroundColorHoverCached);
else
drawRectangleShape(target, states, {m_tabWidth[i], usableHeight}, m_selectedBackgroundColorCached);
}
}
else // This tab is not selected
{
if (m_spriteTab.isSet())
{
Sprite spriteTab = m_spriteTab;
spriteTab.setSize({m_tabWidth[i], usableHeight});
spriteTab.draw(target, states);
}
else // No texture was loaded
{
if ((m_hoveringTab == static_cast<int>(i)) && m_backgroundColorHoverCached.isSet())
drawRectangleShape(target, states, {m_tabWidth[i], usableHeight}, m_backgroundColorHoverCached);
else
drawRectangleShape(target, states, {m_tabWidth[i], usableHeight}, m_backgroundColorCached);
drawRectangleShape(target, states, {m_tabs[i].width, usableHeight}, m_selectedBackgroundColorCached);
}
else if ((m_hoveringTab == static_cast<int>(i)) && m_backgroundColorHoverCached.isSet())
drawRectangleShape(target, states, {m_tabs[i].width, usableHeight}, m_backgroundColorHoverCached);
else
drawRectangleShape(target, states, {m_tabs[i].width, usableHeight}, m_backgroundColorCached);
}
// Draw the borders between the tabs
states.transform.translate({m_tabWidth[i], 0});
if ((m_bordersCached != Borders{0}) && (i < m_tabWidth.size() - 1))
states.transform.translate({m_tabs[i].width, 0});
if ((m_bordersCached != Borders{0}) && (i < m_tabs.size() - 1))
{
drawRectangleShape(target, states, {(m_bordersCached.getLeft() + m_bordersCached.getRight()) / 2.f, usableHeight}, m_borderColorCached);
states.transform.translate({(m_bordersCached.getLeft() + m_bordersCached.getRight()) / 2.f, 0});
}
// Apply clipping if required for the text in this tab
const float usableWidth = m_tabWidth[i] - (2 * m_distanceToSideCached);
const float usableWidth = m_tabs[i].width - (2 * m_distanceToSideCached);
#ifdef TGUI_USE_CPP17
std::optional<Clipping> clipping;
if (m_tabTexts[i].getSize().x > usableWidth)
if (m_tabs[i].text.getSize().x > usableWidth)
clipping.emplace(target, textStates, Vector2f{m_distanceToSideCached, 0}, Vector2f{usableWidth, usableHeight});
#else
std::unique_ptr<Clipping> clipping;
if (m_tabTexts[i].getSize().x > usableWidth)
if (m_tabs[i].text.getSize().x > usableWidth)
clipping = make_unique<Clipping>(target, textStates, Vector2f{m_distanceToSideCached, 0}, Vector2f{usableWidth, usableHeight});
#endif
// Draw the text
textStates.transform.translate({m_distanceToSideCached + ((usableWidth - m_tabTexts[i].getSize().x) / 2.f), ((usableHeight - m_tabTexts[i].getSize().y) / 2.f)});
m_tabTexts[i].draw(target, textStates);
textStates.transform.translate({m_distanceToSideCached + ((usableWidth - m_tabs[i].text.getSize().x) / 2.f), ((usableHeight - m_tabs[i].text.getSize().y) / 2.f)});
m_tabs[i].text.draw(target, textStates);
}
}

View File

@ -61,6 +61,44 @@ TEST_CASE("[Tabs]")
REQUIRE(tabs->getFullSize() == tabs->getSize());
}
SECTION("TabVisible")
{
REQUIRE(!tabs->getTabVisible(0)); // Tab that doesn't exist can't be visible
tabs->add("0");
tabs->add("1");
REQUIRE(tabs->getTabVisible(0));
REQUIRE(tabs->getTabVisible(1));
REQUIRE(!tabs->getTabVisible(2)); // Tab that doesn't exist can't be visible
tabs->setTabVisible(0, false);
tabs->setTabVisible(2, true); // Showing tab that doesn't exist has no effect
REQUIRE(!tabs->getTabVisible(0));
REQUIRE(tabs->getTabVisible(1));
REQUIRE(!tabs->getTabVisible(2)); // Tab that doesn't exist can't be visible
}
SECTION("TabEnabled")
{
REQUIRE(!tabs->getTabEnabled(0)); // Tab that doesn't exist can't be enabled
tabs->add("0");
tabs->add("1");
REQUIRE(tabs->getTabEnabled(0));
REQUIRE(tabs->getTabEnabled(1));
REQUIRE(!tabs->getTabEnabled(2)); // Tab that doesn't exist can't be enabled
tabs->setTabEnabled(0, false);
tabs->setTabEnabled(2, true); // Enabling tab that doesn't exist has no effect
REQUIRE(!tabs->getTabEnabled(0));
REQUIRE(tabs->getTabEnabled(1));
REQUIRE(!tabs->getTabEnabled(2)); // Tab that doesn't exist can't be enabled
}
/// TODO: Test the functions in the Tab class
testWidgetRenderer(tabs->getRenderer());
@ -147,11 +185,14 @@ TEST_CASE("[Tabs]")
{
tabs->add("1");
tabs->add("2");
tabs->add("invisible");
tabs->add("3");
tabs->select("2");
tabs->setTextSize(20);
tabs->setTabHeight(26);
tabs->setMaximumTabWidth(100);
tabs->setTabVisible(2, false);
tabs->setTabEnabled(3, false);
testSavingWidget("Tabs", tabs);
}