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  std::auto_ptr<Glib::Error> error;
76  set_icon_from_file(RESDIR"/guis/lasergui/lines_"ICON_FORMAT".png", error);
77 
78  add(__area);
79  __area.show();
80  __area.set_robot_drawer(&__athome_drawer);
81 
82  Gtk::RadioButton::Group group = __tb_lines.get_group();
83  __tb_points.set_group(group);
84  group = __tb_lines.get_group();
85  __tb_hull.set_group(group);
86  __tb_lines.set_active(true);
87 
88  __tb_lines.set_sensitive(false);
89  __tb_points.set_sensitive(false);
90  __tb_hull.set_sensitive(false);
91  __tb_lowres.set_sensitive(false);
92  __tb_rotation.set_sensitive(false);
93  __tb_zoom_in.set_sensitive(false);
94  __tb_zoom_out.set_sensitive(false);
95 
96  __tbar.append(__tb_connection);
97  __tbar.append(__sep_0);
98  __tbar.append(__tb_lines);
99  __tbar.append(__tb_points);
100  __tbar.append(__tb_hull);
101  __tbar.append(__sep_1);
102  __tbar.append(__tb_lowres);
103  __tbar.append(__tb_rotation);
104  __tbar.append(__sep_2);
105  __tbar.append(__tb_zoom_in);
106  __tbar.append(__tb_zoom_out);
107 
108  add_toolbar(__tbar);
109  __tbar.show_all();
110 
111  __tb_lines.signal_toggled().connect(sigc::bind(sigc::mem_fun(__area, &LaserDrawingArea::set_draw_mode), LaserDrawingArea::MODE_LINES));
112  __tb_points.signal_toggled().connect(sigc::bind(sigc::mem_fun(__area, &LaserDrawingArea::set_draw_mode), LaserDrawingArea::MODE_POINTS));
113  __tb_hull.signal_toggled().connect(sigc::bind(sigc::mem_fun(__area, &LaserDrawingArea::set_draw_mode), LaserDrawingArea::MODE_HULL));
114  __tb_zoom_in.signal_clicked().connect(sigc::mem_fun(__area, &LaserDrawingArea::zoom_in));
115  __tb_zoom_out.signal_clicked().connect(sigc::mem_fun(__area, &LaserDrawingArea::zoom_out));
116 
117  __tb_connection.signal_clicked().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_connection_clicked));
118  __tb_rotation.signal_clicked().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_rotation_toggled));
119  __tb_lowres.signal_clicked().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_resolution_toggled));
120 
121  __connection_dispatcher.signal_connected().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_connect));
122  __connection_dispatcher.signal_disconnected().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_disconnect));
123 
124 #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
125  signal_key_press_event().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_key_pressed));
126  signal_window_state_event().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_window_state_event));
127 #endif
128  }
129 
130  /** Destructor. */
132  {
133  __area.set_laser360_if(NULL);
134  if (__bb) {
135  __bb->close(__laser_if);
136  delete __bb;
137  delete __ifd;
138  }
139  }
140 
141  protected:
142  /** Event handler for key pressed events.
143  * @param event event parameters
144  * @return always false
145  */
146  virtual bool on_key_pressed(GdkEventKey* event)
147  {
148  if(!event) return false;
149 
150  switch (event->keyval) {
151  case GDK_F6:
152  if ( __fullscreen ) {
153  unfullscreen();
154  } else {
155  fullscreen();
156  }
157  break;
158  case GDK_F7:
159  __area.zoom_in();
160  break;
161  case GDK_F8:
162  __area.zoom_out();
163  break;
164  }
165 
166  // Returning true would stop the event now
167  return false;
168  }
169 
170  /** Event handler for window state change events.
171  * @param event event parameters
172  * @return always false
173  */
174  virtual bool on_window_state_event(GdkEventWindowState *event)
175  {
176  if (event->new_window_state == GDK_WINDOW_STATE_FULLSCREEN) {
177  __fullscreen = true;
178  } else {
179  __fullscreen = false;
180  }
181  return false;
182  }
183 
184  /** Event handler for connection button. */
186  {
187  if ( ! __connection_dispatcher.get_client()->connected() ) {
188  ServiceChooserDialog ssd(*this, __connection_dispatcher.get_client());
189  ssd.run_and_connect();
190  } else {
191  __connection_dispatcher.get_client()->disconnect();
192  }
193  }
194 
195  /** Event handler for connected event. */
196  virtual void on_connect()
197  {
198  try {
199  __bb = new RemoteBlackBoard(__connection_dispatcher.get_client());
200  __laser_if = __bb->open_for_reading<Laser360Interface>("Laser");
201 
202  __area.set_laser360_if(__laser_if);
203  __ifd = new InterfaceDispatcher("LaserInterfaceDispatcher", __laser_if);
204  __ifd->signal_data_changed().connect(sigc::hide(sigc::mem_fun(__area, &LaserDrawingArea::queue_draw)));
205  __ifd->signal_writer_removed().connect(sigc::hide(sigc::mem_fun(__area, &LaserDrawingArea::queue_draw)));
206  __bb->register_listener(__ifd, BlackBoard::BBIL_FLAG_DATA | BlackBoard::BBIL_FLAG_WRITER);
207 
208  __area.queue_draw();
209 
210  __tb_connection.set_stock_id(Gtk::Stock::DISCONNECT);
211  __tb_lines.set_sensitive(true);
212  __tb_points.set_sensitive(true);
213  __tb_hull.set_sensitive(true);
214  __tb_lowres.set_sensitive(true);
215  __tb_rotation.set_sensitive(true);
216  __tb_zoom_in.set_sensitive(true);
217  __tb_zoom_out.set_sensitive(true);
218  } catch (Exception &e) {
219  e.print_trace();
220  if ( __bb ) {
221  __bb->close(__laser_if);
222  delete __ifd;
223  delete __bb;
224  __laser_if = NULL;
225  __bb = NULL;
226  __ifd = NULL;
227  }
228  }
229  }
230 
231  /** Event handler for disconnected event. */
232  virtual void on_disconnect()
233  {
234  __area.set_laser360_if(NULL);
235  __area.queue_draw();
236  __bb->close(__laser_if);
237  delete __bb;
238  delete __ifd;
239  __bb = NULL;
240  __ifd = NULL;
241  __laser_if = NULL;
242  __tb_connection.set_stock_id(Gtk::Stock::CONNECT);
243  __tb_lines.set_sensitive(false);
244  __tb_points.set_sensitive(false);
245  __tb_hull.set_sensitive(false);
246  __tb_lowres.set_sensitive(false);
247  __tb_rotation.set_sensitive(false);
248  __tb_zoom_in.set_sensitive(false);
249  __tb_zoom_out.set_sensitive(false);
250  }
251 
252  /** Event handler for rotation button. */
254  {
255  if ( __tb_rotation.get_active() ) {
256  __area.set_rotation(M_PI / 2);
257  } else {
258  __area.set_rotation(0);
259  }
260  }
261 
262  /** Event handler for rotation button. */
264  {
265  if ( __tb_lowres.get_active() ) {
266  __area.set_resolution(3);
267  } else {
268  __area.set_resolution(1);
269  }
270  }
271 
272  private:
273  AllemaniACsAtHomeCairoRobotDrawer __athome_drawer;
274  BlackBoard *__bb;
275  Laser360Interface *__laser_if;
276  InterfaceDispatcher *__ifd;
277  ConnectionDispatcher __connection_dispatcher;
278 
279  Gtk::Image __img_lines;
280  Gtk::Image __img_points;
281  Gtk::Image __img_hull;
282  Gtk::Image __img_lowres;
283  Gtk::Image __img_rotation;
284  Gtk::ToolButton __tb_connection;
285  Gtk::SeparatorToolItem __sep_0;
286  Gtk::RadioToolButton __tb_lines;
287  Gtk::RadioToolButton __tb_points;
288  Gtk::RadioToolButton __tb_hull;
289  Gtk::SeparatorToolItem __sep_1;
290  Gtk::ToggleToolButton __tb_lowres;
291  Gtk::ToggleToolButton __tb_rotation;
292  Gtk::SeparatorToolItem __sep_2;
293  Gtk::ToolButton __tb_zoom_in;
294  Gtk::ToolButton __tb_zoom_out;
295  Gtk::Toolbar __tbar;
296 
297  LaserDrawingArea __area;
298 
299  bool __fullscreen;
300 };
301 
302 int
303 main(int argc, char** argv)
304 {
305  Gtk::Main kit(argc, argv);
306  Hildon::init();
307 
308  osso_context_t* osso_context = osso_initialize("lasergui", "0.1", TRUE /* deprecated parameter */, 0 /* Use default Glib main loop context */);
309  Glib::set_application_name("Laser GUI");
310 
311  LaserGuiHildonWindow window;
312  kit.run(window);
313 
314  osso_deinitialize(osso_context);
315  return 0;
316 }
Laser360Interface Fawkes BlackBoard Interface.
consider data events
Definition: blackboard.h:83
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.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier)
Open interface for reading.
Definition: remote.cpp:272
void zoom_out()
Zoom out.
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:619
consider writer events
Definition: blackboard.h:86
Remote BlackBoard.
Definition: remote.h:49
The BlackBoard abstract class.
Definition: blackboard.h:49
Watches network client events and dispatches them as signals.
Draw AllemaniACs AtHome robot.
Interface listener with dispatcher.
void on_rotation_toggled()
Event handler for rotation button.
LaserGuiHildonWindow()
Constructor.