43 #include <boost/preprocessor/cat.hpp>
51 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
57 int n = list->get_item_count();
63 return list->get_row_grid(
i - 1);
65 int n = multi_page->get_page_count();
71 return &multi_page->page_grid(
i - 1);
76 throw std::invalid_argument(
"out of range");
80 int n = tree_view_node->count_children();
82 throw std::invalid_argument(
"out of range");
84 return &tree_view_node->get_child_at(
i - 1);
86 int n = stacked_widget->get_layer_count();
88 throw std::invalid_argument(
"out of range");
90 return stacked_widget->get_layer_grid(
i - 1);
97 return w.find(m,
false);
103 using tsetters = std::map<std::string, std::vector<std::function<bool(lua_State*,
int,
gui2::widget&,
bool)>>>;
106 template<
typename w
idget_type,
typename value_type>
109 virtual value_type
get(lua_State* L, widget_type&
w)
const = 0;
113 template<
typename w
idget_type,
typename value_type>
116 virtual void set(lua_State* L, widget_type&
w,
const value_type& value)
const = 0;
120 template<
typename w
idget_type,
typename value_type,
typename action_type,
bool setter>
124 using map_type = std::conditional_t<setter, tsetters, tgetters>;
125 using list_type =
typename map_type::mapped_type;
126 using callback_type =
typename list_type::value_type;
129 if constexpr(setter) {
131 fcn = [action = action_type()](lua_State* L,
int idx,
gui2::widget&
w,
bool nop) {
132 if(widget_type* pw =
dynamic_cast<widget_type*
>(&
w)) {
133 if(!nop) action.set(L, *pw, lua_check<value_type>(L, idx));
140 fcn = [action = action_type()](lua_State* L,
gui2::widget&
w,
bool nop) {
141 if(widget_type* pw =
dynamic_cast<widget_type*
>(&
w)) {
142 if(!nop)
lua_push(L, action.get(L, *pw));
148 list_type& list = (*map)[std::string(name_part)];
153 #define WIDGET_GETTER4(name, value_type, widgt_type, id) \
154 struct BOOST_PP_CAT(getter_, id) : public widget_getter<widgt_type, value_type> { \
155 value_type get(lua_State* L, widgt_type& w) const override; \
157 struct BOOST_PP_CAT(getter_adder_, id) { \
158 BOOST_PP_CAT(getter_adder_, id) () \
160 register_widget_attribute<widgt_type, value_type, BOOST_PP_CAT(getter_, id), false>(name); \
163 static BOOST_PP_CAT(getter_adder_, id) BOOST_PP_CAT(getter_adder_instance_, id) ; \
164 value_type BOOST_PP_CAT(getter_, id)::get([[maybe_unused]] lua_State* L, widgt_type& w) const
167 #define WIDGET_SETTER4(name, value_type, widgt_type, id) \
168 struct BOOST_PP_CAT(setter_, id) : public widget_setter<widgt_type, value_type> { \
169 void set(lua_State* L, widgt_type& w, const value_type& value) const override; \
171 struct BOOST_PP_CAT(setter_adder_, id) { \
172 BOOST_PP_CAT(setter_adder_, id) ()\
174 register_widget_attribute<widgt_type, value_type, BOOST_PP_CAT(setter_, id), true>(name); \
177 static BOOST_PP_CAT(setter_adder_, id) BOOST_PP_CAT(setter_adder_instance_, id); \
178 void BOOST_PP_CAT(setter_, id)::set([[maybe_unused]] lua_State* L, widgt_type& w, const value_type& value) const
186 #define WIDGET_GETTER(name, value_type, widgt_type) WIDGET_GETTER4(name, value_type, widgt_type, __LINE__)
188 #define WIDGET_SETTER(name, value_type, widgt_type) WIDGET_SETTER4(name, value_type, widgt_type, __LINE__)
195 return w.get_selected_row() + 1;
200 w.select_row(value - 1);
205 return w.get_selected_page() + 1;
210 w.select_page(value -1);
215 return w.current_layer() + 1;
220 w.select_layer(value - 1);
225 return w.get_value() + 1;
230 if(value >
int(
w.num_states())) {
231 throw std::invalid_argument(
"invalid index");
233 w.set_value(value - 1);
238 if(
w.num_states() == 2) {
239 return w.get_value_bool();
241 throw std::invalid_argument(
"invalid widget");
246 w.set_value_bool(value);
251 return w.get_value();
261 return w.get_value();
271 return w.get_maximum_value();
276 w.set_value_range(
w.get_minimum_value(), value);
281 return w.get_minimum_value();
286 w.set_value_range(value,
w.get_maximum_value());
291 return w.get_percentage();
296 w.set_percentage(value);
301 auto res =
w.selected_item()->describe_path();
302 for(
int&
a : res) { ++
a;}
308 auto res =
w.describe_path();
309 for(
int&
a : res) { ++
a;}
325 w.set_displayed_type(*ut);
327 w.set_displayed_unit(*u);
335 return w.get_page_count();
340 return w.get_item_count();
345 w.set_use_markup(value);
354 w.set_use_markup(
true);
365 w.set_tooltip(value);
372 ERR_LUA <<
"gui.widget.set_callback didn't exist";
375 lua_pushvalue(L, value.index);
384 visibility
flag = visibility::visible;
386 switch(lua_type(L, value.index)) {
389 ? visibility::visible
390 : visibility::invisible;
394 const std::string& str = lua_tostring(L, value.index);
395 if(str ==
"visible") {
396 flag = visibility::visible;
397 }
else if(str ==
"hidden") {
398 flag = visibility::hidden;
399 }
else if(str ==
"invisible") {
400 flag = visibility::invisible;
402 luaL_argerror(L, value.index,
"string must be one of: visible, hidden, invisible");
412 if(
flag == visibility::hidden) {
435 return sw->get_control_type();
438 return "tree_view_node";
457 ERR_LUA <<
"widget was deleted";
462 ERR_LUA <<
"cannot find window in widget callback";
472 throw std::invalid_argument(
"the widget has no window assigned");
474 lua_pushvalue(L, value.index);
484 throw std::invalid_argument(
"the widget has no window assigned");
486 lua_pushvalue(L, value.index);
498 throw std::invalid_argument(
"the widget has no window assigned");
501 throw std::invalid_argument(
"unsupported widget");
503 lua_pushvalue(L, value.index);
516 if(lua_isinteger(L, 2)) {
524 std::string_view str = lua_check<std::string_view>(L, 2);
528 for(
const auto& func : it->second) {
529 if(func(L,
w,
false)) {
534 if(
luaW_getglobal(L,
"gui",
"widget", std::string(str).c_str())) {
541 ERR_LUA <<
"invalid property of '" <<
typeid(
w).name()<<
"' widget :" << str;
542 return luaL_argerror(L, 2,
"invalid property of widget");
548 std::string_view str = lua_check<std::string_view>(L, 2);
553 for(
const auto& func : it->second) {
554 if(func(L, 3,
w,
false)) {
558 ERR_LUA <<
"none of "<< it->second.size() <<
" setters matched";
561 ERR_LUA <<
"unknown property id : " << str <<
" #known properties=" <<
setters.size();
564 ERR_LUA <<
"invalid modifiable property of '" <<
typeid(
w).name()<<
"' widget:" << str;
565 return luaL_argerror(L, 2,
"invalid modifiable property of widget");
571 std::vector<std::string> keys;
573 for(
const auto& [key, funcs] :
getters) {
574 if(key ==
"value_compat")
continue;
575 for(
const auto& func : funcs) {
576 if(func(L,
w,
true)){
583 for(
const auto& [key, funcs] :
setters) {
584 if(key ==
"value_compat")
continue;
585 if(key ==
"callback")
continue;
586 for(
const auto& func : funcs) {
587 if(func(L, 0,
w,
true)){
595 for(
auto child = iter_t(
w); !child.at_end(); child.next()) {
596 const auto& key = child->
id();
597 if(!key.empty() && key !=
w.id()) {
604 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.
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.
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.
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