Let ProgressBar use the new renderer system

0.8
Bruno Van de Velde 2016-07-23 19:32:13 +02:00
parent fa8ec3804f
commit a3c0856d6e
19 changed files with 678 additions and 1067 deletions

View File

@ -42,14 +42,15 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Creates a clipping object which will define a clipping region until the object is destroyed
///
/// @param target Target to which we are drawing
/// @param topLeft Position of the top left corner of the clipping area relative to the view
/// @param bottomRight Position of the bottom right corner of the clipping area relative to the view
/// @param target Target to which we are drawing
/// @param topLeft Position of the top left corner of the clipping area relative to the view
/// @param size Size of the clipping area relative to the view
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Clipping(const sf::RenderTarget& target, sf::Vector2f topLeft, sf::Vector2f bottomRight)
Clipping(const sf::RenderTarget& target, const sf::RenderStates& states, sf::Vector2f topLeft, sf::Vector2f size)
{
const sf::View& view = target.getView();
sf::Vector2f bottomRight = topLeft + size;
// Calculate the scale factor of the view
float scaleViewX = target.getSize().x / view.getSize().x;
@ -61,6 +62,9 @@ namespace tgui
sf::Vector2f bottomRightPosition = {(bottomRight.x - view.getCenter().x + (view.getSize().x / 2.f)) * view.getViewport().width + (view.getSize().x * view.getViewport().left),
(bottomRight.y - view.getCenter().y + (view.getSize().y / 2.f)) * view.getViewport().height + (view.getSize().y * view.getViewport().top)};
topLeftPosition = states.transform.transformPoint(topLeftPosition);
bottomRightPosition = states.transform.transformPoint(bottomRightPosition);
// Get the old clipping area
glGetIntegerv(GL_SCISSOR_BOX, m_scissor);

View File

@ -0,0 +1,220 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2016 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.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef TGUI_PROGRESS_BAR_RENDERER_HPP
#define TGUI_PROGRESS_BAR_RENDERER_HPP
#include <TGUI/Renderers/WidgetRenderer.hpp>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
struct TGUI_API ProgressBarRenderer : public WidgetRenderer
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the size of the borders
///
/// @param borders Size of the borders
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBorders(const Borders& borders);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the size of the borders
///
/// @return border size
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Borders getBorders() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text that is optionally displayed on top of the progress bar
///
/// @param color The new text color
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColor(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the text that is optionally displayed on top of the progress bar
///
/// @return Text color
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getTextColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text that is on top of the filled part of the progress bar
///
/// @param color The new text color that is displayed on top of the filled part
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColorFilled(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the text that is on top of the filled part of the progress bar
///
/// @return Text color that is displayed on top of the filled part
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getTextColorFilled() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background color of the progress bar
///
/// @param color The new background color
///
/// This is the color that you see in the part of the progress bar that is not filled.
///
/// Note that this color is ignored when you set a background image.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBackgroundColor(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the background color of the progress bar
///
/// @return Background color
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getBackgroundColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the fill color of the progress bar
///
/// @param color The new fill color
///
/// This is the color that is used to fill the progress bar and is drawn on top of the background color.
///
/// Note that this color is ignored when you set an fill image.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setFillColor(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the fill color of the progress bar
///
/// @return Fill color
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getFillColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the border color
///
/// @param color The color that is used for the borders that are optionally drawn around the progress bar
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBorderColor(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the border color
///
/// @return Border color
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getBorderColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background image of the progress bar
///
/// @param texture The new background texture
///
/// When this image is set then the background color property will be ignored.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureBackground(const Texture& texture);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the background image
///
/// @return Background texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture& getTextureBackground() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the fill image of the progress bar
///
/// @param texture The new fill texture
///
/// When this image is set then the fill color property will be ignored.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureFill(const Texture& texture);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the fill image
///
/// @return Fill texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture& getTextureFill() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the text style
///
/// @param style New text style
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextStyle(TextStyle style);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns text style
///
/// @return Style of the text
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TextStyle getTextStyle() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif // TGUI_PROGRESS_BAR_RENDERER_HPP

View File

@ -56,8 +56,8 @@
#include <TGUI/Widgets/MenuBar.hpp>
#include <TGUI/Widgets/MessageBox.hpp>*/
#include <TGUI/Widgets/Panel.hpp>
#include <TGUI/Widgets/Picture.hpp>/**
#include <TGUI/Widgets/ProgressBar.hpp>*/
#include <TGUI/Widgets/Picture.hpp>
#include <TGUI/Widgets/ProgressBar.hpp>
#include <TGUI/Widgets/RadioButton.hpp>/**
#include <TGUI/Widgets/Scrollbar.hpp>
#include <TGUI/Widgets/Slider.hpp>

View File

@ -27,14 +27,13 @@
#define TGUI_PROGRESS_BAR_HPP
#include <TGUI/Renderers/ProgressBarRenderer.hpp>
#include <TGUI/Widgets/Label.hpp>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
class ProgressBarRenderer;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Progress bar widget
///
@ -96,28 +95,12 @@ namespace tgui
/// @return Reference to the renderer
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<ProgressBarRenderer> getRenderer() const
ProgressBarRenderer* getRenderer() const
{
return std::static_pointer_cast<ProgressBarRenderer>(m_renderer);
return aurora::downcast<ProgressBarRenderer*>(m_renderer.get());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the position of the widget
///
/// This function completely overwrites the previous position.
/// See the move function to apply an offset based on the previous position instead.
/// The default position of a transformable widget is (0, 0).
///
/// @param position New position
///
/// @see move, getPosition
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void setPosition(const Layout2d& position) override;
using Transformable::setPosition;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the size of the progress bar
///
@ -128,28 +111,6 @@ namespace tgui
using Transformable::setSize;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the full size of the progress bar
///
/// The size returned by this function includes the borders.
///
/// @return Full size of the progress bar
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual sf::Vector2f getFullSize() const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the font of the text in the widget
///
/// @param font The new font
///
/// When you don't call this function then the font from the parent widget will be used.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void setFont(const Font& font) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets a minimum value
///
@ -161,6 +122,15 @@ namespace tgui
void setMinimum(unsigned int minimum);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the minimum value
///
/// @return The current minimum value
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int getMinimum() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets a maximum value
///
@ -172,6 +142,15 @@ namespace tgui
void setMaximum(unsigned int maximum);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the maximum value
///
/// @return The current maximum value
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int getMaximum() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the current value
///
@ -183,40 +162,13 @@ namespace tgui
void setValue(unsigned int value);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the minimum value
///
/// @return The current minimum value
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int getMinimum() const
{
return m_minimum;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the maximum value
///
/// @return The current maximum value
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int getMaximum() const
{
return m_maximum;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the current value
///
/// @return The current value
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int getValue() const
{
return m_value;
}
unsigned int getValue() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -247,10 +199,7 @@ namespace tgui
/// @return Text that is drawn on top of the progress bar
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sf::String getText() const
{
return m_textBack.getText();
}
sf::String getText() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -269,10 +218,7 @@ namespace tgui
/// @return The current text size
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int getTextSize() const
{
return m_textBack.getTextSize();
}
unsigned int getTextSize() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -294,48 +240,32 @@ namespace tgui
/// By default the progress bar is filled from left to right.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FillDirection getFillDirection()
{
return m_fillDirection;
}
FillDirection getFillDirection() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the opacity of the widget
protected:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Function called when one of the properties of the renderer is changed
///
/// @param opacity The opacity of the widget. 0 means completely transparent, while 1 (default) means fully opaque
/// @param property Lowercase name of the property that was changed
/// @param value New value of the property
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void setOpacity(float opacity) override;
virtual void rendererChanged(const std::string& property, ObjectConverter& value) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the distance between the position where the widget is drawn and where the widget is placed
///
/// This is basically the width and height of the optional borders drawn around widgets.
///
/// @return Offset of the widget
///
// Returns the size without the borders
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual sf::Vector2f getWidgetOffset() const override;
sf::Vector2f getInnerSize() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected:
// Draws the widget on the render target.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Reloads the widget
///
/// @param primary Primary parameter for the loader
/// @param secondary Secondary parameter for the loader
/// @param force Try to only change the looks of the widget and not alter the widget itself when false
///
/// @throw Exception when the connected theme could not create the widget
///
/// When primary is an empty string the built-in white theme will be used.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void reload(const std::string& primary = "", const std::string& secondary = "", bool force = false) override;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -347,17 +277,14 @@ namespace tgui
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// When the value changes, or when the minimum/maximum limits change then a smaller of bigger piece of the front image
// must be drawn. This function is called to calculate the size of the piece to draw.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void recalculateSize();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Draws the widget on the render target.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
void recalculateFillSize();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -371,218 +298,13 @@ namespace tgui
Label m_textFront;
unsigned int m_textSize = 0;
sf::FloatRect m_backRect;
sf::FloatRect m_frontRect;
FillDirection m_fillDirection = FillDirection::LeftToRight;
friend class ProgressBarRenderer;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class TGUI_API ProgressBarRenderer : public WidgetRenderer, public WidgetBorders
{
public:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor
///
/// @param progressBar The progress bar that is connected to the renderer
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ProgressBarRenderer(ProgressBar* progressBar) : m_progressBar{progressBar} {}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes a property of the renderer
///
/// @param property The property that you would like to change
/// @param value The new serialized value that you like to assign to the property
///
/// @throw Exception when deserialization fails or when the widget does not have this property
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void setProperty(std::string property, const std::string& value) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes a property of the renderer
///
/// @param property The property that you would like to change
/// @param value The new value that you like to assign to the property.
/// The ObjectConverter is implicitly constructed from the possible value types
///
/// @throw Exception for unknown properties or when value was of a wrong type
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual void setProperty(std::string property, ObjectConverter&& value) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Retrieves the value of a certain property
///
/// @param property The property that you would like to retrieve
///
/// @return The value inside a ObjectConverter object which you can extract with the correct get function or
/// an ObjectConverter object with type ObjectConverter::Type::None when the property did not exist.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual ObjectConverter getProperty(std::string property) const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Gets a map with all properties and their values
///
/// @return Property-value pairs of the renderer
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual std::map<std::string, ObjectConverter> getPropertyValuePairs() const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the font of the text
///
/// When you don't call this function then the global font will be use.
/// This global font can be changed with the setGlobalFont function from the parent.
///
/// @param font The new font
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextFont(std::shared_ptr<sf::Font> font);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text that is optionally displayed on top of the progress bar
///
/// @param color The new text color
///
/// This changes both the back and front text colors.
///
/// @see setTextColorBack
/// @see setTextColorFront
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColor(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text that is optionally displayed on top of the progress bar
///
/// @param color The new text color that is displayed on top of the background color/image
///
/// This color is displayed on top of the unfilled part. The front text color will be used on top of the filled part.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColorBack(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text that is optionally displayed on top of the progress bar
///
/// @param color The new text color that is displayed on top of the foreground color/image
///
/// This color is displayed on top of the filled part. The back text color will be used on top of the unfilled part.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColorFront(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background color of the progress bar
///
/// @param color The new background color
///
/// This is the color that you see in the part of the progress bar that is not filled.
///
/// Note that this color is ignored when you set an image as background.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBackgroundColor(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the foreground color of the progress bar
///
/// @param color The new foreground color
///
/// This is the color that is used to fill the progress bar and is drawn on top of the background color.
///
/// Note that this color is ignored when you set an image as foreground.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setForegroundColor(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the border color
///
/// @param color The color that is used for the borders that are optionally drawn around the progress bar
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBorderColor(Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background image of the progress bar
///
/// @param texture The new background texture
///
/// When this image and the front image are set, the background and foreground color properties will be ignored.
/// Pass an empty string to unset the image, in this case the color properties will be used again.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBackTexture(const Texture& texture);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the foreground image of the progress bar
///
/// @param texture The new foreground texture
///
/// When this image and the back image are set, the background and foreground color properties will be ignored.
/// Pass an empty string to unset the image, in this case the color properties will be used again.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setFrontTexture(const Texture& texture);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Draws the widget on the render target.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Makes a copy of the renderer
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual std::shared_ptr<WidgetRenderer> clone(Widget* widget) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected:
ProgressBar* m_progressBar;
Texture m_textureBack;
Texture m_textureFront;
sf::Color m_textColorFront;
sf::Color m_textColorBack;
sf::Color m_backgroundColor;
sf::Color m_foregroundColor;
sf::Color m_borderColor;
friend class ProgressBar;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

View File

@ -29,6 +29,7 @@ set(TGUI_SRC
Renderers/EditBoxRenderer.cpp
Renderers/LabelRenderer.cpp
Renderers/PanelRenderer.cpp
Renderers/ProgressBarRenderer.cpp
Renderers/RadioButtonRenderer.cpp
Renderers/WidgetRenderer.cpp
Widgets/Button.cpp
@ -47,7 +48,7 @@ set(TGUI_SRC
#Widgets/MessageBox.cpp
Widgets/Panel.cpp
Widgets/Picture.cpp
#Widgets/ProgressBar.cpp
Widgets/ProgressBar.cpp
Widgets/RadioButton.cpp
#Widgets/Scrollbar.cpp
#Widgets/Slider.cpp

View File

@ -36,8 +36,8 @@
#include <TGUI/Widgets/Label.hpp>/**
#include <TGUI/Widgets/ListBox.hpp>*/
#include <TGUI/Widgets/Panel.hpp>
#include <TGUI/Widgets/Picture.hpp>/**
#include <TGUI/Widgets/ProgressBar.hpp>*/
#include <TGUI/Widgets/Picture.hpp>
#include <TGUI/Widgets/ProgressBar.hpp>
#include <TGUI/Widgets/RadioButton.hpp>/**
#include <TGUI/Widgets/Scrollbar.hpp>
#include <TGUI/Widgets/Slider.hpp>
@ -638,7 +638,7 @@ namespace tgui
return picture;
}
/**
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TGUI_API Widget::Ptr loadProgressBar(std::shared_ptr<DataIO::Node> node, Widget::Ptr widget = nullptr)
@ -680,7 +680,7 @@ namespace tgui
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
*/
TGUI_API Widget::Ptr loadRadioButton(std::shared_ptr<DataIO::Node> node, Widget::Ptr widget = nullptr)
{
RadioButton::Ptr radioButton;
@ -864,8 +864,8 @@ namespace tgui
{"listbox", std::bind(loadListBox, std::placeholders::_1, std::shared_ptr<ListBox>{})},*/
{"label", std::bind(loadLabel, std::placeholders::_1, std::shared_ptr<Label>{})},
{"panel", std::bind(loadPanel, std::placeholders::_1, std::shared_ptr<Panel>{})},
{"picture", std::bind(loadPicture, std::placeholders::_1, std::shared_ptr<Picture>{})},/**
{"progressbar", std::bind(loadProgressBar, std::placeholders::_1, std::shared_ptr<ProgressBar>{})},*/
{"picture", std::bind(loadPicture, std::placeholders::_1, std::shared_ptr<Picture>{})},
{"progressbar", std::bind(loadProgressBar, std::placeholders::_1, std::shared_ptr<ProgressBar>{})},
{"radiobutton", std::bind(loadRadioButton, std::placeholders::_1, std::shared_ptr<RadioButton>{})}/**,
{"scrollbar", std::bind(loadScrollbar, std::placeholders::_1, std::shared_ptr<Scrollbar>{})},
{"slider", std::bind(loadSlider, std::placeholders::_1, std::shared_ptr<Slider>{})},

View File

@ -33,8 +33,8 @@
#include <TGUI/Widgets/Knob.hpp>*/
#include <TGUI/Widgets/Label.hpp>/**
#include <TGUI/Widgets/ListBox.hpp>*/
#include <TGUI/Widgets/Picture.hpp>/**
#include <TGUI/Widgets/ProgressBar.hpp>*/
#include <TGUI/Widgets/Picture.hpp>
#include <TGUI/Widgets/ProgressBar.hpp>
#include <TGUI/Widgets/RadioButton.hpp>/**
#include <TGUI/Widgets/Scrollbar.hpp>
#include <TGUI/Widgets/Slider.hpp>
@ -376,7 +376,7 @@ namespace tgui
return node;
}
/**
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TGUI_API std::shared_ptr<DataIO::Node> saveProgressBar(ProgressBar::Ptr progressBar)
@ -404,7 +404,7 @@ namespace tgui
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
*/
TGUI_API std::shared_ptr<DataIO::Node> saveRadioButton(RadioButton::Ptr radioButton)
{
auto node = saveWidget(radioButton);
@ -541,8 +541,8 @@ namespace tgui
{"label", saveLabel},/**
{"listbox", saveListBox},*/
{"panel", saveContainer},
{"picture", savePicture},/**
{"progressbar", saveProgressBar},*/
{"picture", savePicture},
{"progressbar", saveProgressBar},
{"radiobutton", saveRadioButton}/**,
{"scrollbar", saveScrollbar},
{"slider", saveSlider},

View File

@ -0,0 +1,46 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2016 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 <TGUI/Renderers/ProgressBarRenderer.hpp>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
TGUI_RENDERER_PROPERTY_OUTLINE(ProgressBarRenderer, Borders)
TGUI_RENDERER_PROPERTY_COLOR(ProgressBarRenderer, TextColor, sf::Color::Black)
TGUI_RENDERER_PROPERTY_COLOR(ProgressBarRenderer, TextColorFilled, {})
TGUI_RENDERER_PROPERTY_COLOR(ProgressBarRenderer, BackgroundColor, sf::Color::White)
TGUI_RENDERER_PROPERTY_COLOR(ProgressBarRenderer, FillColor, Color(0, 110, 255))
TGUI_RENDERER_PROPERTY_COLOR(ProgressBarRenderer, BorderColor, sf::Color::Black)
TGUI_RENDERER_PROPERTY_TEXTURE(ProgressBarRenderer, TextureBackground)
TGUI_RENDERER_PROPERTY_TEXTURE(ProgressBarRenderer, TextureFill)
TGUI_RENDERER_PROPERTY_TEXT_STYLE(ProgressBarRenderer, TextStyle, sf::Text::Regular)
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -522,23 +522,7 @@ namespace tgui
// Apply clipping when needed
std::unique_ptr<Clipping> clipping;
if (m_textureRect != sf::FloatRect{0, 0, 0, 0})
{
///TODO: Fix clipping
/// transformPoint should probably be moved to Clipping class and getAbsolutePosition() would no longer be needed here
/// Lots of testing will be required after this change
/*
clipping = std::make_unique<Clipping>(target,
sf::Vector2f{getAbsolutePosition().x + padding.left, getAbsolutePosition().y + padding.top},
sf::Vector2f{getAbsolutePosition().x + getSize().x - padding.right, getAbsolutePosition().y + getSize().y - padding.bottom}
);
*/
/*
sf::Vector2f topLeftPosition = states.transform.transformPoint(((m_textureRect.left - view.getCenter().x + (view.getSize().x / 2.f)) * view.getViewport().width) + (view.getSize().x * view.getViewport().left),
((m_textureRect.top - view.getCenter().y + (view.getSize().y / 2.f)) * view.getViewport().height) + (view.getSize().y * view.getViewport().top));
sf::Vector2f bottomRightPosition = states.transform.transformPoint((m_textureRect.left + m_textureRect.width - view.getCenter().x + (view.getSize().x / 2.f)) * view.getViewport().width + (view.getSize().x * view.getViewport().left),
(m_textureRect.top + m_textureRect.height - view.getCenter().y + (view.getSize().y / 2.f)) * view.getViewport().height + (view.getSize().y * view.getViewport().top));
*/
}
clipping = std::make_unique<Clipping>(target, states, sf::Vector2f{m_textureRect.left, m_textureRect.top}, sf::Vector2f{m_textureRect.width, m_textureRect.height});
states.texture = &m_data->texture;
target.draw(m_vertices.data(), m_vertices.size(), sf::PrimitiveType::TrianglesStrip, states);

View File

@ -249,6 +249,7 @@ namespace tgui
else if ((property == "texture") || (property == "texturehover") || (property == "texturedown") || (property == "texturedisabled") || (property == "texturefocused"))
{
value.getTexture().setSize(getInnerSize());
value.getTexture().setOpacity(getRenderer()->getOpacity());
if (property == "texturefocused")
m_allowFocus = value.getTexture().isLoaded();
@ -301,14 +302,10 @@ namespace tgui
if (borders != Borders{0})
{
drawBorders(target, states, borders, getSize(), getRenderer()->getBorderColor());
// Don't try to draw the text when there is no space left for it
if ((getSize().x <= borders.left + borders.right) || (getSize().y <= borders.top + borders.bottom))
return;
states.transform.translate({borders.left, borders.top});
}
// Check if there is a background texture
states.transform.translate({borders.left, borders.top});
if (getRenderer()->getTexture().isLoaded())
{
if (!m_enabled && getRenderer()->getTextureDisabled().isLoaded())

View File

@ -23,7 +23,6 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <TGUI/Container.hpp>
#include <TGUI/Widgets/CheckBox.hpp>
#include <TGUI/Clipping.hpp>
@ -203,10 +202,7 @@ namespace tgui
if (m_checked)
{
// Set the clipping for all draw calls that happen until this clipping object goes out of scope
Clipping clipping{target,
{getAbsolutePosition().x + borders.left, getAbsolutePosition().y + borders.top},
{getAbsolutePosition().x + getSize().x - borders.right, getAbsolutePosition().y + getSize().y - borders.bottom}
};
Clipping clipping{target, states, {borders.left, borders.top}, getInnerSize()};
sf::Vector2f size = getInnerSize();

View File

@ -1278,13 +1278,9 @@ namespace tgui
else
drawBorders(target, states, borders, getSize(), getRenderer()->getBorderColor());
// Don't try to draw the text when there is no space left for it
if ((getSize().x <= borders.left + borders.right) || (getSize().y <= borders.top + borders.bottom))
return;
states.transform.translate({borders.left, borders.top});
}
states.transform.translate({borders.left, borders.top});
// Draw the background
if (getRenderer()->getTexture().isLoaded())
{
@ -1314,10 +1310,7 @@ namespace tgui
// Set the clipping for all draw calls that happen until this clipping object goes out of scope
Padding padding = getRenderer()->getPadding();
Clipping clipping{target,
{getAbsolutePosition().x + padding.left, getAbsolutePosition().y + padding.top},
{getAbsolutePosition().x + getSize().x - padding.right, getAbsolutePosition().y + getSize().y - padding.bottom}
};
Clipping clipping{target, states, {padding.left, padding.top}, {getSize().x - padding.left - padding.right, getSize().y - padding.top - padding.bottom}};
if ((m_textBeforeSelection.getString() != "") || (m_textSelection.getString() != ""))
{

View File

@ -23,7 +23,6 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <TGUI/Container.hpp>
#include <TGUI/Widgets/Label.hpp>
#include <TGUI/Clipping.hpp>
@ -251,30 +250,29 @@ namespace tgui
{
states.transform.translate(std::round(getPosition().x), std::round(getPosition().y));
// Draw the background
if (getRenderer()->getBackgroundColor() != sf::Color::Transparent)
drawRectangleShape(target, states, getSize(), getRenderer()->getBackgroundColor());
Borders borders = getRenderer()->getBorders();
sf::Vector2f innerSize = {getSize().x - borders.left - borders.right, getSize().y - borders.top - borders.bottom};
// Draw the borders
Borders borders = getRenderer()->getBorders();
if (borders != Borders{0})
{
drawBorders(target, states, borders, getSize(), getRenderer()->getBorderColor());
// Don't try to draw the text when there is no space left for it
if ((getSize().x <= borders.left + borders.right) || (getSize().y <= borders.top + borders.bottom))
return;
states.transform.translate({borders.left, borders.top});
}
// Draw the background
if (getRenderer()->getBackgroundColor() != sf::Color::Transparent)
drawRectangleShape(target, states, innerSize, getRenderer()->getBackgroundColor());
// Apply clipping when needed
std::unique_ptr<Clipping> clipping;
if (!m_autoSize)
{
Padding padding = getRenderer()->getPadding();
clipping = std::make_unique<Clipping>(target,
sf::Vector2f{getAbsolutePosition().x + padding.left, getAbsolutePosition().y + padding.top},
sf::Vector2f{getAbsolutePosition().x + getSize().x - padding.right, getAbsolutePosition().y + getSize().y - padding.bottom}
);
innerSize.x -= padding.left + padding.right;
innerSize.y -= padding.top + padding.bottom;
clipping = std::make_unique<Clipping>(target, states, sf::Vector2f{padding.left, padding.top}, innerSize);
}
// Draw the text
@ -398,24 +396,23 @@ namespace tgui
// There is always at least one line
lineCount = std::max(1u, lineCount);
Outline outline = getRenderer()->getPadding() + getRenderer()->getBorders();
if (m_autoSize)
{
Borders borders = getRenderer()->getPadding() + getRenderer()->getBorders();
m_size = {std::max(calculatedLabelWidth, maxWidth) + borders.left + borders.right,
(lineCount * font->getLineSpacing(m_textSize)) + borders.top + borders.bottom};
m_size = {std::max(calculatedLabelWidth, maxWidth) + outline.left + outline.right,
(lineCount * font->getLineSpacing(m_textSize)) + outline.top + outline.bottom};
}
// Update the line positions
{
Borders borders = getRenderer()->getPadding() + getRenderer()->getBorders();
if ((getSize().x <= borders.left + borders.right) || (getSize().y <= borders.top + borders.bottom))
if ((getSize().x <= outline.left + outline.right) || (getSize().y <= outline.top + outline.bottom))
return;
sf::Vector2f pos{borders.left, borders.top - getTextVerticalCorrection(font, m_textSize, m_textStyle)};
sf::Vector2f pos{getRenderer()->getBorders().left, getRenderer()->getBorders().top - getTextVerticalCorrection(font, m_textSize, m_textStyle)};
if (m_verticalAlignment != VerticalAlignment::Top)
{
float totalHeight = getSize().y - borders.top - borders.bottom;
float totalHeight = getSize().y - outline.top - outline.bottom;
float totalTextHeight = m_lines.size() * font->getLineSpacing(m_textSize);
if (m_verticalAlignment == VerticalAlignment::Center)
@ -434,7 +431,7 @@ namespace tgui
}
else // Center or Right alignment
{
float totalWidth = getSize().x - borders.left - borders.right;
float totalWidth = getSize().x - outline.left - outline.right;
for (auto& line : m_lines)
{

View File

@ -134,24 +134,18 @@ namespace tgui
if (borders != Borders{0})
{
drawBorders(target, states, borders, getSize(), getRenderer()->getBorderColor());
// Don't try to draw the text when there is no space left for it
if ((getSize().x <= borders.left + borders.right) || (getSize().y <= borders.top + borders.bottom))
return;
states.transform.translate({borders.left, borders.top});
}
// Set the clipping for all draw calls that happen until this clipping object goes out of scope
Clipping clipping{target,
{getAbsolutePosition().x + borders.left, getAbsolutePosition().y + borders.top},
{getAbsolutePosition().x + getSize().x - borders.right, getAbsolutePosition().y + getSize().y - borders.bottom}
};
sf::Vector2f innerSize = {getSize().x - borders.left - borders.right, getSize().y - borders.top - borders.bottom};
Clipping clipping{target, states, {borders.left, borders.top}, innerSize};
// Draw the background
if (getRenderer()->getBackgroundColor() != sf::Color::Transparent)
drawRectangleShape(target, states, getSize(), getRenderer()->getBackgroundColor());
drawRectangleShape(target, states, innerSize, getRenderer()->getBackgroundColor());
// Draw the child widgets
states.transform.translate({borders.left, borders.top});
drawWidgetContainer(&target, states);
}

View File

@ -23,11 +23,9 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <TGUI/Container.hpp>
#include <TGUI/Widgets/ProgressBar.hpp>
#include <TGUI/Loading/Theme.hpp>
#include <TGUI/Clipping.hpp>
#include <SFML/OpenGL.hpp>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -38,12 +36,20 @@ namespace tgui
ProgressBar::ProgressBar()
{
m_callback.widgetType = "ProgressBar";
m_type = "ProgressBar";
addSignal<int>("ValueChanged");
addSignal<int>("Full");
m_renderer = std::make_shared<ProgressBarRenderer>(this);
reload();
m_renderer = aurora::makeCopied<ProgressBarRenderer>();
setRenderer(m_renderer->getData());
getRenderer()->setBorders({2});
getRenderer()->setTextColor(sf::Color::Black);
getRenderer()->setTextColorFilled(sf::Color::White);
getRenderer()->setBackgroundColor({245, 245, 245});
getRenderer()->setFillColor({0, 110, 255});
getRenderer()->setBorderColor(sf::Color::Black);
setSize(160, 20);
}
@ -60,60 +66,15 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBar::setPosition(const Layout2d& position)
{
Widget::setPosition(position);
getRenderer()->m_textureBack.setPosition(getPosition());
getRenderer()->m_textureFront.setPosition(getRenderer()->m_textureBack.getPosition()
+ ((getRenderer()->m_textureBack.getSize() - getRenderer()->m_textureFront.getSize()) / 2.0f));
m_textBack.setPosition(getPosition().x + (getSize().x - m_textBack.getSize().x) / 2.0f,
getPosition().y + (getSize().y - m_textBack.getSize().y) / 2.0f);
m_textFront.setPosition(m_textBack.getPosition());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBar::setSize(const Layout2d& size)
{
Widget::setSize(size);
if (getRenderer()->m_textureBack.isLoaded() && getRenderer()->m_textureFront.isLoaded())
{
getRenderer()->m_textureBack.setSize(getSize());
sf::Vector2f frontSize;
switch (getRenderer()->m_textureBack.getScalingType())
{
case Texture::ScalingType::Normal:
frontSize.x = getRenderer()->m_textureFront.getImageSize().x * getSize().x / getRenderer()->m_textureBack.getImageSize().x;
frontSize.y = getRenderer()->m_textureFront.getImageSize().y * getSize().y / getRenderer()->m_textureBack.getImageSize().y;
break;
case Texture::ScalingType::Horizontal:
frontSize.x = getSize().x - ((getRenderer()->m_textureBack.getImageSize().x - getRenderer()->m_textureFront.getImageSize().x) * (getSize().y / getRenderer()->m_textureBack.getImageSize().y));
frontSize.y = getRenderer()->m_textureFront.getImageSize().y * getSize().y / getRenderer()->m_textureBack.getImageSize().y;
break;
case Texture::ScalingType::Vertical:
frontSize.x = getRenderer()->m_textureFront.getImageSize().x * getSize().x / getRenderer()->m_textureBack.getImageSize().x;
frontSize.y = getSize().y - ((getRenderer()->m_textureBack.getImageSize().y - getRenderer()->m_textureFront.getImageSize().y) * (getSize().x / getRenderer()->m_textureBack.getImageSize().x));
break;
case Texture::ScalingType::NineSlice:
frontSize.x = getSize().x - (getRenderer()->m_textureBack.getImageSize().x - getRenderer()->m_textureFront.getImageSize().x);
frontSize.y = getSize().y - (getRenderer()->m_textureBack.getImageSize().y - getRenderer()->m_textureFront.getImageSize().y);
break;
}
getRenderer()->m_textureFront.setSize(frontSize);
}
if (getRenderer()->getTextureBackground().isLoaded())
getRenderer()->getTextureBackground().setSize(getInnerSize());
// Recalculate the size of the front image
recalculateSize();
recalculateFillSize();
// Recalculate the text size
setText(getText());
@ -121,25 +82,6 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sf::Vector2f ProgressBar::getFullSize() const
{
return {getSize().x + getRenderer()->getBorders().left + getRenderer()->getBorders().right,
getSize().y + getRenderer()->getBorders().top + getRenderer()->getBorders().bottom};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBar::setFont(const Font& font)
{
Widget::setFont(font);
m_textBack.setFont(font);
m_textFront.setFont(font);
setText(getText());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBar::setMinimum(unsigned int minimum)
{
// Set the new minimum
@ -154,7 +96,14 @@ namespace tgui
m_value = m_minimum;
// Recalculate the size of the front image (the size of the part that will be drawn)
recalculateSize();
recalculateFillSize();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int ProgressBar::getMinimum() const
{
return m_minimum;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -173,7 +122,14 @@ namespace tgui
m_value = m_maximum;
// Recalculate the size of the front image (the size of the part that will be drawn)
recalculateSize();
recalculateFillSize();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int ProgressBar::getMaximum() const
{
return m_maximum;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -197,12 +153,19 @@ namespace tgui
sendSignal("Full", m_value);
// Recalculate the size of the front image (the size of the part that will be drawn)
recalculateSize();
recalculateFillSize();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int ProgressBar::getValue() const
{
return m_value;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int ProgressBar::incrementValue()
{
// When the value is still below the maximum then adjust it
@ -225,16 +188,16 @@ namespace tgui
if (m_textSize == 0)
{
unsigned int textSize;
if (getRenderer()->m_textureBack.isLoaded() && getRenderer()->m_textureFront.isLoaded())
textSize = findBestTextSize(getFont(), getRenderer()->m_textureFront.getSize().y * 0.85f);
if (getRenderer()->getTextureFill().isLoaded())
textSize = findBestTextSize(getRenderer()->getFont(), getRenderer()->getTextureFill().getSize().y * 0.85f);
else
textSize = findBestTextSize(getFont(), getSize().y * 0.85f);
textSize = findBestTextSize(getRenderer()->getFont(), getInnerSize().y * 0.85f);
m_textBack.setTextSize(textSize);
// Make the text smaller when it's too width
if (m_textBack.getSize().x > (getSize().x * 0.85f))
m_textBack.setTextSize(static_cast<unsigned int>(textSize * ((getSize().x * 0.85f) / m_textBack.getSize().x)));
if (m_textBack.getSize().x > (getInnerSize().x * 0.85f))
m_textBack.setTextSize(static_cast<unsigned int>(textSize * ((getInnerSize().x * 0.85f) / m_textBack.getSize().x)));
}
else // When the text has a fixed size
{
@ -243,9 +206,13 @@ namespace tgui
}
m_textFront.setTextSize(m_textBack.getTextSize());
}
// Reposition the text
updatePosition();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sf::String ProgressBar::getText() const
{
return m_textBack.getText();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -254,542 +221,241 @@ namespace tgui
{
// Change the text size
m_textSize = size;
// Call setText to reposition the text
setText(getText());
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int ProgressBar::getTextSize() const
{
return m_textBack.getTextSize();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBar::setFillDirection(FillDirection direction)
{
m_fillDirection = direction;
recalculateSize();
recalculateFillSize();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBar::setOpacity(float opacity)
ProgressBar::FillDirection ProgressBar::getFillDirection() const
{
ClickableWidget::setOpacity(opacity);
getRenderer()->m_textureBack.setColor({255, 255, 255, static_cast<sf::Uint8>(m_opacity * 255)});
getRenderer()->m_textureFront.setColor({255, 255, 255, static_cast<sf::Uint8>(m_opacity * 255)});
m_textBack.setTextColor(calcColorOpacity(getRenderer()->m_textColorBack, getOpacity()));
m_textFront.setTextColor(calcColorOpacity(getRenderer()->m_textColorFront, getOpacity()));
return m_fillDirection;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sf::Vector2f ProgressBar::getWidgetOffset() const
void ProgressBar::rendererChanged(const std::string& property, ObjectConverter& value)
{
return {getRenderer()->getBorders().left, getRenderer()->getBorders().top};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBar::recalculateSize()
{
sf::Vector2f size;
if (getRenderer()->m_textureBack.isLoaded() && getRenderer()->m_textureFront.isLoaded())
size = getRenderer()->m_textureFront.getSize();
else
size = getSize();
switch (getFillDirection())
if (property == "borders")
{
case FillDirection::LeftToRight:
m_frontRect = {0, 0, size.x * ((m_value - m_minimum) / static_cast<float>(m_maximum - m_minimum)), size.y};
break;
case FillDirection::RightToLeft:
m_frontRect = {0, 0, size.x * ((m_value - m_minimum) / static_cast<float>(m_maximum - m_minimum)), size.y};
m_frontRect.left = size.x - m_frontRect.width;
break;
case FillDirection::TopToBottom:
m_frontRect = {0, 0, size.x, size.y * ((m_value - m_minimum) / static_cast<float>(m_maximum - m_minimum))};
break;
case FillDirection::BottomToTop:
m_frontRect = {0, 0, size.x, size.y * ((m_value - m_minimum) / static_cast<float>(m_maximum - m_minimum))};
m_frontRect.top = size.y - m_frontRect.height;
break;
updateSize();
}
else if ((property == "textcolor") || (property == "textcolorfilled"))
{
m_textBack.getRenderer()->setTextColor(getRenderer()->getTextColor());
if (getRenderer()->m_textureBack.isLoaded() && getRenderer()->m_textureFront.isLoaded())
getRenderer()->m_textureFront.setTextureRect(m_frontRect);
if (getRenderer()->getTextColorFilled().isSet())
m_textFront.getRenderer()->setTextColor(getRenderer()->getTextColorFilled());
else
m_textFront.getRenderer()->setTextColor(getRenderer()->getTextColor());
}
else if (property == "texturebackground")
{
value.getTexture().setSize(getInnerSize());
value.getTexture().setOpacity(getRenderer()->getOpacity());
}
else if (property == "texturefill")
{
recalculateFillSize();
value.getTexture().setOpacity(getRenderer()->getOpacity());
}
else if (property == "textstyle")
{
m_textBack.getRenderer()->setTextStyle(value.getTextStyle());
m_textFront.getRenderer()->setTextStyle(value.getTextStyle());
}
else if (property == "opacity")
{
getRenderer()->getTextureBackground().setOpacity(value.getNumber());
getRenderer()->getTextureFill().setOpacity(value.getNumber());
m_textBack.getRenderer()->setOpacity(value.getNumber());
m_textFront.getRenderer()->setOpacity(value.getNumber());
}
else if (property == "font")
{
m_textBack.getRenderer()->setFont(value.getFont());
m_textFront.getRenderer()->setFont(value.getFont());
setText(getText());
}
else if ((property != "bordercolor") && (property != "backgroundcolor") && (property != "fillcolor"))
Widget::rendererChanged(property, value);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBar::reload(const std::string& primary, const std::string& secondary, bool force)
sf::Vector2f ProgressBar::getInnerSize() const
{
getRenderer()->setBorders({2, 2, 2, 2});
getRenderer()->setTextColorBack({0, 0, 0});
getRenderer()->setTextColorFront({255, 255, 255});
getRenderer()->setBackgroundColor({245, 245, 245});
getRenderer()->setForegroundColor({0, 110, 255});
getRenderer()->setBorderColor({0, 0, 0});
getRenderer()->setBackTexture({});
getRenderer()->setFrontTexture({});
if (m_theme && primary != "")
{
getRenderer()->setBorders({0, 0, 0, 0});
Widget::reload(primary, secondary, force);
if (force)
{
// Use the size of the images when images were loaded
if (getRenderer()->m_textureBack.isLoaded() && getRenderer()->m_textureFront.isLoaded())
{
setSize(getRenderer()->m_textureBack.getImageSize());
if (getSize().y >= 2 * getSize().x)
setFillDirection(FillDirection::BottomToTop);
}
}
// Calculate the size of the front image (the size of the part that will be drawn)
recalculateSize();
}
Borders borders = getRenderer()->getBorders();
return {getSize().x - borders.left - borders.right, getSize().y - borders.top - borders.bottom};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBar::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
getRenderer()->draw(target, states);
}
states.transform.translate(getPosition());
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setProperty(std::string property, const std::string& value)
{
property = toLower(property);
if (property == "borders")
setBorders(Deserializer::deserialize(ObjectConverter::Type::Borders, value).getBorders());
else if (property == "backgroundcolor")
setBackgroundColor(Deserializer::deserialize(ObjectConverter::Type::Color, value).getColor());
else if (property == "foregroundcolor")
setForegroundColor(Deserializer::deserialize(ObjectConverter::Type::Color, value).getColor());
else if (property == "textcolor")
setTextColor(Deserializer::deserialize(ObjectConverter::Type::Color, value).getColor());
else if (property == "textcolorback")
setTextColorBack(Deserializer::deserialize(ObjectConverter::Type::Color, value).getColor());
else if (property == "textcolorfront")
setTextColorFront(Deserializer::deserialize(ObjectConverter::Type::Color, value).getColor());
else if (property == "bordercolor")
setBorderColor(Deserializer::deserialize(ObjectConverter::Type::Color, value).getColor());
else if (property == "backimage")
setBackTexture(Deserializer::deserialize(ObjectConverter::Type::Texture, value).getTexture());
else if (property == "frontimage")
setFrontTexture(Deserializer::deserialize(ObjectConverter::Type::Texture, value).getTexture());
else
WidgetRenderer::setProperty(property, value);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setProperty(std::string property, ObjectConverter&& value)
{
property = toLower(property);
if (value.getType() == ObjectConverter::Type::Borders)
// Draw the borders
Borders borders = getRenderer()->getBorders();
if (borders != Borders{0})
{
if (property == "borders")
setBorders(value.getBorders());
drawBorders(target, states, borders, getSize(), getRenderer()->getBorderColor());
states.transform.translate({borders.left, borders.top});
}
// Draw the background
if (getRenderer()->getTextureBackground().isLoaded())
getRenderer()->getTextureBackground().draw(target, states);
else
{
sf::Vector2f positionOffset = {m_backRect.left, m_backRect.top};
states.transform.translate(positionOffset);
drawRectangleShape(target, states, {m_backRect.width, m_backRect.height}, getRenderer()->getBackgroundColor());
states.transform.translate(-positionOffset);
}
// Draw the filled area
sf::Vector2f imageShift;
if (getRenderer()->getTextureFill().isLoaded())
{
if (getRenderer()->getTextureBackground().isLoaded() && (getRenderer()->getTextureBackground().getSize() != getRenderer()->getTextureFill().getSize()))
{
imageShift = (getRenderer()->getTextureBackground().getSize() - getRenderer()->getTextureFill().getSize()) / 2.f;
states.transform.translate(imageShift);
getRenderer()->getTextureFill().draw(target, states);
states.transform.translate(-imageShift);
}
else
return WidgetRenderer::setProperty(property, std::move(value));
getRenderer()->getTextureFill().draw(target, states);
}
else if (value.getType() == ObjectConverter::Type::Color)
else // Using colors instead of a texture
{
if (property == "backgroundcolor")
setBackgroundColor(value.getColor());
else if (property == "foregroundcolor")
setForegroundColor(value.getColor());
else if (property == "textcolor")
setTextColor(value.getColor());
else if (property == "textcolorback")
setTextColorBack(value.getColor());
else if (property == "textcolorfront")
setTextColorFront(value.getColor());
else if (property == "bordercolor")
setBorderColor(value.getColor());
else
WidgetRenderer::setProperty(property, std::move(value));
}
else if (value.getType() == ObjectConverter::Type::Texture)
{
if (property == "backimage")
setBackTexture(value.getTexture());
else if (property == "frontimage")
setFrontTexture(value.getTexture());
else
WidgetRenderer::setProperty(property, std::move(value));
}
else
WidgetRenderer::setProperty(property, std::move(value));
}
sf::Vector2f positionOffset = {m_frontRect.left, m_frontRect.top};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ObjectConverter ProgressBarRenderer::getProperty(std::string property) const
{
property = toLower(property);
if (property == "borders")
return m_borders;
else if (property == "backgroundcolor")
return m_backgroundColor;
else if (property == "foregroundcolor")
return m_foregroundColor;
else if (property == "textcolor")
return m_textColorBack;
else if (property == "textcolorback")
return m_textColorBack;
else if (property == "textcolorfront")
return m_textColorFront;
else if (property == "bordercolor")
return m_borderColor;
else if (property == "backimage")
return m_textureBack;
else if (property == "frontimage")
return m_textureFront;
else
return WidgetRenderer::getProperty(property);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::map<std::string, ObjectConverter> ProgressBarRenderer::getPropertyValuePairs() const
{
auto pairs = WidgetRenderer::getPropertyValuePairs();
if (m_textureBack.isLoaded() && m_textureFront.isLoaded())
{
pairs["BackImage"] = m_textureBack;
pairs["FrontImage"] = m_textureFront;
}
else
{
pairs["BackgroundColor"] = m_backgroundColor;
pairs["ForegroundColor"] = m_foregroundColor;
}
if (m_progressBar->m_textBack.getTextColor() == m_progressBar->m_textFront.getTextColor())
pairs["TextColor"] = m_textColorBack;
else
{
pairs["TextColorBack"] = m_textColorBack;
pairs["TextColorFront"] = m_textColorFront;
}
pairs["BorderColor"] = m_borderColor;
pairs["Borders"] = m_borders;
return pairs;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setTextColor(const Color& color)
{
setTextColorBack(color);
setTextColorFront(color);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setTextColorBack(const Color& color)
{
m_textColorBack = color;
m_progressBar->m_textBack.setTextColor(calcColorOpacity(m_textColorBack, m_progressBar->getOpacity()));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setTextColorFront(const Color& color)
{
m_textColorFront = color;
m_progressBar->m_textFront.setTextColor(calcColorOpacity(m_textColorFront, m_progressBar->getOpacity()));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setBackgroundColor(const Color& color)
{
m_backgroundColor = color;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setForegroundColor(const Color& color)
{
m_foregroundColor = color;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setBorderColor(const Color& color)
{
m_borderColor = color;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setBackTexture(const Texture& texture)
{
m_textureBack = texture;
if (m_textureBack.isLoaded())
{
m_textureBack.setPosition(m_progressBar->getPosition());
m_textureBack.setSize(m_progressBar->getSize());
m_textureBack.setColor({255, 255, 255, static_cast<sf::Uint8>(m_progressBar->getOpacity() * 255)});
if (m_textureFront.isLoaded())
m_progressBar->updateSize();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::setFrontTexture(const Texture& texture)
{
m_textureFront = texture;
if (m_textureFront.isLoaded())
{
if (m_textureBack.isLoaded())
m_progressBar->updateSize();
m_textureFront.setColor({255, 255, 255, static_cast<sf::Uint8>(m_progressBar->getOpacity() * 255)});
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ProgressBarRenderer::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
// Check if there are textures
if (m_textureBack.isLoaded() && m_textureFront.isLoaded())
{
target.draw(m_textureBack, states);
target.draw(m_textureFront, states);
}
else // There is no background texture
{
sf::RectangleShape back(m_progressBar->getSize());
back.setPosition(m_progressBar->getPosition());
back.setFillColor(calcColorOpacity(m_backgroundColor, m_progressBar->getOpacity()));
target.draw(back, states);
sf::Vector2f frontPosition = m_progressBar->getPosition();
if (m_progressBar->getFillDirection() == ProgressBar::FillDirection::RightToLeft)
frontPosition.x += m_progressBar->getSize().x - m_progressBar->m_frontRect.width;
else if (m_progressBar->getFillDirection() == ProgressBar::FillDirection::BottomToTop)
frontPosition.y += m_progressBar->getSize().y - m_progressBar->m_frontRect.height;
sf::RectangleShape front({m_progressBar->m_frontRect.width, m_progressBar->m_frontRect.height});
front.setPosition(frontPosition);
front.setFillColor(calcColorOpacity(m_foregroundColor, m_progressBar->getOpacity()));
target.draw(front, states);
states.transform.translate(positionOffset);
drawRectangleShape(target, states, {m_frontRect.width, m_frontRect.height}, getRenderer()->getFillColor());
states.transform.translate(-positionOffset);
}
// Draw the text
if (m_progressBar->m_textBack.getText() != "")
if (m_textBack.getText() != "")
{
if (m_progressBar->m_textBack.getTextColor() == m_progressBar->m_textFront.getTextColor())
target.draw(m_progressBar->m_textBack, states);
sf::Vector2f textTranslation = (getInnerSize() - m_textBack.getSize()) / 2.f;
if (sf::Color(m_textBack.getRenderer()->getTextColor()) == sf::Color(m_textFront.getRenderer()->getTextColor()))
{
states.transform.translate(textTranslation);
target.draw(m_textBack, states);
states.transform.translate(-textTranslation);
}
else
{
// Get the old clipping area
GLint scissor[4];
glGetIntegerv(GL_SCISSOR_BOX, scissor);
// Calculate the scale factor of the view
const sf::View& view = target.getView();
float scaleViewX = target.getSize().x / view.getSize().x;
float scaleViewY = target.getSize().y / view.getSize().y;
sf::FloatRect backRect;
sf::FloatRect frontRect;
frontRect.width = m_progressBar->m_frontRect.width;
frontRect.height = m_progressBar->m_frontRect.height;
switch (m_progressBar->getFillDirection())
// Draw the text on top of the unfilled part
{
case ProgressBar::FillDirection::LeftToRight:
{
frontRect.left = m_progressBar->getAbsolutePosition().x;
frontRect.top = m_progressBar->getAbsolutePosition().y;
Clipping clipping{target, states, imageShift + sf::Vector2f{m_backRect.left, m_backRect.top}, {m_backRect.width, m_backRect.height}};
if (m_textureBack.isLoaded() && m_textureFront.isLoaded())
{
frontRect.left += m_textureFront.getPosition().x - m_progressBar->getPosition().x;
frontRect.top += m_textureFront.getPosition().y - m_progressBar->getPosition().y;
backRect.width = m_textureFront.getSize().x - frontRect.width;
}
else
backRect.width = m_progressBar->getSize().x - frontRect.width;
backRect.left = frontRect.left + frontRect.width;
backRect.top = frontRect.top;
backRect.height = frontRect.height;
break;
}
case ProgressBar::FillDirection::RightToLeft:
{
backRect.left = m_progressBar->getAbsolutePosition().x;
backRect.top = m_progressBar->getAbsolutePosition().y;
if (m_textureBack.isLoaded() && m_textureFront.isLoaded())
{
backRect.left += m_textureFront.getPosition().x - m_progressBar->getPosition().x;
backRect.top += m_textureFront.getPosition().y - m_progressBar->getPosition().y;
backRect.width = m_textureFront.getSize().x - frontRect.width;
backRect.height = m_textureFront.getSize().y;
}
else
{
backRect.width = m_progressBar->getSize().x - frontRect.width;
backRect.height = m_progressBar->getSize().y;
}
frontRect.left = backRect.left + backRect.width;
frontRect.top = backRect.top;
frontRect.height = backRect.height;
break;
}
case ProgressBar::FillDirection::TopToBottom:
{
frontRect.left = m_progressBar->getAbsolutePosition().x;
frontRect.top = m_progressBar->getAbsolutePosition().y;
if (m_textureBack.isLoaded() && m_textureFront.isLoaded())
{
frontRect.left += m_textureFront.getPosition().x - m_progressBar->getPosition().x;
frontRect.top += m_textureFront.getPosition().y - m_progressBar->getPosition().y;
backRect.height = m_textureFront.getSize().y - frontRect.height;
}
else
backRect.height = m_progressBar->getSize().y - frontRect.height;
backRect.left = frontRect.left;
backRect.top = frontRect.top + frontRect.height;
backRect.width = frontRect.width;
break;
}
case ProgressBar::FillDirection::BottomToTop:
{
backRect.left = m_progressBar->getAbsolutePosition().x;
backRect.top = m_progressBar->getAbsolutePosition().y;
if (m_textureBack.isLoaded() && m_textureFront.isLoaded())
{
backRect.left += m_textureFront.getPosition().x - m_progressBar->getPosition().x;
backRect.top += m_textureFront.getPosition().y - m_progressBar->getPosition().y;
backRect.width = m_textureFront.getSize().x;
backRect.height = m_textureFront.getSize().y - frontRect.height;
}
else
{
backRect.width = m_progressBar->getSize().x;
backRect.height = m_progressBar->getSize().y - frontRect.height;
}
frontRect.left = backRect.left;
frontRect.top = backRect.top + backRect.height;
frontRect.width = backRect.width;
break;
}
states.transform.translate(textTranslation);
target.draw(m_textBack, states);
states.transform.translate(-textTranslation);
}
// Calculate the clipping area for the back text
GLint scissorLeft = std::max(static_cast<GLint>(backRect.left * scaleViewX), scissor[0]);
GLint scissorTop = std::max(static_cast<GLint>(backRect.top * scaleViewY), static_cast<GLint>(target.getSize().y) - scissor[1] - scissor[3]);
GLint scissorRight = std::min(static_cast<GLint>((backRect.left + backRect.width) * scaleViewX), scissor[0] + scissor[2]);
GLint scissorBottom = std::min(static_cast<GLint>((backRect.top + backRect.height) * scaleViewY), static_cast<GLint>(target.getSize().y) - scissor[1]);
// Draw the text on top of the filled part
{
Clipping clipping{target, states, imageShift + sf::Vector2f{m_frontRect.left, m_frontRect.top}, {m_frontRect.width, m_frontRect.height}};
if (scissorRight < scissorLeft)
scissorRight = scissorLeft;
else if (scissorBottom < scissorTop)
scissorTop = scissorBottom;
// Set the clipping area
glScissor(scissorLeft, target.getSize().y - scissorBottom, scissorRight - scissorLeft, scissorBottom - scissorTop);
// Draw the back text
target.draw(m_progressBar->m_textBack, states);
// Calculate the clipping area for the front text
scissorLeft = std::max(static_cast<GLint>(frontRect.left * scaleViewX), scissor[0]);
scissorTop = std::max(static_cast<GLint>(frontRect.top * scaleViewY), static_cast<GLint>(target.getSize().y) - scissor[1] - scissor[3]);
scissorRight = std::min(static_cast<GLint>((frontRect.left + frontRect.width) * scaleViewX), scissor[0] + scissor[2]);
scissorBottom = std::min(static_cast<GLint>((frontRect.top + frontRect.height) * scaleViewY), static_cast<GLint>(target.getSize().y) - scissor[1]);
if (scissorRight < scissorLeft)
scissorRight = scissorLeft;
else if (scissorBottom < scissorTop)
scissorTop = scissorBottom;
// Set the clipping area
glScissor(scissorLeft, target.getSize().y - scissorBottom, scissorRight - scissorLeft, scissorBottom - scissorTop);
// Draw the front text
target.draw(m_progressBar->m_textFront, states);
// Reset the old clipping area
glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
states.transform.translate(textTranslation);
target.draw(m_textFront, states);
states.transform.translate(-textTranslation);
}
}
}
// Draw the borders around the progress bar
if (m_borders != Borders{0, 0, 0, 0})
{
sf::Vector2f position = m_progressBar->getPosition();
sf::Vector2f size = m_progressBar->getSize();
// Draw left border
sf::RectangleShape border({m_borders.left, size.y + m_borders.top});
border.setPosition(position.x - m_borders.left, position.y - m_borders.top);
border.setFillColor(calcColorOpacity(m_borderColor, m_progressBar->getOpacity()));
target.draw(border, states);
// Draw top border
border.setSize({size.x + m_borders.right, m_borders.top});
border.setPosition(position.x, position.y - m_borders.top);
target.draw(border, states);
// Draw right border
border.setSize({m_borders.right, size.y + m_borders.bottom});
border.setPosition(position.x + size.x, position.y);
target.draw(border, states);
// Draw bottom border
border.setSize({size.x + m_borders.left, m_borders.bottom});
border.setPosition(position.x - m_borders.left, position.y + size.y);
target.draw(border, states);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<WidgetRenderer> ProgressBarRenderer::clone(Widget* widget)
void ProgressBar::recalculateFillSize()
{
auto renderer = std::make_shared<ProgressBarRenderer>(*this);
renderer->m_progressBar = static_cast<ProgressBar*>(widget);
return renderer;
sf::Vector2f size = getInnerSize();
if (getRenderer()->getTextureFill().isLoaded())
{
sf::Vector2f frontSize;
if (getRenderer()->getTextureBackground().isLoaded())
{
switch (getRenderer()->getTextureBackground().getScalingType())
{
case Texture::ScalingType::Normal:
frontSize.x = getRenderer()->getTextureFill().getImageSize().x * getInnerSize().x / getRenderer()->getTextureBackground().getImageSize().x;
frontSize.y = getRenderer()->getTextureFill().getImageSize().y * getInnerSize().y / getRenderer()->getTextureBackground().getImageSize().y;
break;
case Texture::ScalingType::Horizontal:
frontSize.x = getInnerSize().x - ((getRenderer()->getTextureBackground().getImageSize().x - getRenderer()->getTextureFill().getImageSize().x) * (getInnerSize().y / getRenderer()->getTextureBackground().getImageSize().y));
frontSize.y = getRenderer()->getTextureFill().getImageSize().y * getInnerSize().y / getRenderer()->getTextureBackground().getImageSize().y;
break;
case Texture::ScalingType::Vertical:
frontSize.x = getRenderer()->getTextureFill().getImageSize().x * getInnerSize().x / getRenderer()->getTextureBackground().getImageSize().x;
frontSize.y = getInnerSize().y - ((getRenderer()->getTextureBackground().getImageSize().y - getRenderer()->getTextureFill().getImageSize().y) * (getInnerSize().x / getRenderer()->getTextureBackground().getImageSize().x));
break;
case Texture::ScalingType::NineSlice:
frontSize.x = getInnerSize().x - (getRenderer()->getTextureBackground().getImageSize().x - getRenderer()->getTextureFill().getImageSize().x);
frontSize.y = getInnerSize().y - (getRenderer()->getTextureBackground().getImageSize().y - getRenderer()->getTextureFill().getImageSize().y);
break;
}
}
else // There is a fill texture but not a background one
frontSize = getInnerSize();
getRenderer()->getTextureFill().setSize(frontSize);
size = frontSize;
}
switch (getFillDirection())
{
case FillDirection::LeftToRight:
m_frontRect = {0, 0, size.x * ((m_value - m_minimum) / static_cast<float>(m_maximum - m_minimum)), size.y};
m_backRect = {m_frontRect.width, 0, size.x - m_frontRect.width, size.y};
break;
case FillDirection::RightToLeft:
m_frontRect = {0, 0, size.x * ((m_value - m_minimum) / static_cast<float>(m_maximum - m_minimum)), size.y};
m_frontRect.left = size.x - m_frontRect.width;
m_backRect = {0, 0, size.x - m_frontRect.width, size.y};
break;
case FillDirection::TopToBottom:
m_frontRect = {0, 0, size.x, size.y * ((m_value - m_minimum) / static_cast<float>(m_maximum - m_minimum))};
m_backRect = {0, m_frontRect.height, size.x, size.y - m_frontRect.height};
break;
case FillDirection::BottomToTop:
m_frontRect = {0, 0, size.x, size.y * ((m_value - m_minimum) / static_cast<float>(m_maximum - m_minimum))};
m_frontRect.top = size.y - m_frontRect.height;
m_backRect = {0, 0, size.x, size.y - m_frontRect.height};
break;
}
if (getRenderer()->getTextureFill().isLoaded())
getRenderer()->getTextureFill().setTextureRect(m_frontRect);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -24,7 +24,6 @@
#include <TGUI/Container.hpp>
#include <TGUI/Loading/Theme.hpp>
#include <TGUI/Widgets/RadioButton.hpp>
namespace tgui
@ -281,6 +280,8 @@ namespace tgui
{
updateTextureSizes();
value.getTexture().setOpacity(getRenderer()->getOpacity());
if (property == "texturefocused")
m_allowFocus = value.getTexture().isLoaded();
}

View File

@ -35,7 +35,7 @@ set(TEST_SOURCES
#Widgets/MessageBox.cpp
Widgets/Panel.cpp
Widgets/Picture.cpp
#Widgets/ProgressBar.cpp
Widgets/ProgressBar.cpp
Widgets/RadioButton.cpp
#Widgets/Scrollbar.cpp
#Widgets/Slider.cpp

View File

@ -25,26 +25,30 @@
#include "../Tests.hpp"
#include <TGUI/Widgets/ProgressBar.hpp>
TEST_CASE("[ProgressBar]") {
TEST_CASE("[ProgressBar]")
{
tgui::ProgressBar::Ptr progressBar = std::make_shared<tgui::ProgressBar>();
progressBar->setFont("resources/DroidSansArmenian.ttf");
progressBar->getRenderer()->setFont("resources/DroidSansArmenian.ttf");
progressBar->setMinimum(10);
progressBar->setMaximum(20);
progressBar->setValue(15);
SECTION("Signals") {
SECTION("Signals")
{
REQUIRE_NOTHROW(progressBar->connect("ValueChanged", [](){}));
REQUIRE_NOTHROW(progressBar->connect("Full", [](){}));
REQUIRE_NOTHROW(progressBar->connect("ValueChanged", [](int){}));
REQUIRE_NOTHROW(progressBar->connect("Full", [](int){}));
REQUIRE_NOTHROW(progressBar->connect("ValueChanged", [](unsigned int){}));
REQUIRE_NOTHROW(progressBar->connect("Full", [](unsigned int){}));
}
SECTION("WidgetType") {
SECTION("WidgetType")
{
REQUIRE(progressBar->getWidgetType() == "ProgressBar");
}
SECTION("Minimum") {
SECTION("Minimum")
{
REQUIRE(progressBar->getMinimum() == 10);
progressBar->setMinimum(12);
@ -63,7 +67,8 @@ TEST_CASE("[ProgressBar]") {
REQUIRE(progressBar->getMaximum() == 22);
}
SECTION("Maximum") {
SECTION("Maximum")
{
REQUIRE(progressBar->getMaximum() == 20);
progressBar->setMaximum(17);
@ -82,7 +87,8 @@ TEST_CASE("[ProgressBar]") {
REQUIRE(progressBar->getMaximum() == 9);
}
SECTION("Value") {
SECTION("Value")
{
REQUIRE(progressBar->getValue() == 15);
progressBar->setValue(14);
@ -95,7 +101,8 @@ TEST_CASE("[ProgressBar]") {
REQUIRE(progressBar->getValue() == 20);
}
SECTION("Value") {
SECTION("incrementValue")
{
progressBar->setValue(18);
REQUIRE(progressBar->getValue() == 18);
REQUIRE(progressBar->incrementValue() == 19);
@ -106,18 +113,21 @@ TEST_CASE("[ProgressBar]") {
REQUIRE(progressBar->getValue() == 20);
}
SECTION("Text") {
SECTION("Text")
{
REQUIRE(progressBar->getText() == "");
progressBar->setText("SomeText");
REQUIRE(progressBar->getText() == "SomeText");
}
SECTION("TextSize") {
SECTION("TextSize")
{
progressBar->setTextSize(25);
REQUIRE(progressBar->getTextSize() == 25);
}
SECTION("FillDirection") {
SECTION("FillDirection")
{
REQUIRE(progressBar->getFillDirection() == tgui::ProgressBar::FillDirection::LeftToRight);
progressBar->setFillDirection(tgui::ProgressBar::FillDirection::RightToLeft);
REQUIRE(progressBar->getFillDirection() == tgui::ProgressBar::FillDirection::RightToLeft);
@ -129,120 +139,104 @@ TEST_CASE("[ProgressBar]") {
REQUIRE(progressBar->getFillDirection() == tgui::ProgressBar::FillDirection::LeftToRight);
}
SECTION("Renderer") {
SECTION("Renderer")
{
auto renderer = progressBar->getRenderer();
SECTION("colored") {
SECTION("set serialized property") {
REQUIRE_NOTHROW(renderer->setProperty("TextColor", "rgb(10, 20, 30)"));
REQUIRE(renderer->getProperty("TextColor").getColor() == sf::Color(10, 20, 30));
REQUIRE(renderer->getProperty("TextColorBack").getColor() == sf::Color(10, 20, 30));
REQUIRE(renderer->getProperty("TextColorFront").getColor() == sf::Color(10, 20, 30));
SECTION("colored")
{
SECTION("set serialized property")
{
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColor", "rgb(20, 30, 40)"));
REQUIRE_NOTHROW(renderer->setProperty("ForegroundColor", "rgb(30, 40, 50)"));
REQUIRE_NOTHROW(renderer->setProperty("TextColorBack", "rgb(40, 50, 60)"));
REQUIRE_NOTHROW(renderer->setProperty("TextColorFront", "rgb(50, 60, 70)"));
REQUIRE_NOTHROW(renderer->setProperty("FillColor", "rgb(30, 40, 50)"));
REQUIRE_NOTHROW(renderer->setProperty("TextColor", "rgb(40, 50, 60)"));
REQUIRE_NOTHROW(renderer->setProperty("TextColorFilled", "rgb(50, 60, 70)"));
REQUIRE_NOTHROW(renderer->setProperty("BorderColor", "rgb(60, 70, 80)"));
REQUIRE_NOTHROW(renderer->setProperty("TextStyle", "Italic"));
REQUIRE_NOTHROW(renderer->setProperty("Borders", "(1, 2, 3, 4)"));
}
SECTION("set object property") {
REQUIRE_NOTHROW(renderer->setProperty("TextColor", sf::Color{10, 20, 30}));
REQUIRE(renderer->getProperty("TextColor").getColor() == sf::Color(10, 20, 30));
REQUIRE(renderer->getProperty("TextColorBack").getColor() == sf::Color(10, 20, 30));
REQUIRE(renderer->getProperty("TextColorFront").getColor() == sf::Color(10, 20, 30));
SECTION("set object property")
{
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColor", sf::Color{20, 30, 40}));
REQUIRE_NOTHROW(renderer->setProperty("ForegroundColor", sf::Color{30, 40, 50}));
REQUIRE_NOTHROW(renderer->setProperty("TextColorBack", sf::Color{40, 50, 60}));
REQUIRE_NOTHROW(renderer->setProperty("TextColorFront", sf::Color{50, 60, 70}));
REQUIRE_NOTHROW(renderer->setProperty("FillColor", sf::Color{30, 40, 50}));
REQUIRE_NOTHROW(renderer->setProperty("TextColor", sf::Color{40, 50, 60}));
REQUIRE_NOTHROW(renderer->setProperty("TextColorFilled", sf::Color{50, 60, 70}));
REQUIRE_NOTHROW(renderer->setProperty("BorderColor", sf::Color{60, 70, 80}));
REQUIRE_NOTHROW(renderer->setProperty("TextStyle", sf::Text::Italic));
REQUIRE_NOTHROW(renderer->setProperty("Borders", tgui::Borders{1, 2, 3, 4}));
}
SECTION("functions") {
renderer->setTextColor({10, 20, 30});
REQUIRE(renderer->getProperty("TextColor").getColor() == sf::Color(10, 20, 30));
REQUIRE(renderer->getProperty("TextColorBack").getColor() == sf::Color(10, 20, 30));
REQUIRE(renderer->getProperty("TextColorFront").getColor() == sf::Color(10, 20, 30));
SECTION("functions")
{
renderer->setBackgroundColor({20, 30, 40});
renderer->setForegroundColor({30, 40, 50});
renderer->setTextColorBack({40, 50, 60});
renderer->setTextColorFront({50, 60, 70});
renderer->setFillColor({30, 40, 50});
renderer->setTextColor({40, 50, 60});
renderer->setTextColorFilled({50, 60, 70});
renderer->setBorderColor({60, 70, 80});
renderer->setTextStyle(sf::Text::Italic);
renderer->setBorders({1, 2, 3, 4});
SECTION("getPropertyValuePairs") {
auto pairs = renderer->getPropertyValuePairs();
REQUIRE(pairs.size() == 6);
REQUIRE(pairs["BackgroundColor"].getColor() == sf::Color(20, 30, 40));
REQUIRE(pairs["ForegroundColor"].getColor() == sf::Color(30, 40, 50));
REQUIRE(pairs["TextColorBack"].getColor() == sf::Color(40, 50, 60));
REQUIRE(pairs["TextColorFront"].getColor() == sf::Color(50, 60, 70));
REQUIRE(pairs["BorderColor"].getColor() == sf::Color(60, 70, 80));
REQUIRE(pairs["Borders"].getOutline() == tgui::Borders(1, 2, 3, 4));
}
}
REQUIRE(renderer->getProperty("BackgroundColor").getColor() == sf::Color(20, 30, 40));
REQUIRE(renderer->getProperty("ForegroundColor").getColor() == sf::Color(30, 40, 50));
REQUIRE(renderer->getProperty("TextColorBack").getColor() == sf::Color(40, 50, 60));
REQUIRE(renderer->getProperty("TextColorFront").getColor() == sf::Color(50, 60, 70));
REQUIRE(renderer->getProperty("FillColor").getColor() == sf::Color(30, 40, 50));
REQUIRE(renderer->getProperty("TextColor").getColor() == sf::Color(40, 50, 60));
REQUIRE(renderer->getProperty("TextColorFilled").getColor() == sf::Color(50, 60, 70));
REQUIRE(renderer->getProperty("BorderColor").getColor() == sf::Color(60, 70, 80));
REQUIRE(renderer->getProperty("TextStyle").getTextStyle() == sf::Text::Italic);
REQUIRE(renderer->getProperty("Borders").getOutline() == tgui::Borders(1, 2, 3, 4));
REQUIRE(renderer->getBackgroundColor() == sf::Color(20, 30, 40));
REQUIRE(renderer->getFillColor() == sf::Color(30, 40, 50));
REQUIRE(renderer->getTextColor() == sf::Color(40, 50, 60));
REQUIRE(renderer->getTextColorFilled() == sf::Color(50, 60, 70));
REQUIRE(renderer->getBorderColor() == sf::Color(60, 70, 80));
REQUIRE(renderer->getTextStyle() == sf::Text::Italic);
REQUIRE(renderer->getBorders() == tgui::Borders(1, 2, 3, 4));
}
SECTION("textured") {
SECTION("textured")
{
tgui::Texture textureBack("resources/Black.png", {180, 64, 90, 40}, {20, 0, 50, 40});
tgui::Texture textureFront("resources/Black.png", {180, 108, 82, 32}, {16, 0, 50, 32});
REQUIRE(!renderer->getProperty("BackImage").getTexture().isLoaded());
REQUIRE(!renderer->getProperty("FrontImage").getTexture().isLoaded());
REQUIRE(!renderer->getProperty("TextureBackground").getTexture().isLoaded());
REQUIRE(!renderer->getProperty("TextureFill").getTexture().isLoaded());
SECTION("set serialized property") {
REQUIRE_NOTHROW(renderer->setProperty("BackImage", tgui::Serializer::serialize(textureBack)));
REQUIRE_NOTHROW(renderer->setProperty("FrontImage", tgui::Serializer::serialize(textureFront)));
SECTION("set serialized property")
{
REQUIRE_NOTHROW(renderer->setProperty("TextureBackground", tgui::Serializer::serialize(textureBack)));
REQUIRE_NOTHROW(renderer->setProperty("TextureFill", tgui::Serializer::serialize(textureFront)));
}
SECTION("set object property") {
REQUIRE_NOTHROW(renderer->setProperty("BackImage", textureBack));
REQUIRE_NOTHROW(renderer->setProperty("FrontImage", textureFront));
SECTION("set object property")
{
REQUIRE_NOTHROW(renderer->setProperty("TextureBackground", textureBack));
REQUIRE_NOTHROW(renderer->setProperty("TextureFill", textureFront));
}
SECTION("functions") {
renderer->setBackTexture(textureBack);
renderer->setFrontTexture(textureFront);
SECTION("getPropertyValuePairs") {
auto pairs = renderer->getPropertyValuePairs();
REQUIRE(pairs.size() == 6);
REQUIRE(pairs["BackImage"].getTexture().getData() == textureBack.getData());
REQUIRE(pairs["FrontImage"].getTexture().getData() == textureFront.getData());
}
SECTION("functions")
{
renderer->setTextureBackground(textureBack);
renderer->setTextureFill(textureFront);
}
REQUIRE(renderer->getProperty("BackImage").getTexture().isLoaded());
REQUIRE(renderer->getProperty("FrontImage").getTexture().isLoaded());
REQUIRE(renderer->getProperty("TextureBackground").getTexture().isLoaded());
REQUIRE(renderer->getProperty("TextureFill").getTexture().isLoaded());
REQUIRE(renderer->getProperty("BackImage").getTexture().getData() == textureBack.getData());
REQUIRE(renderer->getProperty("FrontImage").getTexture().getData() == textureFront.getData());
REQUIRE(renderer->getTextureBackground().getData() == textureBack.getData());
REQUIRE(renderer->getTextureFill().getData() == textureFront.getData());
}
}
SECTION("Saving and loading from file") {
REQUIRE_NOTHROW(progressBar = std::make_shared<tgui::Theme>()->load("ProgressBar"));
auto theme = std::make_shared<tgui::Theme>("resources/Black.txt");
REQUIRE_NOTHROW(progressBar = theme->load("ProgressBar"));
REQUIRE(progressBar->getPrimaryLoadingParameter() == "resources/Black.txt");
REQUIRE(progressBar->getSecondaryLoadingParameter() == "progressbar");
SECTION("Saving and loading from file")
{
tgui::Theme theme{"resources/Black.txt"};
progressBar->setRenderer(theme.getRenderer("ProgressBar"));
auto parent = std::make_shared<tgui::GuiContainer>();
parent->add(progressBar);
progressBar->setOpacity(0.8f);
progressBar->setText("SomeText");
progressBar->setTextSize(25);
progressBar->setFillDirection(tgui::ProgressBar::FillDirection::RightToLeft);
@ -255,12 +249,9 @@ TEST_CASE("[ProgressBar]") {
REQUIRE_NOTHROW(parent->saveWidgetsToFile("WidgetFileProgressBar2.txt"));
REQUIRE(compareFiles("WidgetFileProgressBar1.txt", "WidgetFileProgressBar2.txt"));
SECTION("Copying widget") {
tgui::ProgressBar temp;
temp = *progressBar;
parent->removeAllWidgets();
parent->add(tgui::ProgressBar::copy(std::make_shared<tgui::ProgressBar>(temp)));
SECTION("Copying widget")
{
copy(parent, progressBar);
REQUIRE_NOTHROW(parent->saveWidgetsToFile("WidgetFileProgressBar2.txt"));
REQUIRE(compareFiles("WidgetFileProgressBar1.txt", "WidgetFileProgressBar2.txt"));

View File

@ -4,7 +4,6 @@ Button {
TextureDown : "Black.png" Part(90, 64, 45, 50) Middle(10, 0, 25, 50);
TextColor : rgb(190, 190, 190);
TextColorHover : rgb(250, 250, 250);
TextColorDown : rgb(250, 250, 250);
}
ChatBox {
@ -96,10 +95,10 @@ Panel {
}
ProgressBar {
BackImage : "Black.png" Part(180, 64, 90, 40) Middle(20, 0, 50, 40);
FrontImage : "Black.png" Part(180, 108, 90, 32) Middle(16, 0, 50, 32);
TextColorBack : rgb(190, 190, 190);
TextColorFront : rgb(250, 250, 250);
TextureBackground : "Black.png" Part(180, 64, 90, 40) Middle(20, 0, 50, 40);
TextureFill : "Black.png" Part(184, 108, 82, 32) Middle(16, 0, 50, 32);
TextColor : rgb(190, 190, 190);
TextColorFilled : rgb(250, 250, 250);
}
RadioButton {