TGUI/include/TGUI/Texture.hpp

416 lines
22 KiB
C++

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2019 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_TEXTURE_HPP
#define TGUI_TEXTURE_HPP
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <TGUI/TextureData.hpp>
#include <TGUI/Vector2f.hpp>
#include <TGUI/Color.hpp>
#include <SFML/System/String.hpp>
#include <functional>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
class TGUI_API Texture
{
public:
using CallbackFunc = std::function<void(std::shared_ptr<TextureData>)>;
using ImageLoaderFunc = std::function<std::unique_ptr<sf::Image>(const sf::String&)>;
using TextureLoaderFunc = std::function<std::shared_ptr<TextureData>(Texture&, const sf::String&, const sf::IntRect&)>;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Default constructor
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture() {}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor that created the texture
///
/// @param id Id for the the image to load (for the default loader, the id is the filename)
/// @param partRect Load only part of the image. Pass an empty rectangle if you want to load the full image
/// @param middlePart Choose the middle part of the image for 9-slice scaling (relative to the part defined by partRect)
/// @param smooth Enable smoothing on the texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture(const char* id,
const sf::IntRect& partRect = sf::IntRect(0, 0, 0, 0),
const sf::IntRect& middlePart = sf::IntRect(0, 0, 0, 0),
bool smooth = false)
: Texture(sf::String{id}, partRect, middlePart, smooth)
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor that created the texture
///
/// @param id Id for the the image to load (for the default loader, the id is the filename)
/// @param partRect Load only part of the image. Pass an empty rectangle if you want to load the full image
/// @param middlePart Choose the middle part of the image for 9-slice scaling (relative to the part defined by partRect)
/// @param smooth Enable smoothing on the texture
///
/// This constructor just calls the corresponding load function.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture(const std::string& id,
const sf::IntRect& partRect = sf::IntRect(0, 0, 0, 0),
const sf::IntRect& middlePart = sf::IntRect(0, 0, 0, 0),
bool smooth = false)
: Texture(sf::String{id}, partRect, middlePart, smooth)
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor that created the texture
///
/// @param id Id for the the image to load (for the default loader, the id is the filename)
/// @param partRect Load only part of the image. Pass an empty rectangle if you want to load the full image
/// @param middlePart Choose the middle part of the image for 9-slice scaling (relative to the part defined by partRect)
/// @param smooth Enable smoothing on the texture
///
/// This constructor just calls the corresponding load function.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture(const sf::String& id,
const sf::IntRect& partRect = sf::IntRect(0, 0, 0, 0),
const sf::IntRect& middlePart = sf::IntRect(0, 0, 0, 0),
bool smooth = false);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor that created the texture from an existing sf::Texture
///
/// @param texture Existing texture to copy
/// @param partRect Load only part of the image. Pass an empty rectangle if you want to load the full image
/// @param middlePart Choose the middle part of the image for 9-slice scaling (relative to the part defined by partRect)
///
/// The texture will be copied, you do not have to keep the sf::Texture alive after calling this function.
///
/// This constructor just calls the corresponding load function.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture(const sf::Texture& texture,
const sf::IntRect& partRect = sf::IntRect(0, 0, 0, 0),
const sf::IntRect& middlePart = sf::IntRect(0, 0, 0, 0));
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Copy constructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture(const Texture&);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Move constructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture(Texture&&);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Destructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
~Texture();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Overload of copy assignment operator
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture& operator=(const Texture&);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Move assignment
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Texture& operator=(Texture&&);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Creates the texture
///
/// @param id Id for the the image to load (for the default loader, the id is the filename)
/// @param partRect Load only part of the image. Don't pass this parameter if you want to load the full image
/// @param middleRect Choose the middle part of the image for 9-slice scaling (relative to the part defined by partRect)
/// @param smooth Enable smoothing on the texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void load(const sf::String& id,
const sf::IntRect& partRect = {},
const sf::IntRect& middleRect = {},
bool smooth = false);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Creates the texture from an existing sf::Texture
///
/// @param texture Existing texture to copy
/// @param partRect Load only part of the texture. Don't pass this parameter if you want to load the full image
/// @param middleRect Choose the middle part of the image for 9-slice scaling (relative to the part defined by partRect)
///
/// The texture will be copied, you do not have to keep the sf::Texture alive after calling this function.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void load(const sf::Texture& texture,
const sf::IntRect& partRect = {},
const sf::IntRect& middleRect = {});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the id that was used to load the texture (for the default loader, the id is the filename)
///
/// @return Id of the texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const sf::String& getId() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the texture data
///
/// @return Data of the texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<TextureData> getData() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the size that the loaded image
///
/// @return Size of the image like it was when loaded (no scaling applied)
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Vector2f getImageSize() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Enables or disable the smooth filter
///
/// When the filter is activated, the texture appears smoother so that pixels are less noticeable.
/// However if you want the texture to look exactly the same as its source file, you should leave it disabled.
/// The smooth filter is disabled by default.
///
/// @param smooth True to enable smoothing, false to disable it
///
/// @see isSmooth
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setSmooth(bool smooth);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Tells whether the smooth filter is enabled or not
///
/// @return True if smoothing is enabled, false if it is disabled
///
/// @see setSmooth
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isSmooth() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the global color of the texture
///
/// This color is modulated (multiplied) with the pixel color. It can be used to colorize the texture,
/// or change its global opacity. Note that the alpha component is multiplied with the opacity of the widget.
///
/// By default, the texture's color is opaque white.
///
/// @param color New color of the texture
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setColor(const Color& color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the global color of the texture
///
/// This color is modulated (multiplied) with the pixel color. It can be used to colorize the texture,
/// or change its global opacity. Note that the alpha component is multiplied with the opacity of the widget.
///
/// By default, the texture's color is opaque white.
///
/// @return Current color of the texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const Color& getColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the shader used to draw the texture
/// @param shader New shader to use
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setShader(sf::Shader* shader);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the shader used to draw the texture
/// @return Shader currently being use to draw the texture
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sf::Shader* getShader() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the middle rect of the texture which is used for 9-slice scaling
///
/// @return Middle rect of the texture
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
sf::IntRect getMiddleRect() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Checks if a certain pixel is transparent
///
/// @param pos Coordinate of the pixel
///
/// @return True when the pixel is transparent, false when it is not
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isTransparentPixel(sf::Vector2u pos) const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets a callback function for when this texture is copied
///
/// @param func Function that will be called when this texture is copied
///
/// This function can be useful when implementing a resource manager.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setCopyCallback(const CallbackFunc& func);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets a callback function for when this texture is destroyed
///
/// @param func Function that will be called when this texture is destroyed
///
/// This function can be useful when implementing a resource manager.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setDestructCallback(const CallbackFunc& func);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Compares the texture with another one
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool operator==(const Texture& right) const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Compares the texture with another one
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool operator!=(const Texture& right) const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets a different image loader
///
/// @param func New image loader function
///
/// The image loader will be called inside the texture loader to create the sf::Image.
///
/// The default loader will simply load the image from a file.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void setImageLoader(const ImageLoaderFunc& func);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the used image loader
///
/// @return Image loader that is currently being used
///
/// @see setImageLoader
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const ImageLoaderFunc& getImageLoader();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets a different texture loader
///
/// @param func New texture loader function
///
/// The texture loader will initialize this Texture object.
///
/// The default loader will use an internal texture manager to prevent the same thing from being loaded twice.
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void setTextureLoader(const TextureLoaderFunc& func);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the used texture loader
///
/// @return Texture loader that is currently being used
///
/// @see setTextureLoader
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static const TextureLoaderFunc& getTextureLoader();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the texture data
///
/// @param data New texture data
/// @param middleRect Choose the middle part of the image part to determine scaling (e.g. 9-slice scaling)
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureData(std::shared_ptr<TextureData> data, const sf::IntRect& middleRect = {});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private:
std::shared_ptr<TextureData> m_data = nullptr;
Color m_color = Color::White;
sf::Shader* m_shader = nullptr;
sf::IntRect m_middleRect;
sf::String m_id;
CallbackFunc m_copyCallback;
CallbackFunc m_destructCallback;
static TextureLoaderFunc m_textureLoader;
static ImageLoaderFunc m_imageLoader;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif // TGUI_TEXTURE_HPP