44 #include <boost/preprocessor/cat.hpp>
52 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
58 int n = list->get_item_count();
64 return list->get_row_grid(
i - 1);
66 int n = multi_page->get_page_count();
72 return &multi_page->page_grid(
i - 1);
77 throw std::invalid_argument(
"out of range");
81 int n = tree_view_node->count_children();
83 throw std::invalid_argument(
"out of range");
85 return &tree_view_node->get_child_at(
i - 1);
87 int n = stacked_widget->get_layer_count();
89 throw std::invalid_argument(
"out of range");
91 return stacked_widget->get_layer_grid(
i - 1);
98 return w.find(m,
false);
104 using tsetters = std::map<std::string, std::vector<std::function<bool(lua_State*,
int,
gui2::widget&,
bool)>>>;
107 template<
typename w
idget_type,
typename value_type,
typename action_type,
bool setter>
111 using map_type = std::conditional_t<setter, tsetters, tgetters>;
112 using list_type =
typename map_type::mapped_type;
113 using callback_type =
typename list_type::value_type;
118 fcn = [action = action_type()](lua_State* L,
int idx,
gui2::widget&
w,
bool nop) {
119 if(widget_type* pw =
dynamic_cast<widget_type*
>(&
w)) {
120 if(!nop) action.set(L, *pw, lua_check<value_type>(L, idx));
127 fcn = [action = action_type()](lua_State* L,
gui2::widget&
w,
bool nop) {
128 if(widget_type* pw =
dynamic_cast<widget_type*
>(&
w)) {
129 if(!nop)
lua_push(L, action.get(L, *pw));
135 list_type& list = (*map)[std::string(name_part)];
140 #define WIDGET_GETTER4(name, value_type, widgt_type, id) \
141 struct BOOST_PP_CAT(getter_, id) : public lua_getter<widgt_type, value_type> { \
142 value_type get(lua_State* L, const widgt_type& w) const override; \
144 struct BOOST_PP_CAT(getter_adder_, id) { \
145 BOOST_PP_CAT(getter_adder_, id) () \
147 register_widget_attribute<widgt_type, value_type, BOOST_PP_CAT(getter_, id), false>(name); \
150 static BOOST_PP_CAT(getter_adder_, id) BOOST_PP_CAT(getter_adder_instance_, id) ; \
151 value_type BOOST_PP_CAT(getter_, id)::get([[maybe_unused]] lua_State* L, const widgt_type& w) const
154 #define WIDGET_SETTER4(name, value_type, widgt_type, id) \
155 struct BOOST_PP_CAT(setter_, id) : public lua_setter<widgt_type, value_type> { \
156 void set(lua_State* L, widgt_type& w, const value_type& value) const override; \
158 struct BOOST_PP_CAT(setter_adder_, id) { \
159 BOOST_PP_CAT(setter_adder_, id) ()\
161 register_widget_attribute<widgt_type, value_type, BOOST_PP_CAT(setter_, id), true>(name); \
164 static BOOST_PP_CAT(setter_adder_, id) BOOST_PP_CAT(setter_adder_instance_, id); \
165 void BOOST_PP_CAT(setter_, id)::set([[maybe_unused]] lua_State* L, widgt_type& w, const value_type& value) const
173 #define WIDGET_GETTER(name, value_type, widgt_type) WIDGET_GETTER4(name, value_type, widgt_type, __LINE__)
175 #define WIDGET_SETTER(name, value_type, widgt_type) WIDGET_SETTER4(name, value_type, widgt_type, __LINE__)
182 return w.get_selected_row() + 1;
187 w.select_row(value - 1);
192 return w.get_selected_page() + 1;
197 w.select_page(value -1);
202 return w.current_layer() + 1;
207 w.select_layer(value - 1);
212 return w.get_value() + 1;
217 if(value >
int(
w.num_states())) {
218 throw std::invalid_argument(
"invalid index");
220 w.set_value(value - 1);
225 if(
w.num_states() == 2) {
226 return w.get_value_bool();
228 throw std::invalid_argument(
"invalid widget");
233 w.set_value_bool(value);
238 return w.get_value();
248 return w.get_value();
258 return w.get_maximum_value();
263 w.set_value_range(
w.get_minimum_value(), value);
268 return w.get_minimum_value();
273 w.set_value_range(value,
w.get_maximum_value());
278 return w.get_percentage();
283 w.set_percentage(value);
288 auto res =
w.selected_item()->describe_path();
289 for(
int& a : res) { ++a;}
295 auto res =
w.describe_path();
296 for(
int& a : res) { ++a;}
312 w.set_displayed_type(*ut);
314 w.set_displayed_unit(*u);
322 return w.get_page_count();
327 return w.get_item_count();
332 w.set_use_markup(value);
341 w.set_use_markup(
true);
352 w.set_tooltip(value);
359 ERR_LUA <<
"gui.widget.set_callback didn't exist";
362 lua_pushvalue(L, value.index);
371 visibility
flag = visibility::visible;
373 switch(lua_type(L, value.index)) {
376 ? visibility::visible
377 : visibility::invisible;
381 const std::string& str = lua_tostring(L, value.index);
382 if(str ==
"visible") {
383 flag = visibility::visible;
384 }
else if(str ==
"hidden") {
385 flag = visibility::hidden;
386 }
else if(str ==
"invisible") {
387 flag = visibility::invisible;
389 luaL_argerror(L, value.index,
"string must be one of: visible, hidden, invisible");
399 if(
flag == visibility::hidden) {
422 return sw->get_control_type();
425 return "tree_view_node";
444 ERR_LUA <<
"widget was deleted";
449 ERR_LUA <<
"cannot find window in widget callback";
459 throw std::invalid_argument(
"the widget has no window assigned");
461 lua_pushvalue(L, value.index);
471 throw std::invalid_argument(
"the widget has no window assigned");
473 lua_pushvalue(L, value.index);
485 throw std::invalid_argument(
"the widget has no window assigned");
488 throw std::invalid_argument(
"unsupported widget");
490 lua_pushvalue(L, value.index);
503 if(lua_isinteger(L, 2)) {
511 std::string_view str = lua_check<std::string_view>(L, 2);
515 for(
const auto& func : it->second) {
516 if(func(L,
w,
false)) {
521 if(
luaW_getglobal(L,
"gui",
"widget", std::string(str).c_str())) {
528 ERR_LUA <<
"invalid property of '" <<
typeid(
w).name()<<
"' widget :" << str;
529 std::string
err =
"invalid property of widget: ";
531 return luaL_argerror(L, 2,
err.c_str());
537 std::string_view str = lua_check<std::string_view>(L, 2);
542 for(
const auto& func : it->second) {
543 if(func(L, 3,
w,
false)) {
547 ERR_LUA <<
"none of "<< it->second.size() <<
" setters matched";
550 ERR_LUA <<
"unknown property id : " << str <<
" #known properties=" <<
setters.size();
553 ERR_LUA <<
"invalid modifiable property of '" <<
typeid(
w).name()<<
"' widget:" << str;
554 std::string
err =
"invalid modifiable property of widget: ";
556 return luaL_argerror(L, 2,
err.c_str());
562 std::vector<std::string> keys;
564 for(
const auto& [key, funcs] :
getters) {
565 if(key ==
"value_compat")
continue;
566 for(
const auto& func : funcs) {
567 if(func(L,
w,
true)){
574 for(
const auto& [key, funcs] :
setters) {
575 if(key ==
"value_compat")
continue;
576 if(key ==
"callback")
continue;
577 for(
const auto& func : funcs) {
578 if(func(L, 0,
w,
true)){
586 for(
auto child = iter_t(
w); !child.at_end(); child.next()) {
587 const auto& key = child->
id();
588 if(!key.empty() && key !=
w.id()) {
595 keys.insert(keys.end(), methods.begin(), methods.end());
virtual void connect_click_handler(const event::signal &signal)=0
Connects a signal handler for a 'click' event.
Small abstract helper class.
A widget that allows the user to input text in single line.
tree_view_node & get_child_at(int index)
std::size_t count_children() const
The number of children in this widget.
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.
std::vector< std::string > luaW_get_attributes(lua_State *L, int idx)
This function does the actual work of grabbing all the attribute names.
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.
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
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 n
static map_location::direction sw