Added new TreeView widget

0.8
Bruno Van de Velde 2018-12-15 10:40:46 +01:00
parent 89b122db0d
commit 9187229aaa
23 changed files with 2581 additions and 29 deletions

View File

@ -1,3 +1,12 @@
TGUI 0.8.2 (TBD)
-----------------
- TreeView widget
- Text styles of lines in ChatBox can now changed
- Clipping was broken when using multiple windows
- ScrollbablePanel didn't fully scroll to right with both scrollbars visible
TGUI 0.8.1 (15 October 2018)
-----------------------------

View File

@ -313,14 +313,14 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the wanted width scrollbar
/// @brief Sets the wanted width of the scrollbar
/// @param scrollbarWidth Requested scrollbar width or 0 to use the default width (texture size if using textures)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setScrollbarWidth(float scrollbarWidth);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the wanted width scrollbar
/// @brief Returns the wanted width of the scrollbar
/// @return Requested scrollbar width or 0 if no width was set (texture width or default value will be used)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float getScrollbarWidth() const;

View File

@ -0,0 +1,272 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2018 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_TREE_VIEW_RENDERER_HPP
#define TGUI_TREE_VIEW_RENDERER_HPP
#include <TGUI/Renderers/WidgetRenderer.hpp>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
class TGUI_API TreeViewRenderer : public tgui::WidgetRenderer
{
public:
using WidgetRenderer::WidgetRenderer;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the size of the borders
/// @param borders Size of the borders
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBorders(const tgui::Borders& borders);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the size of the borders
/// @return border size
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Borders getBorders() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the padding of the tree view
/// @param padding The padding width and height
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setPadding(const Padding& padding);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the size of the padding
/// @return padding size
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Padding getPadding() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background color of the tree view
/// @param backgroundColor The new background color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBackgroundColor(tgui::Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the background color
/// @return Background color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Color getBackgroundColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the borders
/// @param borderColor The new border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBorderColor(tgui::Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the borders
/// @return Border color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Color getBorderColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text
/// @param textColor The new text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColor(tgui::Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the text
/// @return Text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Color getTextColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text of the item below the mouse
/// @param textColor The new hover text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextColorHover(tgui::Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the text of the item below the mouse
/// @return Hover text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Color getTextColorHover() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text from the selected item
/// @param textColor The new selected text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setSelectedTextColor(tgui::Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the text from the selected item
/// @return Selected text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Color getSelectedTextColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the color of the text of the selected item when it is below the mouse
/// @param textColor The new hover text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setSelectedTextColorHover(tgui::Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the color of the text of the selected item when it is below the mouse
/// @return Hover text color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Color getSelectedTextColorHover() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background color of the selected item
/// @param backgroundColor The new selected item background color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setSelectedBackgroundColor(tgui::Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the background color of the selected item
/// @return Selected item background color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Color getSelectedBackgroundColor() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background color used for the item below the mouse
/// @param backgroundColor The new hover background color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setBackgroundColorHover(tgui::Color color);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the background color used for the item below the mouse
/// @return Background color of hovered item
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Color getBackgroundColorHover() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the background color used for the selected item when the mouse hovers over it
/// @param backgroundColor The new selected hover background color
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setSelectedBackgroundColorHover(Color backgroundColor);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the background color used for the selected item when the mouse hovers over it
/// @return Background color of selected item in hover state
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Color getSelectedBackgroundColorHover() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the renderer data of the scrollbar
/// @param scrollbarRendererData Data about how the scrollbar should look
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setScrollbar(std::shared_ptr<tgui::RendererData> scrollbarRenderData);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the renderer data of the scrollbar
/// @return Data about how the scrollbar looks
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<tgui::RendererData> getScrollbar() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Sets the wanted width of the scrollbar
/// @param scrollbarWidth Requested scrollbar width or 0 to use the default width (texture size if using textures)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setScrollbarWidth(float scrollbarWidth);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the wanted width of the scrollbar
/// @return Requested scrollbar width or 0 if no width was set (texture width or default value will be used)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float getScrollbarWidth() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the image used in front of an expanded item
///
/// @param textureBranchExpanded The expanded branch texture
///
/// When this texture is not set, the TextureBranchCollapsed will be used when available.
/// If neither of these textures are set, TextureLeaf is tried.
/// If TextureLeaf isn't set either then a "-" symbol will be displayed in the same color as the text.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureBranchExpanded(const tgui::Texture& textureBranchExpanded);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the image used in front of an expanded item
/// @return The expanded branch texture
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Texture& getTextureBranchExpanded() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the image used in front of a collapsed item
///
/// @param textureBranchCollapsed The collapsed branch texture
///
/// When this texture is not set, the TextureBranchExpanded will be used when available.
/// If neither of these textures are set, TextureLeaf is tried.
/// If TextureLeaf isn't set either then a "+" symbol will be displayed in the same color as the text.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureBranchCollapsed(const tgui::Texture& textureBranchCollapsed);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the image used in front of a collapsed item
/// @return The collapsed branch texture
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Texture& getTextureBranchCollapsed() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the image used in front of a lead item
///
/// @param textureLeaf The lead item texture
///
/// When neither TextureBranchExpanded and TextureBranchCollapsed are set, this texture is also used for branch nodes.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextureLeaf(const tgui::Texture& textureLeaf);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the image used in front of a leaf item
/// @return The lead item texture
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tgui::Texture& getTextureLeaf() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif // TGUI_TREE_VIEW_RENDERER_HPP

View File

@ -577,7 +577,7 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Signal to which the user can subscribe to get callbacks from
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class TGUI_API SignalMenuItem : public Signal
class TGUI_API SignalItemHierarchy : public Signal
{
public:
@ -592,7 +592,7 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Constructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SignalMenuItem(std::string&& name) :
SignalItemHierarchy(std::string&& name) :
Signal{std::move(name), 2}
{
}
@ -666,6 +666,10 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
#ifndef TGUI_REMOVE_DEPRECATED_CODE
using SignalMenuItem = SignalItemHierarchy;
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Base class for Widget which provides functionality to connect signals based on their name

View File

@ -69,6 +69,7 @@
#include <TGUI/Widgets/SpinButton.hpp>
#include <TGUI/Widgets/Tabs.hpp>
#include <TGUI/Widgets/TextBox.hpp>
#include <TGUI/Widgets/TreeView.hpp>
#include <TGUI/Widgets/VerticalLayout.hpp>
#include <TGUI/SignalImpl.hpp>

View File

@ -441,6 +441,9 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the list box contains the given item
///
/// @param item The item to search for
///
/// @return Does the list box contain the item?
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool contains(const sf::String& item) const;
@ -448,6 +451,9 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the list box contains an item with the given id
///
/// @param id The id of the item to search for
///
/// @return Does the list box contain the id?
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool containsId(const sf::String& id) const;

View File

@ -290,7 +290,7 @@ namespace tgui
/// @param hierarchy Hierarchy of the menu item, starting with the menu and ending with menu item to be deleted
/// @param removeParentsWhenEmpty Also delete the parent of the deleted menu item if it has no other children
///
/// @return True when the menu item exists, false when hierarchy was incorrect
/// @return True when the menu item existed and was removed, false when hierarchy was incorrect
///
/// @code
/// menuBar->removeMenuItem({"File", "Save"});
@ -606,7 +606,7 @@ namespace tgui
/// Optional parameters:
/// - The text of the clicked menu item
/// - List containing both the name of the menu and the menu item that was clicked
SignalMenuItem onMenuItemClick = {"MenuItemClicked"};
SignalItemHierarchy onMenuItemClick = {"MenuItemClicked"};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,498 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2018 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_TREE_VIEW_HPP
#define TGUI_TREE_VIEW_HPP
#include <TGUI/CopiedSharedPtr.hpp>
#include <TGUI/Widgets/Scrollbar.hpp>
#include <TGUI/Renderers/TreeViewRenderer.hpp>
#include <TGUI/Text.hpp>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Tree view widget
/// @warning This widget is new and API stability is not yet guaranteed. Functions and their behavior may still change in newer patch releases, based on feedback.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class TGUI_API TreeView : public Widget
{
public:
typedef std::shared_ptr<TreeView> Ptr;
typedef std::shared_ptr<const TreeView> ConstPtr;
/// @brief Read-only node representation used by getNodes
struct ConstNode
{
bool expanded;
sf::String text;
std::vector<ConstNode> nodes;
};
/// @brief Internal representation of a node
struct Node
{
Text text;
unsigned depth = 0;
bool expanded = true;
Node* parent;
std::vector<std::shared_ptr<Node>> nodes;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Default constructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TreeView();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copy constructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TreeView(const TreeView&);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Move constructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TreeView(TreeView&&) = default;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Overload of copy assignment operator
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TreeView& operator=(const TreeView&);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Overload of move assignment operator
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TreeView& operator=(TreeView&&) = default;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Creates a new tree view widget
/// @return The new tree view
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static TreeView::Ptr create();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Makes a copy of another tree view
/// @param treeView The other tree view
/// @return The new tree view
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static TreeView::Ptr copy(TreeView::ConstPtr treeView);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the renderer, which gives access to functions that determine how the widget is displayed
/// @return Temporary pointer to the renderer that may be shared with other widgets using the same renderer
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TreeViewRenderer* getSharedRenderer();
const TreeViewRenderer* getSharedRenderer() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the renderer, which gives access to functions that determine how the widget is displayed
/// @return Temporary pointer to the renderer
/// @warning After calling this function, the widget has its own copy of the renderer and it will no longer be shared.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TreeViewRenderer* getRenderer();
const TreeViewRenderer* getRenderer() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the size of the tree view
/// @param size The new size of the tree view
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setSize(const Layout2d& size) override;
using Widget::setSize;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Adds a new item to the tree view
///
/// @param hierarchy Hierarchy of items, with the last item being the leaf item
/// @param createParents Should the hierarchy be created if it did not exist yet?
///
/// @return True when the item was added (always the case if createParents is true)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool addItem(const std::vector<sf::String>& hierarchy, bool createParents = true);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Expands the given item
///
/// @param hierarchy Hierarchy of items, identifying the node that has to be expanded
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void expand(const std::vector<sf::String>& hierarchy);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Expands all items
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void expandAll();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Collapses the given item
///
/// @param hierarchy Hierarchy of items, identifying the node that has to be collapsed
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void collapse(const std::vector<sf::String>& hierarchy);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Collapses all items
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void collapseAll();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Deselect the item if one was selected
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void deselectItem();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Removes an item
///
/// @param hierarchy Hierarchy of items, identifying the node to be removed
/// @param removeParentsWhenEmpty Also delete the parent of the deleted item if it has no other children
///
/// @return True when the item existed and was removed, false when hierarchy was incorrect
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool removeItem(const std::vector<sf::String>& hierarchy, bool removeParentsWhenEmpty = true);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Removes all items
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void removeAllItems();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the selected item
/// @return Hierarchy of items, identifying the selected node, or an empty list when no item was selected
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<sf::String> getSelectedItem() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the nodes in the tree view
/// @return List of nodes
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<ConstNode> getNodes() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the height of the items in the tree view
/// @param itemHeight The size of a single item in the tree view
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setItemHeight(unsigned int itemHeight);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the height of the items in the tree view
/// @return The item height
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int getItemHeight() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Changes the text size of the items
///
/// @param textSize The size size of the text
///
/// This will not change the height that each item has. By default (or when passing 0 to this function) the text will
/// be auto-sized to nicely fit inside this item height.
///
/// @see setItemHeight
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setTextSize(unsigned int textSize);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns the text size of the items
/// @return The text size
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int getTextSize() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the tree view contains the given item
///
/// @param hierarchy Hierarchy of items, identifying the node to search for
///
/// @return Does the tree view contain the item?
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool contains(const std::vector<sf::String>& hierarchy);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Returns whether the mouse position (which is relative to the parent widget) lies on top of the widget
///
/// @return Is the mouse on top of the widget?
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool mouseOnWidget(Vector2f pos) const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void leftMousePressed(Vector2f pos) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void leftMouseReleased(Vector2f pos) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseMoved(Vector2f pos) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool mouseWheelScrolled(float delta, Vector2f pos) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseNoLongerOnWidget() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseNoLongerDown() override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void markNodesDirty();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Draw the widget to a render target
///
/// @param target Render target to draw to
/// @param states Current render states
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Retrieves a signal based on its name
///
/// @param signalName Name of the signal
///
/// @return Signal that corresponds to the name
///
/// @throw Exception when the name does not match any signal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Signal& getSignal(std::string signalName) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Function called when one of the properties of the renderer is changed
///
/// @param property Lowercase name of the property that was changed
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void rendererChanged(const std::string& property) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Saves the widget as a tree node in order to save it to a file
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<DataIO::Node> save(SavingRenderersMap& renderers) const override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Loads the widget from a tree of nodes
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void load(const std::unique_ptr<DataIO::Node>& node, const LoadingRenderersMap& renderers) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Returns the size without the borders
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Vector2f getInnerSize() const;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Update the colors and text style of the selected and hovered items
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void updateSelectedAndHoveringItemColorsAndStyle();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Update the color and text style of all the items
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void updateItemColorsAndStyle();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// This function is called every frame with the time passed since the last frame.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void update(sf::Time elapsedTime) override;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Makes a copy of the widget
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Widget::Ptr clone() const override
{
return std::make_shared<TreeView>(*this);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void updateTextColors(std::vector<std::shared_ptr<Node>>& nodes);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void createNode(std::vector<std::shared_ptr<Node>>& menus, Node* parent, const sf::String& text);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @internal
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Node* findParentNode(const std::vector<sf::String>& hierarchy, unsigned int parentIndex, std::vector<std::shared_ptr<Node>>& nodes, Node* parent, bool createParents);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Expands or collapses one of the visible items
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void toggleNodeInternal(std::size_t index);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Expands or collapses a node
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool expandOrCollapse(const std::vector<sf::String>& hierarchy, bool expand);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Helper function to load the items from a text file
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loadItems(const std::unique_ptr<DataIO::Node>& node, std::vector<std::shared_ptr<Node>>& items, Node* parent);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rebuilds the list of visible items and positions the texts
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int updateVisibleNodes(std::vector<std::shared_ptr<Node>>& nodes, Node* selectedNode, float textPadding, unsigned int pos);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Updates the text colors of the selected and hovered items
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void updateSelectedAndHoveringItemColors();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Updates the text color of the hovered item
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void updateHoveredItem(int item);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Updates the text color of the selected item
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void updateSelectedItem(int item);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public:
SignalItemHierarchy onItemSelect = {"ItemSelected"}; ///< An node was selected in the tree view. Optional parameter: selected node
SignalItemHierarchy onDoubleClick = {"DoubleClicked"}; ///< A leaf node was double clicked. Optional parameter: selected node
SignalItemHierarchy onExpand = {"Expanded"}; ///< A branch node was expanded in the tree view. Optional parameter: expanded node
SignalItemHierarchy onCollapse = {"Collapsed"}; ///< A branch node was collapsed in the tree view. Optional parameter: collapsed node
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
protected:
// This contains the nodes of the tree
std::vector<std::shared_ptr<Node>> m_nodes;
std::vector<std::shared_ptr<Node>> m_visibleNodes;
int m_selectedItem = -1;
int m_hoveredItem = -1;
// The size must be stored
unsigned int m_itemHeight = 0;
unsigned int m_requestedTextSize = 0;
unsigned int m_textSize = 0;
float m_maxRight = 0;
Vector2f m_iconBounds;
CopiedSharedPtr<ScrollbarChildWidget> m_verticalScrollbar;
CopiedSharedPtr<ScrollbarChildWidget> m_horizontalScrollbar;
bool m_possibleDoubleClick = false;
int m_doubleClickNodeIndex = -1;
Sprite m_spriteBranchExpanded;
Sprite m_spriteBranchCollapsed;
Sprite m_spriteLeaf;
// Cached renderer properties
Borders m_bordersCached;
Borders m_paddingCached;
Color m_borderColorCached;
Color m_backgroundColorCached;
Color m_textColorCached;
Color m_textColorHoverCached;
Color m_selectedTextColorCached;
Color m_selectedTextColorHoverCached;
Color m_selectedBackgroundColorCached;
Color m_selectedBackgroundColorHoverCached;
Color m_backgroundColorHoverCached;
TextStyle m_textStyleCached;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif // TGUI_TREE_VIEW_HPP

View File

@ -47,6 +47,7 @@ set(TGUI_SRC
Renderers/SpinButtonRenderer.cpp
Renderers/TabsRenderer.cpp
Renderers/TextBoxRenderer.cpp
Renderers/TreeViewRenderer.cpp
Renderers/WidgetRenderer.cpp
Widgets/BitmapButton.cpp
Widgets/BoxLayout.cpp
@ -80,6 +81,7 @@ set(TGUI_SRC
Widgets/SpinButton.cpp
Widgets/Tabs.cpp
Widgets/TextBox.cpp
Widgets/TreeView.cpp
Widgets/VerticalLayout.cpp
)

View File

@ -223,6 +223,16 @@ namespace tgui
{"selectedtextcolor", Color::White},
{"selectedtextbackgroundcolor", Color{0, 110, 255}},
{"backgroundcolor", Color::White}})},
{"treeview", RendererData::create({{"borders", Borders{1}},
{"padding", Padding{0}},
{"bordercolor", Color::Black},
{"textcolor", Color{60, 60, 60}},
{"textcolorhover", Color::Black},
{"selectedtextcolor", Color::White},
{"backgroundcolor", Color{245, 245, 245}},
{"backgroundcolorhover", Color::White},
{"selectedbackgroundcolor", Color{0, 110, 255}},
{"selectedbackgroundcolorhover", Color{30, 150, 255}}})},
{"verticallayout", RendererData::create({})}
};
}

View File

@ -53,6 +53,7 @@
#include <TGUI/Widgets/SpinButton.hpp>
#include <TGUI/Widgets/Tabs.hpp>
#include <TGUI/Widgets/TextBox.hpp>
#include <TGUI/Widgets/TreeView.hpp>
#include <TGUI/Widgets/VerticalLayout.hpp>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -91,6 +92,7 @@ namespace tgui
{"spinbutton", std::make_shared<SpinButton>},
{"tabs", std::make_shared<Tabs>},
{"textbox", std::make_shared<TextBox>},
{"treeview", std::make_shared<TreeView>},
{"verticallayout", std::make_shared<VerticalLayout>}
};

View File

@ -0,0 +1,54 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2018 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/TreeViewRenderer.hpp>
#include <TGUI/RendererDefines.hpp>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace tgui
{
TGUI_RENDERER_PROPERTY_OUTLINE(TreeViewRenderer, Borders)
TGUI_RENDERER_PROPERTY_OUTLINE(TreeViewRenderer, Padding)
TGUI_RENDERER_PROPERTY_COLOR(TreeViewRenderer, BackgroundColor, Color::White)
TGUI_RENDERER_PROPERTY_COLOR(TreeViewRenderer, SelectedBackgroundColor, Color(0, 110, 255))
TGUI_RENDERER_PROPERTY_COLOR(TreeViewRenderer, BackgroundColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(TreeViewRenderer, SelectedBackgroundColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(TreeViewRenderer, BorderColor, {})
TGUI_RENDERER_PROPERTY_COLOR(TreeViewRenderer, TextColor, Color::Black)
TGUI_RENDERER_PROPERTY_COLOR(TreeViewRenderer, TextColorHover, {})
TGUI_RENDERER_PROPERTY_COLOR(TreeViewRenderer, SelectedTextColor, Color::White)
TGUI_RENDERER_PROPERTY_COLOR(TreeViewRenderer, SelectedTextColorHover, {})
TGUI_RENDERER_PROPERTY_TEXTURE(TreeViewRenderer, TextureBranchExpanded)
TGUI_RENDERER_PROPERTY_TEXTURE(TreeViewRenderer, TextureBranchCollapsed)
TGUI_RENDERER_PROPERTY_TEXTURE(TreeViewRenderer, TextureLeaf)
TGUI_RENDERER_PROPERTY_RENDERER(TreeViewRenderer, Scrollbar, "scrollbar")
TGUI_RENDERER_PROPERTY_NUMBER(TreeViewRenderer, ScrollbarWidth, 0)
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -351,7 +351,7 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef TGUI_REMOVE_DEPRECATED_CODE
unsigned int SignalMenuItem::connect(const DelegateMenuItem& handler)
unsigned int SignalItemHierarchy::connect(const DelegateMenuItem& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
@ -360,7 +360,7 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalMenuItem::connect(const DelegateMenuItemEx& handler)
unsigned int SignalItemHierarchy::connect(const DelegateMenuItemEx& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<sf::String>(internal_signal::parameters[1])); };
@ -369,7 +369,7 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalMenuItem::connect(const DelegateMenuItemFull& handler)
unsigned int SignalItemHierarchy::connect(const DelegateMenuItemFull& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler](){ handler(internal_signal::dereference<std::vector<sf::String>>(internal_signal::parameters[2])); };
@ -378,7 +378,7 @@ namespace tgui
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalMenuItem::connect(const DelegateMenuItemFullEx& handler)
unsigned int SignalItemHierarchy::connect(const DelegateMenuItemFullEx& handler)
{
const auto id = generateUniqueId();
m_handlers[id] = [handler, name=m_name](){ handler(getWidget(), name, internal_signal::dereference<std::vector<sf::String>>(internal_signal::parameters[2])); };
@ -387,7 +387,7 @@ namespace tgui
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SignalMenuItem::validateTypes(std::initializer_list<std::type_index> unboundParameters) const
unsigned int SignalItemHierarchy::validateTypes(std::initializer_list<std::type_index> unboundParameters) const
{
if ((unboundParameters.size() == 1) && (checkParamType<std::string>(unboundParameters.begin()) || checkParamType<sf::String>(unboundParameters.begin())))
return 1;

View File

@ -1010,7 +1010,7 @@ namespace tgui
// Draw the background of the selected item
if (m_selectedItem >= 0)
{
states.transform.translate({0, static_cast<float>(m_selectedItem * m_itemHeight)});
states.transform.translate({0, m_selectedItem * static_cast<float>(m_itemHeight)});
const Vector2f size = {getInnerSize().x - m_paddingCached.getLeft() - m_paddingCached.getRight(), static_cast<float>(m_itemHeight)};
if ((m_selectedItem == m_hoveringItem) && m_selectedBackgroundColorHoverCached.isSet())
@ -1018,15 +1018,15 @@ namespace tgui
else
drawRectangleShape(target, states, size, m_selectedBackgroundColorCached);
states.transform.translate({0, -static_cast<float>(m_selectedItem * m_itemHeight)});
states.transform.translate({0, -m_selectedItem * static_cast<float>(m_itemHeight)});
}
// Draw the background of the item on which the mouse is standing
if ((m_hoveringItem >= 0) && (m_hoveringItem != m_selectedItem) && m_backgroundColorHoverCached.isSet())
{
states.transform.translate({0, static_cast<float>(m_hoveringItem * m_itemHeight)});
states.transform.translate({0, m_hoveringItem * static_cast<float>(m_itemHeight)});
drawRectangleShape(target, states, {getInnerSize().x - m_paddingCached.getLeft() - m_paddingCached.getRight(), static_cast<float>(m_itemHeight)}, m_backgroundColorHoverCached);
states.transform.translate({0, -static_cast<float>(m_hoveringItem * m_itemHeight)});
states.transform.translate({0, -m_hoveringItem * static_cast<float>(m_itemHeight)});
}
// Draw the items

View File

@ -277,7 +277,7 @@ namespace tgui
if (!menu)
return false;
createMenu((*menu).menuItems, hierarchy.back());
createMenu(menu->menuItems, hierarchy.back());
return true;
}
@ -378,17 +378,17 @@ namespace tgui
if (!menu)
return false;
for (unsigned int j = 0; j < (*menu).menuItems.size(); ++j)
for (unsigned int j = 0; j < menu->menuItems.size(); ++j)
{
auto& menuItem = (*menu).menuItems[j];
auto& menuItem = menu->menuItems[j];
if (menuItem.text.getString() != hierarchy.back())
continue;
if (!enabled && ((*menu).selectedMenuItem == static_cast<int>(j)))
(*menu).selectedMenuItem = -1;
if (!enabled && (menu->selectedMenuItem == static_cast<int>(j)))
menu->selectedMenuItem = -1;
menuItem.enabled = enabled;
updateMenuTextColor(menuItem, ((*menu).selectedMenuItem == static_cast<int>(j)));
updateMenuTextColor(menuItem, (menu->selectedMenuItem == static_cast<int>(j)));
return true;
}
@ -413,7 +413,7 @@ namespace tgui
if (!menuItem)
return false;
return (*menuItem).enabled;
return menuItem->enabled;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -583,9 +583,9 @@ namespace tgui
auto* menu = &m_menus[m_visibleMenu];
std::vector<sf::String> hierarchy;
hierarchy.push_back(m_menus[m_visibleMenu].text.getString());
while ((*menu).selectedMenuItem != -1)
while (menu->selectedMenuItem != -1)
{
auto& menuItem = (*menu).menuItems[(*menu).selectedMenuItem];
auto& menuItem = menu->menuItems[menu->selectedMenuItem];
hierarchy.push_back(menuItem.text.getString());
if (menuItem.menuItems.empty())
{
@ -945,7 +945,7 @@ namespace tgui
if (!menu)
return nullptr;
for (auto& menuItem : (*menu).menuItems)
for (auto& menuItem : menu->menuItems)
{
if (menuItem.text.getString() != hierarchy.back())
continue;
@ -1035,12 +1035,12 @@ namespace tgui
void MenuBar::deselectBottomItem()
{
auto* menu = &m_menus[m_visibleMenu];
while ((*menu).selectedMenuItem != -1)
while (menu->selectedMenuItem != -1)
{
auto& menuItem = (*menu).menuItems[(*menu).selectedMenuItem];
auto& menuItem = menu->menuItems[menu->selectedMenuItem];
if (menuItem.menuItems.empty())
{
closeSubMenus((*menu).menuItems, (*menu).selectedMenuItem);
closeSubMenus(menu->menuItems, menu->selectedMenuItem);
break;
}

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,7 @@ set(TEST_SOURCES
Widgets/SpinButton.cpp
Widgets/Tabs.cpp
Widgets/TextBox.cpp
Widgets/TreeView.cpp
Widgets/VerticalLayout.cpp
)

View File

@ -204,7 +204,7 @@ TEST_CASE("[MenuBar]")
}
}
SECTION("Invalid addMenuItem calls")
SECTION("Invalid calls")
{
REQUIRE(!menuBar->addMenuItem("Item"));

337
tests/Widgets/TreeView.cpp Normal file
View File

@ -0,0 +1,337 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus' Graphical User Interface
// Copyright (C) 2012-2018 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 "Tests.hpp"
#include <TGUI/Widgets/TreeView.hpp>
#include <TGUI/Widgets/Panel.hpp>
TEST_CASE("[TreeView]")
{
auto treeView = tgui::TreeView::create();
treeView->getRenderer()->setFont("resources/DejaVuSans.ttf");
SECTION("Signals")
{
for (const auto& signal : {"ItemSelected", "ItemSelected", "ItemSelected", "ItemSelected"})
{
REQUIRE_NOTHROW(treeView->connect(signal, [](){}));
REQUIRE_NOTHROW(treeView->connect(signal, [](sf::String){}));
REQUIRE_NOTHROW(treeView->connect(signal, [](std::string){}));
REQUIRE_NOTHROW(treeView->connect(signal, [](std::vector<sf::String>){}));
REQUIRE_NOTHROW(treeView->connect(signal, [](tgui::Widget::Ptr, std::string){}));
REQUIRE_NOTHROW(treeView->connect(signal, [](tgui::Widget::Ptr, std::string, sf::String){}));
REQUIRE_NOTHROW(treeView->connect(signal, [](tgui::Widget::Ptr, std::string, std::string){}));
REQUIRE_NOTHROW(treeView->connect(signal, [](tgui::Widget::Ptr, std::string, std::vector<sf::String>){}));
}
}
SECTION("WidgetType")
{
REQUIRE(treeView->getWidgetType() == "TreeView");
}
SECTION("Position and Size")
{
treeView->setPosition(40, 30);
treeView->setSize(150, 100);
treeView->getRenderer()->setBorders(2);
REQUIRE(treeView->getPosition() == sf::Vector2f(40, 30));
REQUIRE(treeView->getSize() == sf::Vector2f(150, 100));
REQUIRE(treeView->getFullSize() == treeView->getSize());
REQUIRE(treeView->getWidgetOffset() == sf::Vector2f(0, 0));
}
SECTION("Adding and removing items")
{
SECTION("No depth")
{
REQUIRE(treeView->getNodes().empty());
REQUIRE(treeView->addItem({"One"}));
REQUIRE(treeView->getNodes().size() == 1);
REQUIRE(treeView->getNodes()[0].text == "One");
REQUIRE(treeView->getNodes()[0].nodes.empty());
REQUIRE(treeView->addItem({"Two"}, false));
REQUIRE(treeView->getNodes().size() == 2);
}
SECTION("Multiple items")
{
REQUIRE(treeView->addItem({"Smilies", "Happy"}));
REQUIRE(treeView->addItem({"Smilies", "Sad"}));
REQUIRE(treeView->addItem({"Smilies", "Neither"}));
REQUIRE(treeView->addItem({"Vehicles", "Parts", "Wheel"}));
REQUIRE(treeView->addItem({"Vehicles", "Whole", "Truck"}));
REQUIRE(treeView->addItem({"Vehicles", "Whole", "Car"}));
SECTION("Verify that nodes were added")
{
REQUIRE(treeView->getNodes().size() == 2);
REQUIRE(treeView->getNodes()[0].text == "Smilies");
REQUIRE(treeView->getNodes()[0].nodes.size() == 3);
REQUIRE(treeView->getNodes()[0].nodes[0].text == "Happy");
REQUIRE(treeView->getNodes()[0].nodes[1].text == "Sad");
REQUIRE(treeView->getNodes()[0].nodes[2].text == "Neither");
REQUIRE(treeView->getNodes()[1].text == "Vehicles");
REQUIRE(treeView->getNodes()[1].nodes.size() == 2);
REQUIRE(treeView->getNodes()[1].nodes[0].text == "Parts");
REQUIRE(treeView->getNodes()[1].nodes[0].nodes.size() == 1);
REQUIRE(treeView->getNodes()[1].nodes[0].nodes[0].text == "Wheel");
REQUIRE(treeView->getNodes()[1].nodes[1].text == "Whole");
REQUIRE(treeView->getNodes()[1].nodes[1].nodes.size() == 2);
REQUIRE(treeView->getNodes()[1].nodes[1].nodes[0].text == "Truck");
REQUIRE(treeView->getNodes()[1].nodes[1].nodes[1].text == "Car");
}
SECTION("Removing items")
{
treeView->removeItem({"Vehicles", "Parts", "Wheel"});
treeView->removeItem({"Smilies", "Sad"});
treeView->removeItem({"Vehicles", "Whole", "Car"});
REQUIRE(treeView->getNodes().size() == 2);
REQUIRE(treeView->getNodes()[0].text == "Smilies");
REQUIRE(treeView->getNodes()[0].nodes.size() == 2);
REQUIRE(treeView->getNodes()[0].nodes[0].text == "Happy");
REQUIRE(treeView->getNodes()[0].nodes[1].text == "Neither");
REQUIRE(treeView->getNodes()[1].text == "Vehicles");
REQUIRE(treeView->getNodes()[1].nodes.size() == 1);
REQUIRE(treeView->getNodes()[1].nodes[0].text == "Whole");
REQUIRE(treeView->getNodes()[1].nodes[0].nodes.size() == 1);
REQUIRE(treeView->getNodes()[1].nodes[0].nodes[0].text == "Truck");
SECTION("Keep parent after delete")
{
treeView->removeItem({"Vehicles", "Whole", "Truck"}, false);
REQUIRE(treeView->getNodes()[1].nodes[0].text == "Whole");
REQUIRE(treeView->getNodes()[1].nodes[0].nodes.size() == 0);
}
}
SECTION("Removing all items")
{
treeView->removeAllItems();
REQUIRE(treeView->getNodes().empty());
}
}
SECTION("Invalid calls")
{
treeView->addItem({"One"});
REQUIRE(!treeView->addItem({"Two", "Sub"}, false));
REQUIRE(!treeView->addItem(std::vector<sf::String>()));
REQUIRE(!treeView->removeItem({"One", "Sub"}));
}
}
SECTION("Collapsing and expanding items")
{
treeView->addItem({"Smilies", "Neither"});
treeView->addItem({"Vehicles", "Parts", "Wheel"});
// Nodes are expanded by default
REQUIRE(treeView->getNodes()[0].expanded);
REQUIRE(treeView->getNodes()[1].expanded);
REQUIRE(treeView->getNodes()[1].nodes[0].expanded);
treeView->collapse({"Vehicles"});
REQUIRE(!treeView->getNodes()[1].expanded);
REQUIRE(treeView->getNodes()[1].nodes[0].expanded); // collapse doesn't affect state of child nodes
treeView->collapse({"Vehicles", "Parts"});
REQUIRE(!treeView->getNodes()[1].nodes[0].expanded);
treeView->expand({"Vehicles"});
REQUIRE(treeView->getNodes()[1].expanded);
REQUIRE(!treeView->getNodes()[1].nodes[0].expanded); // expand doesn't affect state of child nodes
treeView->collapseAll();
REQUIRE(!treeView->getNodes()[0].expanded);
REQUIRE(!treeView->getNodes()[1].expanded);
REQUIRE(!treeView->getNodes()[1].nodes[0].expanded);
treeView->expandAll();
REQUIRE(treeView->getNodes()[0].expanded);
REQUIRE(treeView->getNodes()[1].expanded);
REQUIRE(treeView->getNodes()[1].nodes[0].expanded);
}
SECTION("ItemHeight")
{
treeView->setItemHeight(30);
REQUIRE(treeView->getItemHeight() == 30);
}
SECTION("TextSize")
{
treeView->setTextSize(25);
REQUIRE(treeView->getTextSize() == 25);
}
SECTION("Events / Signals")
{
SECTION("Widget")
{
testWidgetSignals(treeView);
}
/// TODO
}
testWidgetRenderer(treeView->getRenderer());
SECTION("Renderer")
{
auto renderer = treeView->getRenderer();
SECTION("colored")
{
tgui::ScrollbarRenderer scrollbarRenderer;
scrollbarRenderer.setTrackColor(sf::Color::Red);
scrollbarRenderer.setThumbColor(sf::Color::Blue);
SECTION("set serialized property")
{
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColor", "rgb(20, 30, 40)"));
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColorHover", "rgb(50, 60, 70)"));
REQUIRE_NOTHROW(renderer->setProperty("TextColor", "rgb(30, 40, 50)"));
REQUIRE_NOTHROW(renderer->setProperty("TextColorHover", "rgb(40, 50, 60)"));
REQUIRE_NOTHROW(renderer->setProperty("SelectedBackgroundColor", "rgb(60, 70, 80)"));
REQUIRE_NOTHROW(renderer->setProperty("SelectedBackgroundColorHover", "rgb(90, 100, 110)"));
REQUIRE_NOTHROW(renderer->setProperty("SelectedTextColor", "rgb(70, 80, 90)"));
REQUIRE_NOTHROW(renderer->setProperty("SelectedTextColorHover", "rgb(100, 110, 120)"));
REQUIRE_NOTHROW(renderer->setProperty("BorderColor", "rgb(80, 90, 100)"));
REQUIRE_NOTHROW(renderer->setProperty("Borders", "(1, 2, 3, 4)"));
REQUIRE_NOTHROW(renderer->setProperty("Padding", "(5, 6, 7, 8)"));
REQUIRE_NOTHROW(renderer->setProperty("Scrollbar", "{ TrackColor = Red; ThumbColor = Blue; }"));
REQUIRE_NOTHROW(renderer->setProperty("ScrollbarWidth", "15"));
}
SECTION("set object property")
{
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColor", sf::Color{20, 30, 40}));
REQUIRE_NOTHROW(renderer->setProperty("BackgroundColorHover", sf::Color{50, 60, 70}));
REQUIRE_NOTHROW(renderer->setProperty("TextColor", sf::Color{30, 40, 50}));
REQUIRE_NOTHROW(renderer->setProperty("TextColorHover", sf::Color{40, 50, 60}));
REQUIRE_NOTHROW(renderer->setProperty("SelectedBackgroundColor", sf::Color{60, 70, 80}));
REQUIRE_NOTHROW(renderer->setProperty("SelectedBackgroundColorHover", sf::Color{90, 100, 110}));
REQUIRE_NOTHROW(renderer->setProperty("SelectedTextColor", sf::Color{70, 80, 90}));
REQUIRE_NOTHROW(renderer->setProperty("SelectedTextColorHover", sf::Color{100, 110, 120}));
REQUIRE_NOTHROW(renderer->setProperty("BorderColor", sf::Color{80, 90, 100}));
REQUIRE_NOTHROW(renderer->setProperty("Borders", tgui::Borders{1, 2, 3, 4}));
REQUIRE_NOTHROW(renderer->setProperty("Padding", tgui::Borders{5, 6, 7, 8}));
REQUIRE_NOTHROW(renderer->setProperty("Scrollbar", scrollbarRenderer.getData()));
REQUIRE_NOTHROW(renderer->setProperty("ScrollbarWidth", 15));
}
SECTION("functions")
{
renderer->setBackgroundColor({20, 30, 40});
renderer->setBackgroundColorHover({50, 60, 70});
renderer->setTextColor({30, 40, 50});
renderer->setTextColorHover({40, 50, 60});
renderer->setSelectedBackgroundColor({60, 70, 80});
renderer->setSelectedBackgroundColorHover({90, 100, 110});
renderer->setSelectedTextColor({70, 80, 90});
renderer->setSelectedTextColorHover({100, 110, 120});
renderer->setBorderColor({80, 90, 100});
renderer->setBorders({1, 2, 3, 4});
renderer->setPadding({5, 6, 7, 8});
renderer->setScrollbar(scrollbarRenderer.getData());
renderer->setScrollbarWidth(15);
}
REQUIRE(renderer->getProperty("BackgroundColor").getColor() == sf::Color(20, 30, 40));
REQUIRE(renderer->getProperty("BackgroundColorHover").getColor() == sf::Color(50, 60, 70));
REQUIRE(renderer->getProperty("TextColor").getColor() == sf::Color(30, 40, 50));
REQUIRE(renderer->getProperty("TextColorHover").getColor() == sf::Color(40, 50, 60));
REQUIRE(renderer->getProperty("SelectedBackgroundColor").getColor() == sf::Color(60, 70, 80));
REQUIRE(renderer->getProperty("SelectedBackgroundColorHover").getColor() == sf::Color(90, 100, 110));
REQUIRE(renderer->getProperty("SelectedTextColor").getColor() == sf::Color(70, 80, 90));
REQUIRE(renderer->getProperty("SelectedTextColorHover").getColor() == sf::Color(100, 110, 120));
REQUIRE(renderer->getProperty("BorderColor").getColor() == sf::Color(80, 90, 100));
REQUIRE(renderer->getProperty("Borders").getOutline() == tgui::Borders(1, 2, 3, 4));
REQUIRE(renderer->getProperty("Padding").getOutline() == tgui::Borders(5, 6, 7, 8));
REQUIRE(renderer->getProperty("ScrollbarWidth").getNumber() == 15);
REQUIRE(renderer->getScrollbar()->propertyValuePairs.size() == 2);
REQUIRE(renderer->getScrollbar()->propertyValuePairs["trackcolor"].getColor() == sf::Color::Red);
REQUIRE(renderer->getScrollbar()->propertyValuePairs["thumbcolor"].getColor() == sf::Color::Blue);
}
SECTION("textured")
{
tgui::Texture textureBranchExpanded("resources/TreeView/Expanded.png");
tgui::Texture textureBranchCollapsed("resources/TreeView/Collapsed.png");
tgui::Texture textureLeaf("resources/TreeView/Leaf.png");
SECTION("set serialized property")
{
REQUIRE_NOTHROW(renderer->setProperty("TextureBranchExpanded", tgui::Serializer::serialize(textureBranchExpanded)));
REQUIRE_NOTHROW(renderer->setProperty("TextureBranchCollapsed", tgui::Serializer::serialize(textureBranchCollapsed)));
REQUIRE_NOTHROW(renderer->setProperty("TextureLeaf", tgui::Serializer::serialize(textureLeaf)));
}
SECTION("set object property")
{
REQUIRE_NOTHROW(renderer->setProperty("TextureBranchExpanded", textureBranchExpanded));
REQUIRE_NOTHROW(renderer->setProperty("TextureBranchCollapsed", textureBranchCollapsed));
REQUIRE_NOTHROW(renderer->setProperty("TextureLeaf", textureLeaf));
}
SECTION("functions")
{
renderer->setTextureBranchExpanded(textureBranchExpanded);
renderer->setTextureBranchCollapsed(textureBranchCollapsed);
renderer->setTextureLeaf(textureLeaf);
}
REQUIRE(renderer->getProperty("TextureBranchExpanded").getTexture().getData() != nullptr);
REQUIRE(renderer->getProperty("TextureBranchCollapsed").getTexture().getData() != nullptr);
REQUIRE(renderer->getProperty("TextureLeaf").getTexture().getData() != nullptr);
REQUIRE(renderer->getTextureBranchExpanded().getData() == textureBranchExpanded.getData());
REQUIRE(renderer->getTextureBranchCollapsed().getData() == textureBranchCollapsed.getData());
REQUIRE(renderer->getTextureLeaf().getData() == textureLeaf.getData());
}
}
SECTION("Saving and loading from file")
{
treeView->addItem({"Smilies", "Happy"});
treeView->addItem({"Smilies", "Sad"});
treeView->addItem({"Smilies", "Neither"});
treeView->addItem({"Vehicles", "Parts", "Wheel"});
treeView->addItem({"Vehicles", "Whole", "Truck"});
treeView->addItem({"Vehicles", "Whole", "Car"});
treeView->collapse({"Vehicles", "Whole"});
treeView->setItemHeight(30);
treeView->setTextSize(25);
testSavingWidget("TreeView", treeView, false);
}
// TODO: Draw
}

26
themes/TreeView/Black.txt Normal file
View File

@ -0,0 +1,26 @@
TreeView {
TextureBranchCollapsed = "Collapsed.png";
TextureBranchExpanded = "Expanded.png";
TextureLeaf = "Leaf.png";
TextColor = rgb(190, 190, 190);
TextColorHover = rgb(250, 250, 250);
BackgroundColor = rgb( 80, 80, 80);
BackgroundColorHover = rgb(100, 100, 100);
SelectedBackgroundColor = rgb( 10, 110, 255);
SelectedBackgroundColorHover = rgb(30, 150, 255);
SelectedTextColor = White;
BorderColor = Black;
Borders = 1;
Scrollbar = &Scrollbar;
}
Scrollbar {
TextureTrack = "../Black.png" Part(123, 154, 20, 20);
TextureTrackHover = "../Black.png" Part(123, 174, 20, 20);
TextureThumb = "../Black.png" Part(143, 154, 20, 20);
TextureThumbHover = "../Black.png" Part(143, 174, 20, 20);
TextureArrowUp = "../Black.png" Part(163, 154, 20, 20) Middle(0, 0, 20, 19);
TextureArrowUpHover = "../Black.png" Part(183, 154, 20, 20) Middle(0, 0, 20, 19);
TextureArrowDown = "../Black.png" Part(163, 174, 20, 20) Middle(0, 1, 20, 19);
TextureArrowDownHover = "../Black.png" Part(183, 174, 20, 20) Middle(0, 1, 20, 19);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

BIN
themes/TreeView/Leaf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B