Lumiera  0.pre.03
»edit your freedom«
test-control.hpp
Go to the documentation of this file.
1 /*
2  TEST-CONTROL.hpp - child window to trigger self tests and diagnostics
3 
4  Copyright (C)
5  2018, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
29 #ifndef STAGE_DIALOG_TEST_CONTROL_H
30 #define STAGE_DIALOG_TEST_CONTROL_H
31 
32 
33 #include "stage/gtk-base.hpp"
34 #include "stage/dialog/dialog.hpp"
35 #include "stage/ctrl/bus-term.hpp"
36 #include "stage/model/tangible.hpp"
37 #include "include/ui-protocol.hpp"
38 
39 #include "steam/cmd.hpp"
42 
43 #include "lib/test/test-helper.hpp"
44 #include "lib/diff/gen-node.hpp"
45 #include "lib/scoped-ptrvect.hpp"
46 #include "lib/format-string.hpp"
47 #include "lib/format-cout.hpp"
48 #include "lib/nocopy.hpp"
49 #include "lib/util.hpp"
50 
51 #include <utility>
52 #include <string>
53 
54 namespace stage {
55 namespace dialog {
56 
57  using std::string;
58  using std::forward;
59  using lib::diff::GenNode;
60  using util::sanitise;
61  using util::_Fmt;
62 
63 
72  struct FrameBox
73  {
74  Gtk::Frame frame;
75  Gtk::Box box;
76 
77  FrameBox (cuString label,
78  Gtk::Orientation orientation =Gtk::ORIENTATION_VERTICAL)
79  : frame{label}
80  , box{orientation}
81  {
82  frame.add (box);
83  }
84 
85  operator Gtk::Widget&() { return frame; }
86 
87  void
88  pack_start(Gtk::Widget& child, Gtk::PackOptions options =Gtk::PACK_EXPAND_WIDGET, guint padding =0)
89  {
90  box.pack_start (child, options, padding);
91  }
92  };
93 
95  class Page
96  : public Gtk::Box
98  {
99  public:
100  Page()
101  : Gtk::Box{Gtk::ORIENTATION_VERTICAL}
102  { }
103  };
104 
126  class Notebook
127  : public Gtk::Notebook
128  , lib::ScopedPtrVect<Gtk::Widget>
129  {
130  public:
131  template<class PAG, typename...ARGS>
132  Notebook&
133  buildPage (cuString pageLabel, ARGS&& ...ctorArgs)
134  {
135  Gtk::Notebook::append_page (this->manage (new PAG(forward<ARGS> (ctorArgs)...))
136  ,pageLabel);
137  return *this;
138  }
139  };
140 
141 
150  : public Gtk::Dialog
151  {
152  using Bus = ctrl::BusTerm&;
153 
154  Bus uiBus_;
155  Notebook notebook_;
156 
157 
165  struct Page1 : Page
166  {
167  Gtk::Entry content_;
168  FrameBox seg_1_{_("log notification"), Gtk::ORIENTATION_HORIZONTAL},
169  seg_2_{_("mark via UI-Bus")};
170  Gtk::Button trig_1_, trig_2_, trig_3_, trig_4_;
171  Gtk::RadioButton level_info_{"Info"},
172  level_warn_{"Warn"},
173  level_erro_{"Error"};
174  Gtk::Box markParam_;
175  Gtk::ComboBoxText actionID_{true}; // has free-text entry field
176 
177  int
178  getLogLevel()
179  {
180  return level_info_.get_active()? NOTE_INFO :
181  level_warn_.get_active()? NOTE_WARN : NOTE_ERROR;
182  }
183 
184  string
185  getContent()
186  {
187  return string{content_.get_text()};
188  }
189 
190  string
191  getActionID()
192  {
193  return string{actionID_.get_entry_text()};
194  }
195 
196 
197  Page1 (Bus bus)
198  {
199  content_.set_tooltip_markup (_("<b>Ticket #1099</b>:\n"
200  "text message content\n"
201  "<i>when invoking a suitable action,\n"
202  "it will be passed down and sent back</i>"));
203  trig_1_.set_use_underline();
204  trig_1_.set_label ("_display text");
205  trig_1_.property_xalign() = 0;
206  trig_1_.set_tooltip_markup (_("Trigger Steam-Stage <b>roundtrip</b>\n"
207  "Steam invokes GuiNotification::displayInfo"));
208 
209  level_warn_.join_group(level_info_);
210  level_erro_.join_group(level_info_);
211  level_warn_.set_active();
212 
213  trig_2_.set_use_underline();
214  trig_2_.property_xalign() = 0;
215  trig_2_.set_label ("mark _error");
216  trig_2_.set_tooltip_markup (_("trigger Steam-command, which in turn\n"
217  "sends an error state mark via UI-Bus"));
218 
219  trig_3_.set_use_underline();
220  trig_3_.property_xalign() = 0;
221  trig_3_.set_label ("mark _info");
222  trig_3_.set_tooltip_markup (_("trigger Steam-command, which in turn\n"
223  "sends an info state mark via UI-Bus"));
224 
225  trig_4_.set_use_underline();
226  trig_4_.set_label ("_mark");
227  trig_4_.property_xalign() = 0;
228  trig_4_.set_tooltip_markup (_("trigger Steam-command, which in turn\n"
229  "sends an <b>state mark</b> message, using\n"
230  "the message action-ID from the combobox"));
231  actionID_.append (cuString{MARK_Flash});
232  actionID_.append (cuString{MARK_reveal});
233  actionID_.append (cuString{MARK_clearErr});
234  actionID_.append (cuString{MARK_clearMsg});
235  actionID_.append (cuString{MARK_expand});
236  actionID_.append (cuString{MARK_reset});
237  actionID_.set_active(1);
238  actionID_.set_tooltip_markup("select the specific action-ID\n"
239  "when sending a <b>mark</b> message.\n"
240  "<u>note</u>: can enter arbitrary ID");
241 
242  markParam_.pack_start(trig_4_);
243  markParam_.pack_start(actionID_, Gtk::PACK_SHRINK);
244 
245  seg_1_.pack_start (trig_1_, Gtk::PACK_EXPAND_WIDGET);
246  seg_1_.pack_start (level_info_, Gtk::PACK_SHRINK);
247  seg_1_.pack_start (level_warn_, Gtk::PACK_SHRINK);
248  seg_1_.pack_start (level_erro_, Gtk::PACK_SHRINK);
249 
250  seg_2_.pack_start (trig_2_);
251  seg_2_.pack_start (trig_3_);
252  seg_2_.pack_start (markParam_);
253 
254  pack_start (content_, Gtk::PACK_SHRINK);
255  pack_start (seg_1_, Gtk::PACK_SHRINK);
256  pack_start (seg_2_, Gtk::PACK_SHRINK);
257 
258  // define the action triggers...
259  trig_1_.signal_clicked().connect(
260  [&]{ bus.act (model::commandMessage (steam::cmd::test_meta_displayInfo, getLogLevel(), getContent())); });
261  trig_2_.signal_clicked().connect(
262  [&]{ bus.act (model::commandMessage (steam::cmd::test_meta_markError, getContent())); });
263  trig_3_.signal_clicked().connect(
264  [&]{ bus.act (model::commandMessage (steam::cmd::test_meta_markNote, getContent())); });
265  trig_4_.signal_clicked().connect(
266  [&]{ bus.act (model::commandMessage (steam::cmd::test_meta_markAction, getActionID(), getContent())); });
267  }
268  };
269 
270 
275  struct Page2 : Page
276  {
277  Gtk::Entry dummy_;
278  FrameBox part_1_{_("populate"), Gtk::ORIENTATION_HORIZONTAL}
279  , part_2_{_("modify content")}
280  ;
281  Gtk::Button seq_1_, seq_2_;
282  Gtk::Button mut_1_;
283 
284  string
285  pickDummyID()
286  {
287  string dummyID = sanitise (dummy_.get_text());
288  dummy_.set_text (string{_Fmt{"d%s%02d"} % lib::test::randStr(2) % (1 + lib::rani(99))});
289  return dummyID;
290  }
291 
292 
293  Page2 (Bus bus)
294  {
295  seq_1_.set_label ("Sequence 1");
296  seq_1_.set_tooltip_markup (_("Push <b>population diff</b> up into the UI\n"
297  "provides the typical simple default timeline structure"));
298 
299  seq_2_.set_label ("Sequence 2");
300  seq_2_.set_tooltip_markup (_("Push <b>population diff</b> up into the UI\n"
301  "provides a complex nested timeline structure"));
302 
303  dummy_.set_tooltip_markup (_("<i>dummy ID value</i>\n"
304  "used to build names in the generated content"));
305  dummy_.set_max_width_chars(12);
306  pickDummyID();
307 
308  part_1_.pack_start (seq_1_, Gtk::PACK_SHRINK);
309  part_1_.pack_start (seq_2_, Gtk::PACK_SHRINK);
310  part_1_.pack_start (dummy_, Gtk::PACK_EXPAND_WIDGET);
311 
312 
313  mut_1_.set_label ("move elements");
314  mut_1_.set_tooltip_markup (_("randomly manipulate temporal position of dummy elements"));
315 
316  part_2_.pack_start (mut_1_);
317 
318  pack_start (part_1_, Gtk::PACK_SHRINK);
319  pack_start (part_2_, Gtk::PACK_SHRINK);
320 
321  // define the action triggers...
322  seq_1_.signal_clicked().connect(
323  [&]{ bus.act (model::commandMessage (steam::cmd::test_fake_injectSequence_1, pickDummyID())); });
324  seq_2_.signal_clicked().connect(
325  [&]{ bus.act (model::commandMessage (steam::cmd::test_fake_injectSequence_2, pickDummyID())); });
326 
327  mut_1_.signal_clicked().connect(
328  [&]{ cerr << "gelldaschaugst..." <<endl; });
329  }
330  };
331 
332 
333 
334  public:
335  TestControl (ctrl::BusTerm& upLink, Gtk::Window& parent)
336  : Dialog(_("Test and Diagnostics"), parent, Gtk::DIALOG_DESTROY_WITH_PARENT)
337  , uiBus_{upLink}
338  {
339  // Setup the overall dialog layout
340  set_border_width (BorderPadding);
341  get_content_area()->pack_start (notebook_);
342 
343  // construct and wire the pages...
344  notebook_.buildPage<Page1> (_("#1099"), uiBus_);
345  notebook_.buildPage<Page2> (_("Populate"), uiBus_);
346 
347  show_all();
348  notebook_.set_current_page(-1);
349  }
350  };
351 
352 
353 }} // namespace stage::dialog
354 #endif /*STAGE_DIALOG_TEST_CONTROL_H*/
Automatically use custom string conversion in C++ stream output.
Abstraction: a tangible element of the User Interface.
Hard wired key constants and basic definitions for communication with the GUI.
Major public Interface of the Lumiera GUI.
connection point at the UI-Bus.
Definition: bus-term.hpp:96
Ticket #1014 : populate the Timeline in the GUI.
explicitly named shortcut for the typical dialog page content holder
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
static const int BorderPadding
The space in pixels to pad the border of Lumiera dialog boxes.
Definition: dialog.hpp:29
Front-end for printf-style string template interpolation.
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
std::string sanitise(std::string const &)
produce an identifier based on the given string.
Definition: util.cpp:56
Dummy and scaffolding to help development of the UI - Session connection.
Common ID definitions for Steam-Layer commands.
something to be aware of, to be indicated unobtrusively
A front-end for using printf-style formatting.
Managing lifecycle for a collection of objects.
Simple vector based collection of pointers, managing lifecycle of the pointed-to objects.
Attachment point to the UI-Bus.
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Lumiera GTK UI implementation root.
Definition: guifacade.cpp:37
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A complex, tabbed-notebook-style non-modal dialog window, dedicated to development, diagnostics and experimentation.
Generic building block for tree shaped (meta)data structures.
A collection of frequently used helper functions to support unit testing.
lib::diff::GenNode commandMessage(Symbol cmdID, ARGS &&... args)
convenience shortcut to build a message suitable for command invocation
Definition: tangible.hpp:242
severe condition to be indicated prominently
Global constants and definitions for dialogs.
Building block for a segment within a dialog page.
possibly interesting info that can be safely ignored
A set of basic GTK includes for the UI.
virtual void act(GenNode const &command)
prepare or trigger invocation of a command.
Definition: ui-bus.cpp:130
generic data element node within a tree
Definition: gen-node.hpp:222
Helper widget to simplify construction and wiring of a [Notebook] widget.
Ticket #1099 : perform a dummy round-trip to verify Steam-Stage integration.