Fawkes API  Fawkes Development Version
lasergui_hildon.cpp
1 
2 /***************************************************************************
3  * lasergui_hildon.cpp - minimalistic laser visualization on Hildon
4  *
5  * Created: Sun Oct 12 17:06:06 2008
6  * Copyright 2008 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "laser_drawing_area.h"
24 
25 #include <gui_utils/robot/allemaniacs_athome.h>
26 #include <gtkmm.h>
27 #include <hildonmm.h>
28 #include <libosso.h>
29 
30 #include <netcomm/fawkes/client.h>
31 #include <blackboard/remote.h>
32 #include <interfaces/Laser360Interface.h>
33 #include <gui_utils/interface_dispatcher.h>
34 #include <gui_utils/connection_dispatcher.h>
35 #include <gui_utils/service_chooser_dialog.h>
36 
37 #if MAEMO_VERSION_MAJOR >= 5
38 # define ICON_FORMAT "white_48x48"
39 #else
40 # define ICON_FORMAT "32x32"
41 #endif
42 
43 using namespace fawkes;
44 
45 /** @class LaserGuiHildonWindow "lasergui_hildon.cpp"
46  * Laser GUI window for Hildon.
47  * @author Tim Niemueller
48  */
49 
50 class LaserGuiHildonWindow : public Hildon::Window
51 {
52  public:
53  /** Constructor. */
55  : __athome_drawer(true),
56  __img_lines(RESDIR"/guis/lasergui/lines_"ICON_FORMAT".png"),
57  __img_points(RESDIR"/guis/lasergui/points_"ICON_FORMAT".png"),
58  __img_hull(RESDIR"/guis/lasergui/hull_"ICON_FORMAT".png"),
59  __img_lowres(RESDIR"/guis/lasergui/lines_lowres_"ICON_FORMAT".png"),
60  __img_rotation(RESDIR"/guis/lasergui/rotate-90.png"),
61  __tb_connection(Gtk::Stock::CONNECT),
62  __tb_lines(__img_lines),
63  __tb_points(__img_points),
64  __tb_hull(__img_hull),
65  __tb_lowres(__img_lowres),
66  __tb_rotation(__img_rotation),
67  __tb_zoom_in(Gtk::Stock::ZOOM_IN),
68  __tb_zoom_out(Gtk::Stock::ZOOM_OUT)
69  {
70  __fullscreen = false;
71  __bb = NULL;
72  __laser_if = NULL;
73  __ifd = NULL;
74 
75 # if GLIBMM_MAJOR_VERSION > 2 || (GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION >= 48)
76  std::unique_ptr<Glib::Error> error;
77 # else
78  std::auto_ptr<Glib::Error> error;
79 # endif
80  set_icon_from_file(RESDIR"/guis/lasergui/lines_"ICON_FORMAT".png", error);
81 
82  add(__area);
83  __area.show();
84  __area.set_robot_drawer(&__athome_drawer);
85 
86  Gtk::RadioButton::Group group = __tb_lines.get_group();
87  __tb_points.set_group(group);
88  group = __tb_lines.get_group();
89  __tb_hull.set_group(group);
90  __tb_lines.set_active(true);
91 
92  __tb_lines.set_sensitive(false);
93  __tb_points.set_sensitive(false);
94  __tb_hull.set_sensitive(false);
95  __tb_lowres.set_sensitive(false);
96  __tb_rotation.set_sensitive(false);
97  __tb_zoom_in.set_sensitive(false);
98  __tb_zoom_out.set_sensitive(false);
99 
100  __tbar.append(__tb_connection);
101  __tbar.append(__sep_0);
102  __tbar.append(__tb_lines);
103  __tbar.append(__tb_points);
104  __tbar.append(__tb_hull);
105  __tbar.append(__sep_1);
106  __tbar.append(__tb_lowres);
107  __tbar.append(__tb_rotation);
108  __tbar.append(__sep_2);
109  __tbar.append(__tb_zoom_in);
110  __tbar.append(__tb_zoom_out);
111 
112  add_toolbar(__tbar);
113  __tbar.show_all();
114 
115  __tb_lines.signal_toggled().connect(sigc::bind(sigc::mem_fun(__area, &LaserDrawingArea::set_draw_mode), LaserDrawingArea::MODE_LINES));
116  __tb_points.signal_toggled().connect(sigc::bind(sigc::mem_fun(__area, &LaserDrawingArea::set_draw_mode), LaserDrawingArea::MODE_POINTS));
117  __tb_hull.signal_toggled().connect(sigc::bind(sigc::mem_fun(__area, &LaserDrawingArea::set_draw_mode), LaserDrawingArea::MODE_HULL));
118  __tb_zoom_in.signal_clicked().connect(sigc::mem_fun(__area, &LaserDrawingArea::zoom_in));
119  __tb_zoom_out.signal_clicked().connect(sigc::mem_fun(__area, &LaserDrawingArea::zoom_out));
120 
121  __tb_connection.signal_clicked().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_connection_clicked));
122  __tb_rotation.signal_clicked().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_rotation_toggled));
123  __tb_lowres.signal_clicked().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_resolution_toggled));
124 
125  __connection_dispatcher.signal_connected().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_connect));
126  __connection_dispatcher.signal_disconnected().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_disconnect));
127 
128 #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
129  signal_key_press_event().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_key_pressed));
130  signal_window_state_event().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_window_state_event));
131 #endif
132  }
133 
134  /** Destructor. */
136  {
137  __area.set_laser360_if(NULL);
138  if (__bb) {
139  __bb->close(__laser_if);
140  delete __bb;
141  delete __ifd;
142  }
143  }
144 
145  protected:
146  /** Event handler for key pressed events.
147  * @param event event parameters
148  * @return always false
149  */
150  virtual bool on_key_pressed(GdkEventKey* event)
151  {
152  if(!event) return false;
153 
154  switch (event->keyval) {
155  case GDK_F6:
156  if ( __fullscreen ) {
157  unfullscreen();
158  } else {
159  fullscreen();
160  }
161  break;
162  case GDK_F7:
163  __area.zoom_in();
164  break;
165  case GDK_F8:
166  __area.zoom_out();
167  break;
168  }
169 
170  // Returning true would stop the event now
171  return false;
172  }
173 
174  /** Event handler for window state change events.
175  * @param event event parameters
176  * @return always false
177  */
178  virtual bool on_window_state_event(GdkEventWindowState *event)
179  {
180  if (event->new_window_state == GDK_WINDOW_STATE_FULLSCREEN) {
181  __fullscreen = true;
182  } else {
183  __fullscreen = false;
184  }
185  return false;
186  }
187 
188  /** Event handler for connection button. */
190  {
191  if ( ! __connection_dispatcher.get_client()->connected() ) {
192  ServiceChooserDialog ssd(*this, __connection_dispatcher.get_client());
193  ssd.run_and_connect();
194  } else {
195  __connection_dispatcher.get_client()->disconnect();
196  }
197  }
198 
199  /** Event handler for connected event. */
200  virtual void on_connect()
201  {
202  try {
203  __bb = new RemoteBlackBoard(__connection_dispatcher.get_client());
204  __laser_if = __bb->open_for_reading<Laser360Interface>("Laser");
205 
206  __area.set_laser360_if(__laser_if);
207  __ifd = new InterfaceDispatcher("LaserInterfaceDispatcher", __laser_if);
208  __ifd->signal_data_changed().connect(sigc::hide(sigc::mem_fun(__area, &LaserDrawingArea::queue_draw)));
209  __ifd->signal_writer_removed().connect(sigc::hide(sigc::mem_fun(__area, &LaserDrawingArea::queue_draw)));
210  __bb->register_listener(__ifd, BlackBoard::BBIL_FLAG_DATA | BlackBoard::BBIL_FLAG_WRITER);
211 
212  __area.queue_draw();
213 
214  __tb_connection.set_stock_id(Gtk::Stock::DISCONNECT);
215  __tb_lines.set_sensitive(true);
216  __tb_points.set_sensitive(true);
217  __tb_hull.set_sensitive(true);
218  __tb_lowres.set_sensitive(true);
219  __tb_rotation.set_sensitive(true);
220  __tb_zoom_in.set_sensitive(true);
221  __tb_zoom_out.set_sensitive(true);
222  } catch (Exception &e) {
223  e.print_trace();
224  if ( __bb ) {
225  __bb->close(__laser_if);
226  delete __ifd;
227  delete __bb;
228  __laser_if = NULL;
229  __bb = NULL;
230  __ifd = NULL;
231  }
232  }
233  }
234 
235  /** Event handler for disconnected event. */
236  virtual void on_disconnect()
237  {
238  __area.set_laser360_if(NULL);
239  __area.queue_draw();
240  __bb->close(__laser_if);
241  delete __bb;
242  delete __ifd;
243  __bb = NULL;
244  __ifd = NULL;
245  __laser_if = NULL;
246  __tb_connection.set_stock_id(Gtk::Stock::CONNECT);
247  __tb_lines.set_sensitive(false);
248  __tb_points.set_sensitive(false);
249  __tb_hull.set_sensitive(false);
250  __tb_lowres.set_sensitive(false);
251  __tb_rotation.set_sensitive(false);
252  __tb_zoom_in.set_sensitive(false);
253  __tb_zoom_out.set_sensitive(false);
254  }
255 
256  /** Event handler for rotation button. */
258  {
259  if ( __tb_rotation.get_active() ) {
260  __area.set_rotation(M_PI / 2);
261  } else {
262  __area.set_rotation(0);
263  }
264  }
265 
266  /** Event handler for rotation button. */
268  {
269  if ( __tb_lowres.get_active() ) {
270  __area.set_resolution(3);
271  } else {
272  __area.set_resolution(1);
273  }
274  }
275 
276  private:
277  AllemaniACsAtHomeCairoRobotDrawer __athome_drawer;
278  BlackBoard *__bb;
279  Laser360Interface *__laser_if;
280  InterfaceDispatcher *__ifd;
281  ConnectionDispatcher __connection_dispatcher;
282 
283  Gtk::Image __img_lines;
284  Gtk::Image __img_points;
285  Gtk::Image __img_hull;
286  Gtk::Image __img_lowres;
287  Gtk::Image __img_rotation;
288  Gtk::ToolButton __tb_connection;
289  Gtk::SeparatorToolItem __sep_0;
290  Gtk::RadioToolButton __tb_lines;
291  Gtk::RadioToolButton __tb_points;
292  Gtk::RadioToolButton __tb_hull;
293  Gtk::SeparatorToolItem __sep_1;
294  Gtk::ToggleToolButton __tb_lowres;
295  Gtk::ToggleToolButton __tb_rotation;
296  Gtk::SeparatorToolItem __sep_2;
297  Gtk::ToolButton __tb_zoom_in;
298  Gtk::ToolButton __tb_zoom_out;
299  Gtk::Toolbar __tbar;
300 
301  LaserDrawingArea __area;
302 
303  bool __fullscreen;
304 };
305 
306 int
307 main(int argc, char** argv)
308 {
309  Gtk::Main kit(argc, argv);
310  Hildon::init();
311 
312  osso_context_t* osso_context = osso_initialize("lasergui", "0.1", TRUE /* deprecated parameter */, 0 /* Use default Glib main loop context */);
313  Glib::set_application_name("Laser GUI");
314 
315  LaserGuiHildonWindow window;
316  kit.run(window);
317 
318  osso_deinitialize(osso_context);
319  return 0;
320 }
Laser360Interface Fawkes BlackBoard Interface.
consider data events
Definition: blackboard.h:99
Only draw beam end points.
Laser drawing area.
Fawkes library namespace.
virtual bool on_key_pressed(GdkEventKey *event)
Event handler for key pressed events.
void zoom_in()
Zoom in.
virtual void on_disconnect()
Event handler for disconnected event.
void set_draw_mode(draw_mode_t mode)
Set the drawing mode.
void on_connection_clicked()
Event handler for connection button.
virtual void on_connect()
Event handler for connected event.
Base class for exceptions in Fawkes.
Definition: exception.h:36
void run_and_connect()
Run dialog and try to connect.
Laser GUI window for Hildon.
void on_resolution_toggled()
Event handler for rotation button.
virtual bool on_window_state_event(GdkEventWindowState *event)
Event handler for window state change events.
~LaserGuiHildonWindow()
Destructor.
void zoom_out()
Zoom out.
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:619
consider writer events
Definition: blackboard.h:102
Remote BlackBoard.
Definition: remote.h:48
The BlackBoard abstract class.
Definition: blackboard.h:48
Watches network client events and dispatches them as signals.
Draw AllemaniACs AtHome robot.
Interface listener with dispatcher.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)
Open interface for reading.
Definition: remote.cpp:272
void on_rotation_toggled()
Event handler for rotation button.
LaserGuiHildonWindow()
Constructor.