52 #include <boost/preprocessor/cat.hpp> 61 #define ERR_LUA LOG_STREAM(err, log_scripting_lua) 67 int n = list->get_item_count();
73 return list->get_row_grid(i - 1);
74 }
else if(
gui2::multi_page* multi_page = dynamic_cast<gui2::multi_page*>(&w)) {
75 int n = multi_page->get_page_count();
81 return &multi_page->page_grid(i - 1);
82 }
else if(
gui2::tree_view* tree_view = dynamic_cast<gui2::tree_view*>(&w)) {
86 throw std::invalid_argument(
"out of range");
90 int n = tree_view_node->count_children();
92 throw std::invalid_argument(
"out of range");
94 return &tree_view_node->get_child_at(i - 1);
96 int n = stacked_widget->get_layer_count();
98 throw std::invalid_argument(
"out of range");
100 return stacked_widget->get_layer_grid(i - 1);
107 return w.
find(m,
false);
110 using tgetters = std::map<std::string, std::vector<std::function<bool(lua_State*, gui2::widget&, bool)>>>;
113 using tsetters = std::map<std::string, std::vector<std::function<bool(lua_State*, int, gui2::widget&, bool)>>>;
116 template<
typename w
idget_type,
typename value_type>
119 virtual value_type
get(lua_State* L, widget_type&
w)
const = 0;
123 template<
typename w
idget_type,
typename value_type>
126 virtual void set(lua_State* L, widget_type&
w,
const value_type& value)
const = 0;
130 template<
typename w
idget_type,
typename value_type,
typename action_type,
bool setter>
134 using map_type = std::conditional_t<setter, tsetters, tgetters>;
135 using list_type =
typename map_type::mapped_type;
136 using callback_type =
typename list_type::value_type;
139 if constexpr(setter) {
141 fcn = [action = action_type()](lua_State* L,
int idx,
gui2::widget&
w,
bool nop) {
142 if(widget_type* pw = dynamic_cast<widget_type*>(&w)) {
143 if(!nop) action.set(L, *pw, lua_check<value_type>(L, idx));
150 fcn = [action = action_type()](lua_State* L,
gui2::widget&
w,
bool nop) {
151 if(widget_type* pw = dynamic_cast<widget_type*>(&w)) {
152 if(!nop)
lua_push(L, action.get(L, *pw));
158 list_type& list = (*map)[std::string(name_part)];
163 #define WIDGET_GETTER4(name, value_type, widgt_type, id) \ 164 struct BOOST_PP_CAT(getter_, id) : public widget_getter<widgt_type, value_type> { \ 165 value_type get(lua_State* L, widgt_type& w) const override; \ 167 struct BOOST_PP_CAT(getter_adder_, id) { \ 168 BOOST_PP_CAT(getter_adder_, id) () \ 170 register_widget_attribute<widgt_type, value_type, BOOST_PP_CAT(getter_, id), false>(name); \ 173 static BOOST_PP_CAT(getter_adder_, id) BOOST_PP_CAT(getter_adder_instance_, id) ; \ 174 value_type BOOST_PP_CAT(getter_, id)::get([[maybe_unused]] lua_State* L, widgt_type& w) const 177 #define WIDGET_SETTER4(name, value_type, widgt_type, id) \ 178 struct BOOST_PP_CAT(setter_, id) : public widget_setter<widgt_type, value_type> { \ 179 void set(lua_State* L, widgt_type& w, const value_type& value) const override; \ 181 struct BOOST_PP_CAT(setter_adder_, id) { \ 182 BOOST_PP_CAT(setter_adder_, id) ()\ 184 register_widget_attribute<widgt_type, value_type, BOOST_PP_CAT(setter_, id), true>(name); \ 187 static BOOST_PP_CAT(setter_adder_, id) BOOST_PP_CAT(setter_adder_instance_, id); \ 188 void BOOST_PP_CAT(setter_, id)::set([[maybe_unused]] lua_State* L, widgt_type& w, const value_type& value) const 196 #define WIDGET_GETTER(name, value_type, widgt_type) WIDGET_GETTER4(name, value_type, widgt_type, __LINE__) 198 #define WIDGET_SETTER(name, value_type, widgt_type) WIDGET_SETTER4(name, value_type, widgt_type, __LINE__) 205 return w.get_selected_row() + 1;
210 w.select_row(value - 1);
215 return w.get_selected_page() + 1;
220 w.select_page(value -1);
225 return w.current_layer() + 1;
230 w.select_layer(value - 1);
235 return w.get_value() + 1;
240 if(value >
int(
w.num_states())) {
241 throw std::invalid_argument(
"invalid index");
243 w.set_value(value - 1);
248 if(
w.num_states() == 2) {
249 return w.get_value_bool();
251 throw std::invalid_argument(
"invalid widget");
256 w.set_value_bool(value);
261 return w.get_value();
271 return w.get_value();
281 return w.get_maximum_value();
286 w.set_value_range(
w.get_minimum_value(), value);
291 return w.get_minimum_value();
296 w.set_value_range(value,
w.get_maximum_value());
301 return w.get_percentage();
306 w.set_percentage(value);
311 auto res =
w.selected_item()->describe_path();
312 for(
int&
a : res) { ++
a;}
318 auto res =
w.describe_path();
319 for(
int&
a : res) { ++
a;}
335 w.set_displayed_type(*ut);
337 w.set_displayed_unit(*u);
345 return w.get_page_count();
350 return w.get_item_count();
355 w.set_use_markup(value);
364 w.set_use_markup(
true);
375 w.set_tooltip(value);
382 ERR_LUA <<
"gui.widget.set_callback didn't exist";
385 lua_pushvalue(L, value.index);
394 visibility
flag = visibility::visible;
396 switch(lua_type(L, value.index)) {
399 ? visibility::visible
400 : visibility::invisible;
404 const std::string& str = lua_tostring(L, value.index);
405 if(str ==
"visible") {
406 flag = visibility::visible;
407 }
else if(str ==
"hidden") {
408 flag = visibility::hidden;
409 }
else if(str ==
"invisible") {
410 flag = visibility::invisible;
412 luaL_argerror(L, value.index,
"string must be one of: visible, hidden, invisible");
422 if(flag == visibility::hidden) {
445 return sw->get_control_type();
447 else if(dynamic_cast<gui2::tree_view_node*>(&
w)) {
448 return "tree_view_node";
450 else if(dynamic_cast<gui2::grid*>(&
w)) {
467 ERR_LUA <<
"widget was deleted";
472 ERR_LUA <<
"cannot find window in widget callback";
482 throw std::invalid_argument(
"the widget has no window assigned");
484 lua_pushvalue(L, value.index);
494 throw std::invalid_argument(
"the widget has no window assigned");
496 lua_pushvalue(L, value.index);
508 throw std::invalid_argument(
"the widget has no window assigned");
511 throw std::invalid_argument(
"unsupported widget");
513 lua_pushvalue(L, value.index);
526 if(lua_isinteger(L, 2)) {
534 std::string_view str = lua_check<std::string_view>(L, 2);
538 for(
const auto& func : it->second) {
539 if(func(L, w,
false)) {
544 if(
luaW_getglobal(L,
"gui",
"widget", std::string(str).c_str())) {
551 ERR_LUA <<
"invalid property of '" <<
typeid(
w).name()<<
"' widget :" << str;
552 return luaL_argerror(L, 2,
"invalid property of widget");
558 std::string_view str = lua_check<std::string_view>(L, 2);
563 for(
const auto& func : it->second) {
564 if(func(L, 3, w,
false)) {
568 ERR_LUA <<
"none of "<< it->second.size() <<
" setters matched";
571 ERR_LUA <<
"unknown property id : " << str <<
" #known properties=" <<
setters.size();
574 ERR_LUA <<
"invalid modifiable property of '" <<
typeid(
w).name()<<
"' widget:" << str;
575 return luaL_argerror(L, 2,
"invalid modifiable property of widget");
581 std::vector<std::string> keys;
583 for(
const auto& [key, funcs] :
getters) {
584 if(key ==
"value_compat")
continue;
585 for(
const auto& func : funcs) {
586 if(func(L, w,
true)){
593 for(
const auto& [key, funcs] :
setters) {
594 if(key ==
"value_compat")
continue;
595 if(key ==
"callback")
continue;
596 for(
const auto& func : funcs) {
597 if(func(L, 0, w,
true)){
605 for(
auto child = iter_t(w); !child.at_end(); child.next()) {
606 const auto& key = child->
id();
607 if(!key.empty() && key != w.
id()) {
615 auto methods = lua_check<std::vector<std::string>>(L, -1);
616 keys.insert(keys.end(), methods.begin(), methods.end());
Small abstract helper class.
This class represents a single unit of a specific type.
int luaW_type_error(lua_State *L, int narg, const char *tname)
Tmust inherit enable_lua_ptr<T>
This object shows the progress of a certain action, or the value state of a certain item...
void lua_push(lua_State *L, const T &val)
Definitions for the interface to Wesnoth Markup Language (WML).
A single unit type that the player may recruit.
Class for a single line text area.
std::size_t count_children() const
The number of children in this widget.
std::map< std::string, t_string > widget_item
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil...
bool luaW_toboolean(lua_State *L, int n)
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
This file contains the canvas object which is the part where the widgets draw (temporally) images on...
A tree view is a control that holds several items of the same or different types. ...
const unit_type * luaW_tounittype(lua_State *L, int idx)
Test if a stack element is a unit type, and return it if so.
tree_view_node & get_child_at(int index)
static map_location::DIRECTION sw
void split_foreach(std::string_view s, char sep, const int flags, const F &f)
A multi page is a control that contains several 'pages' of which only one is visible.
virtual void connect_click_handler(const event::signal &signal)=0
Connects a signal handler for a 'click' event.
A slider is a control that can select a value by moving a grip on a groove.
Standard logging facilities (interface).
Contains the base iterator class for the gui2 widgets.
void invalidate_layout()
Updates the size of the window.
static map_location::DIRECTION n
base class of top level items, the only item which needs to store the final canvases to draw on...
std::string::const_iterator iterator
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.