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);
75 int n = multi_page->get_page_count();
81 return &multi_page->page_grid(
i - 1);
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);
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();
448 return "tree_view_node";
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());
This file contains the canvas object which is the part where the widgets draw (temporally) images on.
virtual void connect_click_handler(const event::signal &signal)=0
Connects a signal handler for a 'click' event.
A multi page is a control that contains several 'pages' of which only one is visible.
This object shows the progress of a certain action, or the value state of a certain item.
Small abstract helper class.
A slider is a control that can select a value by moving a grip on a groove.
Class for a single line text area.
tree_view_node & get_child_at(int index)
std::size_t count_children() const
The number of children in this widget.
A tree view is a control that holds several items of the same or different types.
base class of top level items, the only item which needs to store the final canvases to draw on.
void invalidate_layout()
Updates the size of the window.
Tmust inherit enable_lua_ptr<T>
A single unit type that the player may recruit.
This class represents a single unit of a specific type.
Contains the base iterator class for the gui2 widgets.
Standard logging facilities (interface).
bool luaW_toboolean(lua_State *L, int n)
int luaW_type_error(lua_State *L, int narg, const char *tname)
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.
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
const unit_type * luaW_tounittype(lua_State *L, int idx)
Test if a stack element is a unit type, and return it if so.
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
std::map< std::string, t_string > widget_item
void split_foreach(std::string_view s, char sep, const int flags, const F &f)
std::string::const_iterator iterator
void lua_push(lua_State *L, const T &val)
static map_location::DIRECTION sw
static map_location::DIRECTION n