The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
lua_gui2.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2016 by Chris Beck <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "lua_gui2.hpp"
16 
18 #include "gui/core/canvas.hpp" // for tcanvas
19 #include "gui/core/window_builder.hpp" // for twindow_builder, etc
24 #include "gui/widgets/clickable.hpp" // for tclickable_
25 #include "gui/widgets/control.hpp" // for tcontrol
26 #include "gui/widgets/multi_page.hpp" // for tmulti_page
27 #include "gui/widgets/progress_bar.hpp" // for tprogress_bar
28 #include "gui/widgets/selectable.hpp" // for tselectable_
29 #include "gui/widgets/slider.hpp" // for tslider
30 #include "gui/widgets/text_box.hpp" // for ttext_box
33 #include "gui/widgets/widget.hpp" // for twidget
34 #include "gui/widgets/window.hpp" // for twindow
35 
36 #ifdef GUI2_EXPERIMENTAL_LISTBOX
37 #include "gui/widgets/list.hpp"
38 #else
39 #include "gui/widgets/listbox.hpp"
40 #endif
41 
42 #include "config.hpp"
43 #include "log.hpp"
44 #include "scripting/lua_api.hpp" // for luaW_toboolean, etc
45 #include "scripting/lua_common.hpp"
46 #include "scripting/lua_types.hpp" // for getunitKey, dlgclbkKey, etc
48 #include "tstring.hpp"
49 
50 #include "utils/functional.hpp"
51 
52 #include <map>
53 #include <utility>
54 #include <vector>
55 
56 #include "lua/lauxlib.h" // for luaL_checkinteger, etc
57 #include "lua/lua.h" // for lua_setfield, etc
58 
59 class CVideo;
60 
61 static lg::log_domain log_scripting_lua("scripting/lua");
62 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
63 
64 static const char * dlgclbkKey = "dialog callback";
65 
66 namespace {
67  struct scoped_dialog
68  {
69  lua_State *L;
70  scoped_dialog *prev;
71  static scoped_dialog *current;
73  typedef std::map<gui2::twidget *, int> callback_map;
74  callback_map callbacks;
75 
76  scoped_dialog(lua_State *l, gui2::twindow *w);
77  ~scoped_dialog();
78  private:
79  scoped_dialog(const scoped_dialog &); // not implemented; not allowed.
80  };
81 
82  scoped_dialog *scoped_dialog::current = nullptr;
83 
84  scoped_dialog::scoped_dialog(lua_State *l, gui2::twindow *w)
85  : L(l), prev(current), window(w), callbacks()
86  {
88  , dlgclbkKey);
89  lua_createtable(L, 1, 0);
90  lua_pushvalue(L, -2);
92  lua_rawseti(L, -2, 1);
94  current = this;
95  }
96 
97  scoped_dialog::~scoped_dialog()
98  {
99  delete window;
100  current = prev;
102  , dlgclbkKey);
103  lua_pushvalue(L, -1);
105  lua_rawgeti(L, -1, 1);
106  lua_remove(L, -2);
108  }
109 }//unnamed namespace for scoped_dialog
110 
111 static gui2::twidget *find_widget(lua_State *L, int i, bool readonly)
112 {
113  if (!scoped_dialog::current) {
114  luaL_error(L, "no visible dialog");
115  error_call_destructors_1:
116  luaL_argerror(L, i, "out of bounds");
117  error_call_destructors_2:
118  luaL_typerror(L, i, "string");
119  error_call_destructors_3:
120  luaL_argerror(L, i, "widget not found");
121  return nullptr;
122  }
123 
124  gui2::twidget *w = scoped_dialog::current->window;
125  for (; !lua_isnoneornil(L, i); ++i)
126  {
127 #ifdef GUI2_EXPERIMENTAL_LISTBOX
128  if (gui2::tlist *l = dynamic_cast<gui2::tlist *>(w))
129 #else
130  if (gui2::tlistbox *l = dynamic_cast<gui2::tlistbox *>(w))
131 #endif
132  {
133  int v = lua_tointeger(L, i);
134  if (v < 1)
135  goto error_call_destructors_1;
136  int n = l->get_item_count();
137  if (v > n) {
138  if (readonly)
139  goto error_call_destructors_1;
140  utils::string_map dummy;
141  for (; n < v; ++n)
142  l->add_row(dummy);
143  }
144  w = l->get_row_grid(v - 1);
145  }
146  else if (gui2::tmulti_page *l = dynamic_cast<gui2::tmulti_page *>(w))
147  {
148  int v = lua_tointeger(L, i);
149  if (v < 1)
150  goto error_call_destructors_1;
151  int n = l->get_page_count();
152  if (v > n) {
153  if (readonly)
154  goto error_call_destructors_1;
155  utils::string_map dummy;
156  for (; n < v; ++n)
157  l->add_page(dummy);
158  }
159  w = &l->page_grid(v - 1);
160  }
161  else if (gui2::ttree_view *tv = dynamic_cast<gui2::ttree_view *>(w))
162  {
163  gui2::ttree_view_node& tvn = tv->get_root_node();
164  if(lua_isnumber(L, i))
165  {
166  int v = lua_tointeger(L, i);
167  if (v < 1)
168  goto error_call_destructors_1;
169  int n = tvn.size();
170  if (v > n) {
171  goto error_call_destructors_1;
172  }
173  w = &tvn.get_child_at(v - 1);
174 
175  }
176  else
177  {
179  w = tvn.find(m, false);
180  }
181  }
182  else if (gui2::ttree_view_node *tvn = dynamic_cast<gui2::ttree_view_node *>(w))
183  {
184  if(lua_isnumber(L, i))
185  {
186  int v = lua_tointeger(L, i);
187  if (v < 1)
188  goto error_call_destructors_1;
189  int n = tvn->size();
190  if (v > n) {
191  goto error_call_destructors_1;
192  }
193  w = &tvn->get_child_at(v - 1);
194 
195  }
196  else
197  {
199  w = tvn->find(m, false);
200  }
201  }
202  else
203  {
204  char const *m = lua_tostring(L, i);
205  if (!m) goto error_call_destructors_2;
206  w = w->find(m, false);
207  }
208  if (!w) goto error_call_destructors_3;
209  }
210 
211  return w;
212 }
213 
214 namespace lua_gui2 {
215 
216 /**
217  * Displays a window.
218  * - Arg 1: WML table describing the window.
219  * - Arg 2: function called at pre-show.
220  * - Arg 3: function called at post-show.
221  * - Ret 1: integer.
222  */
223 int show_dialog(lua_State *L, CVideo & video)
224 {
225  config def_cfg = luaW_checkconfig(L, 1);
226 
228  scoped_dialog w(L, gui2::build(video, &def));
229 
230  if (!lua_isnoneornil(L, 2)) {
231  lua_pushvalue(L, 2);
232  lua_call(L, 0, 0);
233  }
234 
235  int v = scoped_dialog::current->window->show(true, 0);
236 
237  if (!lua_isnoneornil(L, 3)) {
238  lua_pushvalue(L, 3);
239  lua_call(L, 0, 0);
240  }
241 
242  lua_pushinteger(L, v);
243  return 1;
244 }
245 
246 /**
247  * Displays a message window
248  * - Arg 1: Table describing the window
249  * - Arg 2: List of options (nil or empty table - no options)
250  * - Arg 3: Text input specifications (nil or empty table - no text input)
251  * - Ret 1: option chosen (if no options: 0 if there's text input, -2 if escape pressed, else -1)
252  * - Ret 2: string entered (empty if none, nil if no text input)
253  */
255 {
256  config txt_cfg;
257  const bool has_input = !lua_isnoneornil(L, 3) && luaW_toconfig(L, 3, txt_cfg) && !txt_cfg.empty();
258  const std::string& input_caption = txt_cfg["label"];
259  std::string input_text = txt_cfg["text"].str();
260  unsigned int input_max_len = txt_cfg["max_length"].to_int(256);
261 
262  std::vector<gui2::twml_message_option> options;
263  int chosen_option = -1;
264  if (!lua_isnoneornil(L, 2)) {
265  luaL_checktype(L, 2, LUA_TTABLE);
266  size_t n = lua_rawlen(L, 2);
267  for(size_t i = 1; i <= n; i++) {
268  lua_rawgeti(L, 2, i);
269  t_string short_opt;
270  config opt;
271  if(luaW_totstring(L, -1, short_opt)) {
272  // Note: Although this currently uses the tlegacy_menu_item class
273  // for the deprecated syntax, this branch should still be retained
274  // when the deprecated syntax is removed, as a simpler method
275  // of specifying options when only a single string is needed.
276  const std::string& opt_str = short_opt;
277  gui2::tlegacy_menu_item item(opt_str);
278  opt["image"] = item.icon();
279  opt["label"] = item.label();
280  opt["description"] = item.description();
281  opt["default"] = item.is_default();
282  if(!opt["image"].blank() || !opt["description"].blank() || !opt["default"].blank()) {
283  // The exact error message depends on whether & or = was actually present
284  if(opt_str.find_first_of('=') == std::string::npos) {
285  // They just used a simple message, so the other error would be misleading
286  ERR_LUA << "[option]message= is deprecated, use label= instead.\n";
287  } else {
288  ERR_LUA << "The &image=col1=col2 syntax is deprecated, use new DescriptionWML instead.\n";
289  }
290  }
291  } else if(!luaW_toconfig(L, -1, opt)) {
292  std::ostringstream error;
293  error << "expected array of config and/or translatable strings, but index ";
294  error << i << " was a " << lua_typename(L, lua_type(L, -1));
295  return luaL_argerror(L, 2, error.str().c_str());
296  }
297  gui2::twml_message_option option(opt["label"], opt["description"], opt["image"]);
298  if(opt["default"].to_bool(false)) {
299  chosen_option = i - 1;
300  }
301  options.push_back(option);
302  lua_pop(L, 1);
303  }
304  lua_getfield(L, 2, "default");
305  if(lua_isnumber(L, -1)) {
306  int i = lua_tointeger(L, -1);
307  if(i < 1 || size_t(i) > n) {
308  std::ostringstream error;
309  error << "default= key in options list is not a valid option index (1-" << n << ")";
310  return luaL_argerror(L, 2, error.str().c_str());
311  }
312  chosen_option = i - 1;
313  }
314  lua_pop(L, 1);
315  }
316 
317  const config& def_cfg = luaW_checkconfig(L, 1);
318  const std::string& title = def_cfg["title"];
319  const std::string& message = def_cfg["message"];
320  const std::string& portrait = def_cfg["portrait"];
321  const bool left_side = def_cfg["left_side"].to_bool(true);
322  const bool mirror = def_cfg["mirror"].to_bool(false);
323 
324  int dlg_result = gui2::show_wml_message(
325  left_side, video, title, message, portrait, mirror,
326  has_input, input_caption, &input_text, input_max_len,
327  options, &chosen_option
328  );
329 
330  if (!has_input && options.empty()) {
331  lua_pushinteger(L, dlg_result);
332  } else {
333  lua_pushinteger(L, chosen_option + 1);
334  }
335 
336  if (has_input) {
337  lua_pushlstring(L, input_text.c_str(), input_text.length());
338  } else {
339  lua_pushnil(L);
340  }
341 
342  return 2;
343 }
344 
345 /**
346  * Displays a popup message
347  * - Arg 1: Title (allows Pango markup)
348  * - Arg 2: Message (allows Pango markup)
349  * - Arg 3: Image (optional)
350  */
352  std::string title = luaL_checkstring(L, 1);
354  std::string image = lua_isnoneornil(L, 3) ? "" : luaL_checkstring(L, 3);
355 
356  gui2::show_transient_message(video, title, msg, image, true, true);
357  return 0;
358 }
359 
360 /**
361  * Sets the value of a widget on the current dialog.
362  * - Arg 1: scalar.
363  * - Args 2..n: path of strings and integers.
364  */
366 {
367  gui2::twidget *w = find_widget(L, 2, false);
368 
369 #ifdef GUI2_EXPERIMENTAL_LISTBOX
370  if (gui2::tlist *l = dynamic_cast<gui2::tlist *>(w))
371 #else
372  if (gui2::tlistbox *l = dynamic_cast<gui2::tlistbox *>(w))
373 #endif
374  {
375  int v = luaL_checkinteger(L, 1);
376  int n = l->get_item_count();
377  if (1 <= v && v <= n)
378  l->select_row(v - 1);
379  else
380  return luaL_argerror(L, 1, "out of bounds");
381  }
382  else if (gui2::tmulti_page *l = dynamic_cast<gui2::tmulti_page *>(w))
383  {
384  int v = luaL_checkinteger(L, 1);
385  int n = l->get_page_count();
386  if (1 <= v && v <= n)
387  l->select_page(v - 1);
388  else
389  return luaL_argerror(L, 1, "out of bounds");
390  }
391  else if (gui2::tselectable_ *s = dynamic_cast<gui2::tselectable_ *>(w))
392  {
393  if(s->num_states() == 2) {
394  s->set_value_bool(luaW_toboolean(L, 1));
395  }
396  else {
397  s->set_value(luaL_checkinteger(L, 1) -1);
398  }
399  }
400  else if (gui2::ttext_box *t = dynamic_cast<gui2::ttext_box *>(w))
401  {
402  const t_string& text = luaW_checktstring(L, 1);
403  t->set_value(text.str());
404  }
405  else if (gui2::tslider *s = dynamic_cast<gui2::tslider *>(w))
406  {
407  const int v = luaL_checkinteger(L, 1);
408  const int m = s->get_minimum_value();
409  const int n = s->get_maximum_value();
410  if (m <= v && v <= n)
411  s->set_value(v);
412  else
413  return luaL_argerror(L, 1, "out of bounds");
414  }
415  else if (gui2::tprogress_bar *p = dynamic_cast<gui2::tprogress_bar *>(w))
416  {
417  const int v = luaL_checkinteger(L, 1);
418  if (0 <= v && v <= 100)
419  p->set_percentage(v);
420  else
421  return luaL_argerror(L, 1, "out of bounds");
422  }
423  else
424  {
425  t_string v = luaW_checktstring(L, 1);
426  gui2::tcontrol *c = dynamic_cast<gui2::tcontrol *>(w);
427  if (!c) return luaL_argerror(L, lua_gettop(L), "unsupported widget");
428  c->set_label(v);
429  }
430 
431  return 0;
432 }
433 
434 /**
435  * Gets the value of a widget on the current dialog.
436  * - Args 1..n: path of strings and integers.
437  * - Ret 1: scalar.
438  */
440 {
441  gui2::twidget *w = find_widget(L, 1, true);
442 
443 #ifdef GUI2_EXPERIMENTAL_LISTBOX
444  if (gui2::tlist *l = dynamic_cast<gui2::tlist *>(w))
445 #else
446  if (gui2::tlistbox *l = dynamic_cast<gui2::tlistbox *>(w))
447 #endif
448  {
449  lua_pushinteger(L, l->get_selected_row() + 1);
450  } else if (gui2::tmulti_page *l = dynamic_cast<gui2::tmulti_page *>(w)) {
451  lua_pushinteger(L, l->get_selected_page() + 1);
452  } else if (gui2::tselectable_ *s = dynamic_cast<gui2::tselectable_ *>(w)) {
453 
454  if(s->num_states() == 2) {
455  lua_pushboolean(L, s->get_value_bool());
456  }
457  else {
458  lua_pushinteger(L, s->get_value() + 1);
459  }
460  } else if (gui2::ttext_box *t = dynamic_cast<gui2::ttext_box *>(w)) {
461  lua_pushstring(L, t->get_value().c_str());
462  } else if (gui2::tslider *s = dynamic_cast<gui2::tslider *>(w)) {
463  lua_pushinteger(L, s->get_value());
464  } else if (gui2::tprogress_bar *p = dynamic_cast<gui2::tprogress_bar *>(w)) {
465  lua_pushinteger(L, p->get_percentage());
466  } else if (gui2::ttree_view *tv = dynamic_cast<gui2::ttree_view *>(w)) {
467  std::vector<int> path = tv->selected_item()->describe_path();
468  lua_createtable(L, path.size(), 0);
469  for(size_t i =0; i < path.size(); ++i) {
470  lua_pushinteger(L, path[i] + 1);
471  lua_rawseti(L, -2, i + 1);
472  }
473  } else
474  return luaL_argerror(L, lua_gettop(L), "unsupported widget");
475 
476  return 1;
477 }
478 namespace
479 {
480  void remove_treeview_node(gui2::ttree_view_node& node, size_t pos, int number)
481  {
482  //Not tested yet.
483  gui2::ttree_view& tv = node.tree_view();
484  if(pos >= node.size()) {
485  return;
486  }
487  if(number <= 0 || number + pos > node.size()) {
488  number = node.size() - pos;
489  }
490  for (int i = 0; i < number; ++i) {
491  tv.remove_node(&node.get_child_at(pos));
492  }
493  }
494 }
495 /**
496  * Removes an entry from a list.
497  * - Arg 1: number, index of the element to delete.
498  * - Arg 2: number, number of the elements to delete. (0 to delete all elements after index)
499  * - Args 2..n: path of strings and integers.
500  */
502 {
503  int pos = luaL_checkinteger(L, 1) - 1;
504  int number = luaL_checkinteger(L, 2);
505  gui2::twidget *w = find_widget(L, 3, true);
506 
507 #ifdef GUI2_EXPERIMENTAL_LISTBOX
508  if (gui2::tlist *l = dynamic_cast<gui2::tlist *>(w))
509 #else
510  if (gui2::tlistbox *l = dynamic_cast<gui2::tlistbox *>(w))
511 #endif
512  {
513  l->remove_row(pos, number);
514  } else if (gui2::tmulti_page *l = dynamic_cast<gui2::tmulti_page *>(w)) {
515  l->remove_page(pos, number);
516  } else if (gui2::ttree_view *tv = dynamic_cast<gui2::ttree_view *>(w)) {
517  remove_treeview_node(tv->get_root_node(), pos, number);
518  } else if (gui2::ttree_view_node *tvn = dynamic_cast<gui2::ttree_view_node *>(w)) {
519  remove_treeview_node(*tvn, pos, number);
520  } else
521  return luaL_argerror(L, lua_gettop(L), "unsupported widget");
522 
523  return 1;
524 }
525 
526 namespace { // helpers of intf_set_dialog_callback()
528  {
529  int cb;
530  {
531  scoped_dialog::callback_map &m = scoped_dialog::current->callbacks;
532  scoped_dialog::callback_map::const_iterator i = m.find(&w);
533  if (i == m.end()) return;
534  cb = i->second;
535  }
536  lua_State *L = scoped_dialog::current->L;
538  , dlgclbkKey);
540  lua_rawgeti(L, -1, cb);
541  lua_remove(L, -2);
542  lua_call(L, 0, 0);
543  }
544 
545  /** Helper struct for intf_set_dialog_callback. */
546  struct tdialog_callback_wrapper
547  {
548  void forward(gui2::twidget* widget)
549  {
550  assert(widget);
551  dialog_callback(*widget);
552  }
553  };
554 }//unnamed namespace for helpers of intf_set_dialog_callback()
555 
556 /**
557  * Sets a callback on a widget of the current dialog.
558  * - Arg 1: function.
559  * - Args 2..n: path of strings and integers.
560  */
562 {
563  gui2::twidget *w = find_widget(L, 2, true);
564 
565  scoped_dialog::callback_map &m = scoped_dialog::current->callbacks;
567  if (i != m.end())
568  {
570  , dlgclbkKey);
572  lua_pushnil(L);
573  lua_rawseti(L, -2, i->second);
574  lua_pop(L, 1);
575  m.erase(i);
576  }
577 
578  if (lua_isnil(L, 1)) return 0;
579 
580  if (gui2::tclickable_ *c = dynamic_cast<gui2::tclickable_ *>(w)) {
581  static tdialog_callback_wrapper wrapper;
582  c->connect_click_handler(std::bind(
583  &tdialog_callback_wrapper::forward
584  , wrapper
585  , w));
586  } else if (gui2::tselectable_ *s = dynamic_cast<gui2::tselectable_ *>(w)) {
587  s->set_callback_state_change(&dialog_callback);
588  }
589 #ifdef GUI2_EXPERIMENTAL_LISTBOX
590  else if (gui2::tlist *l = dynamic_cast<gui2::tlist *>(w)) {
591  static tdialog_callback_wrapper wrapper;
593  , std::bind(
594  &tdialog_callback_wrapper::forward
595  , wrapper
596  , w));
597  }
598 #else
599  else if (gui2::tlistbox *l = dynamic_cast<gui2::tlistbox *>(w)) {
600  l->set_callback_value_change(&dialog_callback);
601  }
602 #endif
603  else if (gui2::ttree_view *tv = dynamic_cast<gui2::ttree_view *>(w)) {
605  }
606  else
607  return luaL_argerror(L, lua_gettop(L), "unsupported widget");
608 
610  , dlgclbkKey);
612  int n = lua_rawlen(L, -1) + 1;
613  m[w] = n;
614  lua_pushvalue(L, 1);
615  lua_rawseti(L, -2, n);
616  lua_pop(L, 1);
617 
618  return 0;
619 }
620 
621 /**
622  * Enables/disables Pango markup on the label of a widget of the current dialog.
623  * - Arg 1: boolean.
624  * - Args 2..n: path of strings and integers.
625  */
627 {
628  bool b = luaW_toboolean(L, 1);
629  gui2::twidget *w = find_widget(L, 2, true);
630  gui2::tcontrol *c = dynamic_cast<gui2::tcontrol *>(w);
631  if (!c) return luaL_argerror(L, lua_gettop(L), "unsupported widget");
632 
633  c->set_use_markup(b);
634  return 0;
635 }
636 
637 /**
638  * Sets a canvas on a widget of the current dialog.
639  * - Arg 1: integer.
640  * - Arg 2: WML table.
641  * - Args 3..n: path of strings and integers.
642  */
644 {
645  int i = luaL_checkinteger(L, 1);
646  gui2::twidget *w = find_widget(L, 3, true);
647  gui2::tcontrol *c = dynamic_cast<gui2::tcontrol *>(w);
648  if (!c) return luaL_argerror(L, lua_gettop(L), "unsupported widget");
649 
650  std::vector<gui2::tcanvas> &cv = c->canvas();
651  if (i < 1 || unsigned(i) > cv.size())
652  return luaL_argerror(L, 1, "out of bounds");
653 
654  config cfg = luaW_checkconfig(L, 2);
655  cv[i - 1].set_cfg(cfg);
656  c->set_is_dirty(true);
657  return 0;
658 }
659 
660 /**
661  * Sets a widget to have the focus
662  * - Args 1..n: path of strings and integers.
663  */
665 {
666  gui2::twidget *w = find_widget(L, 1, true);
667  scoped_dialog::current->window->keyboard_capture(w);
668  return 0;
669 }
670 
671 /**
672  * Sets a widget's state to active or inactive
673  * - Arg 1: boolean.
674  * - Args 2..n: path of strings and integers.
675  */
677 {
678  const bool b = luaW_toboolean(L, 1);
679  gui2::twidget *w = find_widget(L, 2, true);
680  gui2::tcontrol *c = dynamic_cast<gui2::tcontrol *>(w);
681  if (!c) return luaL_argerror(L, lua_gettop(L), "unsupported widget");
682 
683  c->set_active(b);
684  return 0;
685 }
686 
687 /**
688  * Sets the visiblity of a widget in the current dialog.
689  * - Arg 1: boolean.
690  * - Args 2..n: path of strings and integers.
691  */
693 {
694  typedef gui2::tcontrol::tvisible tvisible;
695 
696  tvisible::scoped_enum flag = tvisible::visible;
697 
698  switch (lua_type(L, 1)) {
699  case LUA_TBOOLEAN:
700  flag = luaW_toboolean(L, 1)
701  ? tvisible::visible
702  : tvisible::invisible;
703  break;
704  case LUA_TSTRING:
705  {
706  const std::string& str = lua_tostring(L, 1);
707  if(str == "visible") {
708  flag = tvisible::visible;
709  } else if(str == "hidden") {
710  flag = tvisible::hidden;
711  } else if(str == "invisible") {
712  flag = tvisible::invisible;
713  } else {
714  return luaL_argerror(L, 1, "string must be one of: visible, hidden, invisible");
715  }
716  }
717  break;
718  default:
719  return luaL_typerror(L, 1, "boolean or string");
720  }
721 
722  gui2::twidget *w = find_widget(L, 2, true);
723  gui2::tcontrol *c = dynamic_cast<gui2::tcontrol *>(w);
724  if (!c) return luaL_argerror(L, lua_gettop(L), "unsupported widget");
725 
726  c->set_visible(flag);
727 
728  if(flag == tvisible::hidden) {
729  // HACK: this is needed to force the widget to be repainted immediately
730  // to get rid of its ghost image.
731  scoped_dialog::current->window->invalidate_layout();
732  }
733 
734  return 0;
735 }
736 
738 {
740  return 0;
741 }
742 
743 int show_gamestate_inspector(CVideo & video, const vconfig & cfg)
744 {
745  gui2::tgamestate_inspector inspect_dialog(cfg);
746  inspect_dialog.show(video);
747  return 0;
748 }
749 
750 /**
751  * Sets a widget's state to active or inactive
752  * - Arg 1: string, the type (id of [node_definition]) of the new node.
753  * - Arg 3: integer, where to insert the new node.
754  * - Args 3..n: path of strings and integers.
755  */
756 
758 {
759  const std::string node_type = luaL_checkstring(L, 1);
760  const int insert_pos = luaL_checkinteger(L, 2);
761  static const std::map<std::string, string_map> data;
762  gui2::twidget *w = find_widget(L, 3, false);
763  gui2::ttree_view_node *twn = dynamic_cast<gui2::ttree_view_node *>(w);
764  if (!twn) {
765  if(gui2::ttree_view* tw = dynamic_cast<gui2::ttree_view *>(w)) {
766  twn = &tw->get_root_node();
767  }
768  else {
769  return luaL_argerror(L, lua_gettop(L), "unsupported widget");
770  }
771  }
772  twn->add_child(node_type, data, insert_pos);
773  return 0;
774 }
775 
776 } // end namespace lua_gui2
int intf_set_dialog_active(lua_State *L)
Sets a widget's state to active or inactive.
Definition: lua_gui2.cpp:676
LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
Definition: lapi.cpp:643
#define lua_isnoneornil(L, n)
Definition: lua.h:337
int show_lua_console(lua_State *, CVideo &video, lua_kernel_base *lk)
Definition: lua_gui2.cpp:737
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:667
size_t size() const
The "size" of the widget.
LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:622
int intf_add_dialog_tree_node(lua_State *L)
Sets a widget's state to active or inactive.
Definition: lua_gui2.cpp:757
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int narg)
Definition: lauxlib.cpp:391
LUA_API int lua_type(lua_State *L, int idx)
Definition: lapi.cpp:243
static void display(CVideo &video, lua_kernel_base *lk)
Display a new console, using given video and lua kernel.
twindow * build(CVideo &video, const twindow_builder::tresolution *definition)
Builds a window.
const GLfloat * c
Definition: glew.h:12741
int pos
Definition: formula.cpp:800
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:571
bool show(CVideo &video, const unsigned auto_close_time=0)
Shows the window.
Definition: dialog.cpp:34
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:29
Visibility settings done by the user.
Definition: widget.hpp:61
LUALIB_API void luaL_checktype(lua_State *L, int narg, int t)
Definition: lauxlib.cpp:347
Definition: video.hpp:58
void connect_signal_notify_modified(tdispatcher &dispatcher, const tsignal_notification_function &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.hpp:725
LUA_API int lua_gettop(lua_State *L)
Definition: lapi.cpp:154
This file contains the window object, this object is a top level container which has the event manage...
virtual void set_label(const t_string &label)
Definition: control.cpp:330
#define lua_tointeger(L, i)
Definition: lua.h:319
void show_transient_message(CVideo &video, const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup, const bool restore_background)
Shows a transient message to the user.
Class for a single line text area.
Definition: text_box.hpp:118
Implements simple parsing of legacy GUI1 item markup.
Definition: old_markup.hpp:26
const std::string number
template to number regex
int intf_remove_dialog_item(lua_State *L)
Removes an entry from a list.
Definition: lua_gui2.cpp:501
int intf_set_dialog_markup(lua_State *L)
Enables/disables Pango markup on the label of a widget of the current dialog.
Definition: lua_gui2.cpp:626
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
GLuint GLenum option
Definition: glew.h:2815
bool empty() const
Definition: config.cpp:1105
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:435
GLdouble GLdouble t
Definition: glew.h:1366
ttree_view_node & add_child(const std::string &id, const std::map< std::string, string_map > &data, const int index=-1)
Adds a child item to the list of child nodes.
Definitions for the interface to Wesnoth Markup Language (WML).
const std::string & icon() const
Definition: old_markup.hpp:45
#define lua_pop(L, n)
Definition: lua.h:322
int intf_set_dialog_focus(lua_State *L)
Sets a widget to have the focus.
Definition: lua_gui2.cpp:664
GLdouble l
Definition: glew.h:6966
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
void set_selection_change_callback(std::function< void(twidget &)> callback)
Definition: tree_view.hpp:92
int show_dialog(lua_State *L, CVideo &video)
Displays a window.
Definition: lua_gui2.cpp:223
#define ERR_LUA
Definition: lua_gui2.cpp:62
virtual void set_use_markup(bool use_markup)
Definition: control.cpp:342
const config & options()
#define LUA_TSTRING
Definition: lua.h:81
boost::scoped_ptr< sdl::twindow > window
Definition: video.hpp:215
virtual void set_active(const bool active)=0
Sets the control's state.
GLsizei const char ** path
Definition: glew.h:4654
std::map< std::string, t_string > string_map
bool is_default() const
Definition: old_markup.hpp:60
bool luaW_toboolean(lua_State *L, int n)
Definition: lua_common.cpp:811
ttree_view & tree_view()
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
const GLdouble * v
Definition: glew.h:1359
t_string luaW_checktstring(lua_State *L, int index)
Converts a scalar to a translatable string.
Definition: lua_common.cpp:562
This file contains the canvas object which is the part where the widgets draw (temporally) images on...
LUA_API const char * lua_pushlstring(lua_State *L, const char *s, size_t len)
Definition: lapi.cpp:495
int show_message_dialog(lua_State *L, CVideo &video)
Displays a message window.
Definition: lua_gui2.cpp:254
The multi page class.
Definition: multi_page.hpp:37
static gui2::twidget * find_widget(lua_State *L, int i, bool readonly)
Definition: lua_gui2.cpp:111
LUA_API void lua_remove(lua_State *L, int idx)
Definition: lapi.cpp:176
GLfloat GLfloat p
Definition: glew.h:12766
int intf_set_dialog_canvas(lua_State *L)
Sets a canvas on a widget of the current dialog.
Definition: lua_gui2.cpp:643
Helper class for message options.
Definition: wml_message.hpp:26
LUA_API void lua_pushnil(lua_State *L)
Definition: lapi.cpp:459
const std::string & description() const
Definition: old_markup.hpp:55
Small abstract helper class.
Definition: selectable.hpp:32
static lg::log_domain log_scripting_lua("scripting/lua")
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:675
bool luaW_totstring(lua_State *L, int index, t_string &str)
Converts a scalar to a translatable string.
Definition: lua_common.cpp:537
Small concept class.
Definition: clickable.hpp:39
#define lua_isnil(L, n)
Definition: lua.h:333
int intf_set_dialog_value(lua_State *L)
Sets the value of a widget on the current dialog.
Definition: lua_gui2.cpp:365
LUA_API void lua_rawset(lua_State *L, int idx)
Definition: lapi.cpp:764
ttree_view_node & get_root_node()
Definition: tree_view.hpp:51
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
Definition: lua_common.cpp:749
int show_wml_message(const bool left_side, CVideo &video, const std::string &title, const std::string &message, const std::string &portrait, const bool mirror, const bool has_input, const std::string &input_caption, std::string *input_text, const unsigned maximum_length, const std::vector< twml_message_option > &option_list, int *chosen_option)
Helper function to show a portrait.
static const char * dlgclbkKey
Definition: lua_gui2.cpp:64
The listbox class.
Definition: listbox.hpp:39
int show_popup_dialog(lua_State *L, CVideo &video)
Displays a popup message.
Definition: lua_gui2.cpp:351
LUALIB_API int luaL_argerror(lua_State *L, int narg, const char *extramsg)
Definition: lauxlib.cpp:152
size_t i
Definition: function.cpp:1057
#define lua_tostring(L, i)
Definition: lua.h:345
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
LUA_API void lua_rawseti(lua_State *L, int idx, int n)
Definition: lapi.cpp:778
std::vector< tcanvas > & canvas()
Definition: control.hpp:282
LUA_API void lua_pushvalue(lua_State *L, int idx)
Definition: lapi.cpp:229
LUA_API int lua_isnumber(lua_State *L, int idx)
Definition: lapi.cpp:261
const std::string & label() const
Definition: old_markup.hpp:50
#define lua_call(L, n, r)
Definition: lua.h:252
LUALIB_API int luaL_error(lua_State *L, const char *fmt,...)
Definition: lauxlib.cpp:198
int intf_set_dialog_callback(lua_State *L)
Sets a callback on a widget of the current dialog.
Definition: lua_gui2.cpp:561
Base class for all visible items.
Definition: control.hpp:34
twidget * find(const std::string &id, const bool must_be_active) override
See twidget::find.
LUA_API size_t lua_rawlen(lua_State *L, int idx)
Definition: lapi.cpp:401
#define LUA_REGISTRYINDEX
Definition: lua.h:39
GLclampd n
Definition: glew.h:5903
const GLdouble * m
Definition: glew.h:6968
map_location prev
Definition: astarsearch.cpp:67
Base class for all widgets.
Definition: widget.hpp:49
A variable-expanding proxy for the config class.
Definition: variable.hpp:36
this module manages the cache of images.
Definition: image.cpp:75
Standard logging facilities (interface).
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
void remove_node(ttree_view_node *tree_view_node)
Definition: tree_view.cpp:65
int intf_get_dialog_value(lua_State *L)
Gets the value of a widget on the current dialog.
Definition: lua_gui2.cpp:439
const std::string & str() const
Definition: tstring.hpp:170
ttree_view_node & get_child_at(int index)
int show_gamestate_inspector(CVideo &video, const vconfig &cfg)
Definition: lua_gui2.cpp:743
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
A slider.
Definition: slider.hpp:30
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
GLdouble s
Definition: glew.h:1358
#define LUA_TTABLE
Definition: lua.h:82
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:477
virtual twidget * find(const std::string &id, const bool must_be_active)
Returns a widget with the wanted id.
Definition: widget.cpp:558
void set_visible(const tvisible::scoped_enum visible)
Definition: widget.cpp:445
LUALIB_API int luaL_typerror(lua_State *L, int narg, const char *tname)
Definition: lauxlib.cpp:176
LUA_API void lua_rawget(lua_State *L, int idx)
Definition: lapi.cpp:633
GLsizei const GLcharARB ** string
Definition: glew.h:4503
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:507
void dialog_callback(twidget &caller)
Template for dialog callbacks.
Definition: helper.hpp:31
#define LUA_TBOOLEAN
Definition: lua.h:78
int intf_set_dialog_visible(lua_State *L)
Sets the visiblity of a widget in the current dialog.
Definition: lua_gui2.cpp:692
LUA_API const char * lua_typename(lua_State *L, int t)
Definition: lapi.cpp:249
#define luaL_checkstring(L, n)
Definition: lauxlib.h:115