GUI2 LuaAPI: expand widget attr support (#9497)

This commit is contained in:
white-haired-uncle 2024-11-19 22:41:47 -05:00 committed by GitHub
parent 484116ea09
commit c2b2664eb2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 557 additions and 7 deletions

View file

@ -45,6 +45,34 @@ public:
max_input_length_ = length;
}
std::size_t get_max_input_length() const
{
return max_input_length_;
}
void set_hint_text(const std::string& text)
{
hint_text_ = text;
update_canvas();
}
std::string get_hint_text() const
{
return hint_text_;
}
void set_hint_image(const std::string& image)
{
hint_image_ = image;
update_canvas();
}
std::string get_hint_image() const
{
return hint_image_;
}
void set_hint_data(const std::string& text, const std::string& image)
{
hint_text_ = text;
@ -58,6 +86,11 @@ public:
set_value("");
}
int get_item_count() const
{
return values_.size();
}
void set_values(const std::vector<::config>& values, unsigned selected = 0);
void set_selected(unsigned selected, bool fire_event = true);
unsigned get_selected() const { return selected_; }

View file

@ -66,6 +66,12 @@ public:
void set_text_alpha(unsigned short alpha);
/** See @ref styled_widget::get_link_aware. */
virtual bool get_link_aware() const override
{
return link_aware_;
}
void set_link_aware(bool l);
void set_text_max_width(int max_width) {

View file

@ -80,7 +80,7 @@ public:
editable_ = editable;
}
bool is_editable()
bool is_editable() const
{
return editable_;
}

View file

@ -87,6 +87,11 @@ public:
queue_redraw(); // TODO: draw_manager - does the above change the size?
}
unsigned get_best_slider_length() const
{
return best_slider_length_;
}
void set_value_range(int min_value, int max_value);
void set_minimum_value_label(const t_string& minimum_value_label)
@ -94,11 +99,21 @@ public:
minimum_value_label_ = minimum_value_label;
}
t_string get_minimum_value_label() const
{
return minimum_value_label_;
}
void set_maximum_value_label(const t_string& maximum_value_label)
{
maximum_value_label_ = maximum_value_label;
}
t_string get_maximum_value_label() const
{
return maximum_value_label_;
}
void set_value_labels(const std::vector<t_string>& value_labels);
using label_generator = std::function<t_string(int /*current position*/, int /*num positions*/)>;

View file

@ -146,6 +146,33 @@ public:
max_input_length_ = length;
}
std::size_t get_max_input_length() const
{
return max_input_length_;
}
void set_hint_text(const std::string& text)
{
hint_text_ = text;
update_canvas();
}
std::string get_hint_text() const
{
return hint_text_;
}
void set_hint_image(const std::string& image)
{
hint_image_ = image;
update_canvas();
}
std::string get_hint_image() const
{
return hint_image_;
}
void set_hint_data(const std::string& text, const std::string& image)
{
hint_text_ = text;

View file

@ -196,7 +196,7 @@ public:
/**
* Check whether text can be edited or not
*/
bool is_editable()
bool is_editable() const
{
return editable_;
}

View file

@ -50,6 +50,11 @@ public:
using scrollbar_container::finalize_setup;
const tree_view_node& get_root_node() const
{
return *root_node_;
}
tree_view_node& get_root_node()
{
return *root_node_;
@ -85,6 +90,11 @@ public:
indentation_step_size_ = indentation_step_size;
}
unsigned get_indentation_step_size() const
{
return indentation_step_size_;
}
tree_view_node* selected_item()
{
return selected_item_;

View file

@ -461,6 +461,11 @@ protected:
public:
void set_linked_group(const std::string& linked_group);
std::string get_linked_group() const
{
return linked_group_;
}
/*** *** *** *** *** *** *** *** Members. *** *** *** *** *** *** *** ***/
private:

View file

@ -16,9 +16,14 @@
#include "gui/auxiliary/iterator/iterator.hpp"
#include "gui/widgets/clickable_item.hpp"
#include "gui/widgets/styled_widget.hpp"
#include "gui/widgets/combobox.hpp"
#include "gui/widgets/label.hpp"
#include "gui/widgets/listbox.hpp"
#include "gui/widgets/multi_page.hpp"
#include "gui/widgets/progress_bar.hpp"
#include "gui/widgets/rich_label.hpp"
#include "gui/widgets/scroll_label.hpp"
#include "gui/widgets/scroll_text.hpp"
#include "gui/widgets/selectable_item.hpp"
#include "gui/widgets/slider.hpp"
#include "gui/widgets/stacked_widget.hpp"
@ -47,10 +52,11 @@
#include <utility>
#include <vector>
static lg::log_domain log_scripting_lua("scripting/lua");
#define ERR_LUA LOG_STREAM(err, log_scripting_lua)
#define INVALIDATE_LAYOUT() if(auto window = w.get_window()) { window->invalidate_layout(); }
static gui2::widget* find_child_by_index(gui2::widget& w, int i)
{
assert(i > 0);
@ -253,6 +259,19 @@ WIDGET_SETTER("value_compat,value", int, gui2::slider)
w.set_value(value);
}
WIDGET_GETTER("best_slider_length", int, gui2::slider)
{
return w.get_best_slider_length();
}
WIDGET_SETTER("best_slider_length", int, gui2::slider)
{
if(value < 0) {
throw std::invalid_argument("best_slider_length must be >= 0");
}
w.set_best_slider_length(value);
}
WIDGET_GETTER("max_value", int, gui2::slider)
{
return w.get_maximum_value();
@ -263,6 +282,17 @@ WIDGET_SETTER("max_value", int, gui2::slider)
w.set_value_range(w.get_minimum_value(), value);
}
WIDGET_GETTER("maximum_value_label", t_string, gui2::slider)
{
return w.get_maximum_value_label();
}
WIDGET_SETTER("maximum_value_label", t_string, gui2::slider)
{
w.set_maximum_value_label(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("min_value", int, gui2::slider)
{
return w.get_minimum_value();
@ -273,6 +303,17 @@ WIDGET_SETTER("min_value", int, gui2::slider)
w.set_value_range(value, w.get_maximum_value());
}
WIDGET_GETTER("minimum_value_label", t_string, gui2::slider)
{
return w.get_minimum_value_label();
}
WIDGET_SETTER("minimum_value_label", t_string, gui2::slider)
{
w.set_minimum_value_label(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("value_compat,percentage", int, gui2::progress_bar)
{
return w.get_percentage();
@ -297,6 +338,25 @@ WIDGET_GETTER("path", std::vector<int>, gui2::tree_view_node)
return res;
}
WIDGET_GETTER("unfolded", bool, gui2::tree_view)
{
return !w.get_root_node().is_folded();
}
WIDGET_SETTER("value_compat,unfolded", bool, gui2::tree_view)
{
if(value) {
w.get_root_node().unfold();
} else {
w.get_root_node().fold();
}
}
WIDGET_GETTER("unfolded", bool, gui2::tree_view_node)
{
return !w.is_folded();
}
WIDGET_SETTER("value_compat,unfolded", bool, gui2::tree_view_node)
{
if(value) {
@ -317,9 +377,9 @@ WIDGET_SETTER("value_compat,unit", lua_index_raw, gui2::unit_preview_pane)
}
}
WIDGET_GETTER("item_count", int, gui2::multi_page)
WIDGET_GETTER("item_count", int, gui2::combobox)
{
return w.get_page_count();
return w.get_item_count();
}
WIDGET_GETTER("item_count", int, gui2::listbox)
@ -327,6 +387,32 @@ WIDGET_GETTER("item_count", int, gui2::listbox)
return w.get_item_count();
}
WIDGET_GETTER("item_count", int, gui2::multi_page)
{
return w.get_page_count();
}
WIDGET_GETTER("item_count", int, gui2::stacked_widget)
{
return w.get_layer_count();
}
WIDGET_GETTER("item_count", int, gui2::tree_view)
{
const gui2::tree_view_node& tvn = w.get_root_node();
return tvn.count_children();
}
WIDGET_GETTER("item_count", int, gui2::tree_view_node)
{
return w.count_children();
}
WIDGET_GETTER("use_markup", bool, gui2::styled_widget)
{
return w.get_use_markup();
}
WIDGET_SETTER("use_markup", bool, gui2::styled_widget)
{
w.set_use_markup(value);
@ -342,16 +428,316 @@ WIDGET_SETTER("marked_up_text", t_string, gui2::styled_widget)
w.set_label(value);
}
WIDGET_GETTER("characters_per_line", int, gui2::label)
{
return w.get_characters_per_line();
}
WIDGET_SETTER("characters_per_line", int, gui2::label)
{
if(value < 0) {
throw std::invalid_argument("characters_per_line must be >= 0");
}
w.set_characters_per_line(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("editable", bool, gui2::text_box)
{
return w.is_editable();
}
WIDGET_SETTER("editable", bool, gui2::text_box)
{
w.set_editable(value);
}
WIDGET_GETTER("ellipsize_mode", std::string, gui2::styled_widget)
{
std::string s;
switch(w.get_text_ellipse_mode()) {
case(PangoEllipsizeMode::PANGO_ELLIPSIZE_NONE):
s = "none";
break;
case(PangoEllipsizeMode::PANGO_ELLIPSIZE_START):
s = "start";
break;
case(PangoEllipsizeMode::PANGO_ELLIPSIZE_MIDDLE):
s = "middle";
break;
case(PangoEllipsizeMode::PANGO_ELLIPSIZE_END):
s = "end";
}
return s;
}
WIDGET_SETTER("ellipsize_mode", std::string, gui2::styled_widget)
{
if(value == "none") {
w.set_text_ellipse_mode(PangoEllipsizeMode::PANGO_ELLIPSIZE_NONE);
} else if(value == "start") {
w.set_text_ellipse_mode(PangoEllipsizeMode::PANGO_ELLIPSIZE_START);
} else if(value == "middle") {
w.set_text_ellipse_mode(PangoEllipsizeMode::PANGO_ELLIPSIZE_MIDDLE);
} else if(value == "end") {
w.set_text_ellipse_mode(PangoEllipsizeMode::PANGO_ELLIPSIZE_END);
} else {
throw std::invalid_argument("ellipsize_mode must be one of <none,start,middle,end>");
}
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("enabled", bool, gui2::styled_widget)
{
return w.get_active();
}
WIDGET_SETTER("enabled", bool, gui2::styled_widget)
{
w.set_active(value);
}
WIDGET_GETTER("help", t_string, gui2::styled_widget)
{
return w.help_message();
}
WIDGET_SETTER("help", t_string, gui2::styled_widget)
{
w.set_help_message(value);
}
WIDGET_GETTER("hint_image", std::string, gui2::combobox)
{
return w.get_hint_image();
}
WIDGET_SETTER("hint_image", std::string, gui2::combobox)
{
w.set_hint_image(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("hint_text", t_string, gui2::combobox)
{
return w.get_hint_text();
}
WIDGET_SETTER("hint_text", t_string, gui2::combobox)
{
w.set_hint_text(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("hint_image", std::string, gui2::text_box)
{
return w.get_hint_image();
}
WIDGET_SETTER("hint_image", std::string, gui2::text_box)
{
w.set_hint_image(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("hint_text", t_string, gui2::text_box)
{
return w.get_hint_text();
}
WIDGET_SETTER("hint_text", t_string, gui2::text_box)
{
w.set_hint_text(value);
INVALIDATE_LAYOUT();
}
WIDGET_SETTER("history", std::string, gui2::text_box)
{
w.set_history(value);
}
WIDGET_GETTER("indentation_step_size", int, gui2::tree_view)
{
return w.get_indentation_step_size();
}
WIDGET_SETTER("indentation_step_size", int, gui2::tree_view)
{
if(value < 0) {
throw std::invalid_argument("indentation_step_size must be >= 0");
}
w.set_indentation_step_size(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("link_aware", bool, gui2::label)
{
return w.get_link_aware();
}
WIDGET_SETTER("link_aware", bool, gui2::label)
{
w.set_link_aware(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("link_aware", bool, gui2::rich_label)
{
return w.get_link_aware();
}
WIDGET_SETTER("link_aware", bool, gui2::rich_label)
{
w.set_link_aware(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("link_aware", bool, gui2::scroll_label)
{
return w.get_link_aware();
}
WIDGET_SETTER("link_aware", bool, gui2::scroll_label)
{
w.set_link_aware(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("link_aware", bool, gui2::scroll_text)
{
return w.get_link_aware();
}
WIDGET_SETTER("link_aware", bool, gui2::scroll_text)
{
w.set_link_aware(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("link_color", std::string, gui2::label)
{
return w.get_link_color().to_hex_string();
}
WIDGET_GETTER("link_color", std::string, gui2::rich_label)
{
return w.get_link_color().to_hex_string();
}
WIDGET_GETTER("max_input_length", int, gui2::combobox)
{
return w.get_max_input_length();
}
WIDGET_SETTER("max_input_length", int, gui2::combobox)
{
if(value < 0) {
throw std::invalid_argument("max_input_length must be >= 0");
}
w.set_max_input_length(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("max_input_length", int, gui2::text_box)
{
return w.get_max_input_length();
}
WIDGET_SETTER("max_input_length", int, gui2::text_box)
{
if(value < 0) {
throw std::invalid_argument("max_input_length must be >= 0");
}
w.set_max_input_length(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("step_size", int, gui2::slider)
{
return w.get_step_size();
}
WIDGET_SETTER("step_size", int, gui2::slider)
{
if(value < 0) {
throw std::invalid_argument("step_size must be >= 0");
}
w.set_step_size(value);
}
WIDGET_GETTER("text_alignment", std::string, gui2::styled_widget)
{
std::string s;
switch(w.get_text_alignment()) {
case(PangoAlignment::PANGO_ALIGN_LEFT):
s = "left";
break;
case(PangoAlignment::PANGO_ALIGN_RIGHT):
s = "right";
break;
case(PangoAlignment::PANGO_ALIGN_CENTER):
s = "center";
}
return s;
}
WIDGET_SETTER("text_alignment", std::string, gui2::styled_widget)
{
if(value == "left") {
w.set_text_alignment(PangoAlignment::PANGO_ALIGN_LEFT);
} else if(value == "right") {
w.set_text_alignment(PangoAlignment::PANGO_ALIGN_RIGHT);
} else if(value == "center") {
w.set_text_alignment(PangoAlignment::PANGO_ALIGN_CENTER);
} else {
throw std::invalid_argument("text_alignment must be one of <left,center,right>");
}
}
WIDGET_GETTER("tooltip", t_string, gui2::styled_widget)
{
return w.tooltip();
}
WIDGET_SETTER("tooltip", t_string, gui2::styled_widget)
{
w.set_tooltip(value);
}
WIDGET_GETTER("overflow_to_tooltip", bool, gui2::styled_widget)
{
return w.get_use_tooltip_on_label_overflow();
}
WIDGET_SETTER("overflow_to_tooltip", bool, gui2::styled_widget)
{
w.set_use_tooltip_on_label_overflow(value);
INVALIDATE_LAYOUT();
}
WIDGET_GETTER("wrap", bool, gui2::label)
{
return w.can_wrap();
}
WIDGET_SETTER("wrap", bool, gui2::label)
{
w.set_can_wrap(value);
}
WIDGET_GETTER("wrap", bool, gui2::rich_label)
{
return w.can_wrap();
}
WIDGET_SETTER("wrap", bool, gui2::rich_label)
{
w.set_can_wrap(value);
}
WIDGET_SETTER("callback", lua_index_raw, gui2::widget)
{
@ -363,6 +749,24 @@ WIDGET_SETTER("callback", lua_index_raw, gui2::widget)
lua_call(L, 2, 0);
}
WIDGET_GETTER("visible", std::string, gui2::styled_widget)
{
std::string s;
switch(w.get_visible()) {
case gui2::styled_widget::visibility::visible:
s = "visible";
break;
case gui2::styled_widget::visibility::hidden:
s = "hidden";
break;
case gui2::styled_widget::visibility::invisible:
s = "invisible";
}
return s;
}
WIDGET_SETTER("visible", lua_index_raw, gui2::styled_widget)
{
@ -406,6 +810,11 @@ WIDGET_SETTER("visible", lua_index_raw, gui2::styled_widget)
}
}
WIDGET_GETTER("value_compat,label", t_string, gui2::styled_widget)
{
return w.get_label();
}
//must be last
WIDGET_SETTER("value_compat,label", t_string, gui2::styled_widget)
{

View file

@ -22,4 +22,5 @@ int impl_widget_get(lua_State* L);
int impl_widget_set(lua_State* L);
int impl_widget_dir(lua_State* L);
} // end namespace lua_gui2
} // end namespace lua_widget

View file

@ -1,5 +1,5 @@
These files can be used to allow Lua linting tools to understand Wesnoth types and functions that are defined in C++. Documentation of the annotations format can be found [here](https://github.com/sumneko/lua-language-server/wiki/EmmyLua-Annotations).
These files can be used to allow Lua linting tools to understand Wesnoth types and functions that are defined in C++. Documentation of the annotations format can be found [here](https://luals.github.io/wiki/annotations/).
To enable in Visual Studio Code, install [this Lua plugin](https://marketplace.visualstudio.com/items?itemName=sumneko.lua) and add the following settings to your settings.json:

View file

@ -101,9 +101,13 @@ function gui.add_widget_definition(type, id, content) end
---A reference to a widget in a custom dialog box
---@class widget : gui.widget
---@field enabled boolean
---@field help tstring
---@field tooltip tstring
---@field visible boolean|"'visible'"|"'hidden'"|"'invisible'"
---@field type string
---@field text_alignment "'left'"|"'right'"|"'center'"
---@field ellipsize_mode "'none'"|"'start'"|"'middle'"|"'end'"
---@field overflow_to_tooltip boolean
---@field on_left_click fun()
---The window widget is a container that contains all other widgets in the dialog
@ -141,22 +145,49 @@ function gui.add_widget_definition(type, id, content) end
---A container widget whose children all occupy the same space, overlayed on top of each other
---@class stacked_widget : widget
---@field selected_index integer
---@field item_count integer
---A button that produces a dropdown menu when clicked
---@class menu_button : widget
---@field selected_index integer
---@field on_modified fun()
---A button that produces a dropdown menu when clicked in addition to supporting text input
---@class combobox : widget
---@field hint_image string
---@field hint_text tstring
---@field item_count integer
---@field max_input_length integer
---@field selected_index integer
---@field on_modified fun()
---An editable text box
---@class text_box : widget
---@field text string
---@field editable boolean
---@field hint_image string
---@field hint_text tstring
---@field history string
---@field max_input_length integer
---@field on_modified fun()
---A label that wraps its text and also has a vertical scrollbar
---@class scroll_label : widget
---@field link_aware boolean
---A multiline text area that shows a scrollbar if the text gets too long
---@class scroll_text : widget
---@field link_aware boolean
---A slider
---@class slider : widget
---@field value integer
---@field min_value integer
---@field max_value integer
---@field best_slider_length integer
---@field maximum_value_label tstring
---@field minimum_value_label tstring
---@field step_size integer
---@field on_modified fun()
---A progress bar
@ -166,11 +197,14 @@ function gui.add_widget_definition(type, id, content) end
---A dynamic, hierarchical list of items, shown with a scrollbar
---@class treeview : widget
---@field selected_item_path integer[]
---@field item_count integer
---@field unfolded boolean
---@field on_modified fun()
---A single node in a tree view
---@class tree_view_node : widget
---@field path integer[]
---@field item_count integer
---@field unfolded boolean
---A panel that shows details on a given unit or unit type
@ -183,6 +217,16 @@ function gui.add_widget_definition(type, id, content) end
---A static text label
---@class label : simple_widget
---@field characters_per_line integer
---@field link_aware boolean
---@field link_color string
---@field wrap boolean
---A label that shows formatted text marked up with Help markup
---@class rich_label : simple_widget
---@field link_color string
---@field wrap boolean
---A simple image
---@class image : simple_widget
---A simple button that triggers repeatedly if the mouse is held down