![]() |
Freeciv21
Develop your civilization from humble roots to a global empire
|
A widget that lets the user distribute a fixed number of items across multiple categories. More...
#include <multi_slider.h>
Inheritance diagram for freeciv::multi_slider:
Collaboration diagram for freeciv::multi_slider:Classes | |
| struct | category |
| struct | handle |
Signals | |
| void | values_changed (const std::vector< int > &values) const |
Public Member Functions | |
| multi_slider (QWidget *parent=nullptr) | |
| Constructor. More... | |
| virtual | ~multi_slider ()=default |
| std::size_t | add_category (const QPixmap &icon) |
| Adds a category. More... | |
| void | set_range (std::size_t category, int min, int max) |
| Sets the minimum and maximum number of items a category can have. More... | |
| std::vector< int > | values () const |
| Retrieves the number of items in each category. More... | |
| void | set_values (const std::vector< int > &values) |
| Sets the contents of all item categories. More... | |
| QSize | sizeHint () const override |
| Preferred size of the widget. More... | |
| QSize | minimumSizeHint () const override |
| Minimum size of the widget. More... | |
| std::size_t | total () const |
| Returns the total number of items controlled by this widget. More... | |
Protected Member Functions | |
| bool | event (QEvent *event) override |
| Overrides tab handling to also cycle through visible categories. More... | |
| void | focusInEvent (QFocusEvent *event) override |
| Focuses the first or last category when focus is gained with the keyboard. More... | |
| void | keyPressEvent (QKeyEvent *event) override |
| Handles arrow keys: left/right to change the focused category, up/down to add or remove items. More... | |
| void | leaveEvent (QEvent *event) override |
| Sopts highlighting the closest handle. More... | |
| void | mouseDoubleClickEvent (QMouseEvent *event) override |
| Moves the closest handle when double-clicking. More... | |
| void | mouseMoveEvent (QMouseEvent *event) override |
| Moves the current handle when dragging the mouse. More... | |
| void | mousePressEvent (QMouseEvent *event) override |
| Sets the current handle when pressing a mouse button. More... | |
| void | mouseReleaseEvent (QMouseEvent *event) override |
| Unsets the current handle when releasing a mouse button. More... | |
| void | paintEvent (QPaintEvent *event) override |
| Draws the widget. More... | |
| void | resizeEvent (QResizeEvent *event) override |
| Updates cached geometry information. More... | |
Private Member Functions | |
| void | exchange (std::size_t giver, std::size_t taker, int amount) |
| Exchange items between two categories. More... | |
| bool | grab_item (std::size_t taker, int amount, bool from_left=true, bool from_right=true) |
Grab an item from elsewhere and adds it to the taker category. More... | |
| void | focus_some_category () |
| Makes sure the focused category is a visible one. More... | |
| bool | move_focus (bool forward) |
| Moves focus to the next or previous visible category. More... | |
| int | handle_near (const QPoint &where) |
| Finds the index of the handle closest to the given position. More... | |
| bool | move_handle (int handle, const QPoint &where) |
| Tries to move a handle closer to a given position. More... | |
| void | update_cached_geometry () |
| Updates cached geometry information. More... | |
| std::vector< handle > | visible_handles () const |
| Returns the list of all visible handles. More... | |
Private Attributes | |
| std::vector< category > | m_categories |
| Category data. More... | |
| std::vector< int > | m_values |
| Number of items in each category. More... | |
| int | m_focused_category = 0 |
| Index of the category receiving keyboard input. More... | |
| int | m_closest_handle = -1 |
| Index of the handle being dragged with the mouse. More... | |
| int | m_dragged_handle = -1 |
| struct { | |
| int icons_width = 1 | |
| Width of the area covered with icons. More... | |
| int left_margin = 0 | |
| Empty space left of the icons. More... | |
| double item_width = 1 | |
| The logical width of one item. More... | |
| } | m_geom |
| Cached geometry information. More... | |
A widget that lets the user distribute a fixed number of items across multiple categories.
This widget provides a slider with multiple handles. The width of the slider represents a number of items that the user can distribute across multiple categories. For instance, the items could be citizens that would be distributed to perform various tasks.
The widget needs an icon for each category. The icon should represent a single item in the category. When possible, the widget displays each item using one complete icon. It is important that all icons be of the same size.
Categories are initially added with add_category. A minimum and maximum number of items in each category can optionally be set with set_range. The displayed values are set using set_values and recovered with values. The signal values_changed is emitted each time the user redistributes items (which can be quite frequent).
Users can interact with this widget using the keyboard or the mouse, with interaction patterns optimized for each device. When using the keyboard, the user can navigate between categories using the left and right arrow keys, and add or remove items to the current category using the up and down arrows. Of course, in doing so they also modify other categories. The current category is indicated with a slight underline and is also integrated in tab navigation.
When using the mouse, the user can grab handles shown between categories and drag them wherever they want to adjust the number of items. It is also possible to double-click, which moves the closest handle to the location pointed to by the mouse.
It is a good idea to have a legend explaining what the icons mean next to this widget, as it is not self-explanatory.
Definition at line 13 of file multi_slider.h.
|
explicit |
Constructor.
Definition at line 106 of file multi_slider.cpp.
|
virtualdefault |
| std::size_t freeciv::multi_slider::add_category | ( | const QPixmap & | icon | ) |
Adds a category.
| icon | An icon representing a single item in the category. All icons must have the same size. |
Definition at line 120 of file multi_slider.cpp.
Referenced by national_budget_dialog::refresh().
|
overrideprotected |
Overrides tab handling to also cycle through visible categories.
Definition at line 217 of file multi_slider.cpp.
Referenced by focusInEvent(), keyPressEvent(), leaveEvent(), mouseDoubleClickEvent(), mouseMoveEvent(), mousePressEvent(), and mouseReleaseEvent().
|
private |
Exchange items between two categories.
Definition at line 441 of file multi_slider.cpp.
Referenced by grab_item().
|
private |
Makes sure the focused category is a visible one.
Definition at line 495 of file multi_slider.cpp.
Referenced by exchange().
|
overrideprotected |
Focuses the first or last category when focus is gained with the keyboard.
Definition at line 239 of file multi_slider.cpp.
|
private |
Grab an item from elsewhere and adds it to the taker category.
| taker | Index of the category to add an item to. |
| amount | -1 to give an item away instead. |
| from_left | Allows taking items from (or giving them to) categories on the left of taker. |
| from_right | Allows taking items from (or giving them to) categories on the right of taker. |
Definition at line 458 of file multi_slider.cpp.
Referenced by keyPressEvent(), and move_handle().
|
private |
Finds the index of the handle closest to the given position.
Definition at line 532 of file multi_slider.cpp.
Referenced by mouseDoubleClickEvent(), mouseMoveEvent(), and mousePressEvent().
|
overrideprotected |
Handles arrow keys: left/right to change the focused category, up/down to add or remove items.
Definition at line 258 of file multi_slider.cpp.
|
overrideprotected |
Sopts highlighting the closest handle.
Definition at line 302 of file multi_slider.cpp.
|
override |
Minimum size of the widget.
The width is 5 times the number of items plus extra space for handles, the height is the icon height plus space for handles.
Definition at line 203 of file multi_slider.cpp.
|
overrideprotected |
Moves the closest handle when double-clicking.
Definition at line 312 of file multi_slider.cpp.
|
overrideprotected |
Moves the current handle when dragging the mouse.
Definition at line 325 of file multi_slider.cpp.
|
overrideprotected |
Sets the current handle when pressing a mouse button.
Definition at line 346 of file multi_slider.cpp.
|
overrideprotected |
Unsets the current handle when releasing a mouse button.
Definition at line 359 of file multi_slider.cpp.
|
private |
Moves focus to the next or previous visible category.
| forward | Whether to move focus to the right (true) or to the left (false). |
Definition at line 514 of file multi_slider.cpp.
Referenced by event(), focus_some_category(), and keyPressEvent().
|
private |
Tries to move a handle closer to a given position.
| handle | The index of the handle to move. |
| where | The location where to move it. |
Definition at line 553 of file multi_slider.cpp.
Referenced by mouseDoubleClickEvent(), and mouseMoveEvent().
|
overrideprotected |
Draws the widget.
Definition at line 369 of file multi_slider.cpp.
|
overrideprotected |
Updates cached geometry information.
Definition at line 432 of file multi_slider.cpp.
| void freeciv::multi_slider::set_range | ( | std::size_t | category, |
| int | min, | ||
| int | max | ||
| ) |
Sets the minimum and maximum number of items a category can have.
By default the minimum is zero and the maximum is very large.
| category | The index of the category to modify. |
| min | The smallest allowed value, may not be smaller than zero. |
| max | The largest allowed value. |
Definition at line 142 of file multi_slider.cpp.
Referenced by national_budget_dialog::refresh().
| void freeciv::multi_slider::set_values | ( | const std::vector< int > & | values | ) |
Sets the contents of all item categories.
Definition at line 161 of file multi_slider.cpp.
Referenced by national_budget_dialog::refresh().
|
override |
Preferred size of the widget.
The width is the icon width times the number of items plus extra space for handles, the height is the icon height plus space for handles.
Definition at line 186 of file multi_slider.cpp.
| std::size_t freeciv::multi_slider::total | ( | ) | const |
Returns the total number of items controlled by this widget.
Definition at line 175 of file multi_slider.cpp.
Referenced by minimumSizeHint(), paintEvent(), sizeHint(), and update_cached_geometry().
|
private |
Updates cached geometry information.
Definition at line 584 of file multi_slider.cpp.
Referenced by resizeEvent(), set_range(), and set_values().
|
inline |
Retrieves the number of items in each category.
Definition at line 40 of file multi_slider.h.
Referenced by national_budget_dialog::apply(), keyPressEvent(), move_handle(), and set_values().
|
signal |
Referenced by keyPressEvent(), move_handle(), and set_values().
|
private |
Returns the list of all visible handles.
Definition at line 615 of file multi_slider.cpp.
Referenced by handle_near(), and paintEvent().
| int freeciv::multi_slider::icons_width = 1 |
Width of the area covered with icons.
Definition at line 94 of file multi_slider.h.
| double freeciv::multi_slider::item_width = 1 |
The logical width of one item.
Definition at line 96 of file multi_slider.h.
| int freeciv::multi_slider::left_margin = 0 |
Empty space left of the icons.
Definition at line 95 of file multi_slider.h.
|
private |
Category data.
Definition at line 79 of file multi_slider.h.
Referenced by add_category(), focus_some_category(), focusInEvent(), grab_item(), keyPressEvent(), minimumSizeHint(), move_focus(), paintEvent(), set_range(), set_values(), sizeHint(), and update_cached_geometry().
|
private |
Index of the handle being dragged with the mouse.
Definition at line 89 of file multi_slider.h.
Referenced by leaveEvent(), mouseMoveEvent(), and paintEvent().
|
private |
Definition at line 90 of file multi_slider.h.
Referenced by mouseMoveEvent(), mousePressEvent(), mouseReleaseEvent(), and paintEvent().
|
private |
Index of the category receiving keyboard input.
Definition at line 86 of file multi_slider.h.
Referenced by focus_some_category(), focusInEvent(), keyPressEvent(), move_focus(), and paintEvent().
| struct { ... } freeciv::multi_slider::m_geom |
Cached geometry information.
Referenced by handle_near(), move_handle(), paintEvent(), and update_cached_geometry().
|
private |
Number of items in each category.
Definition at line 83 of file multi_slider.h.
Referenced by add_category(), exchange(), focus_some_category(), grab_item(), move_focus(), move_handle(), paintEvent(), set_values(), total(), values(), and visible_handles().