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 <blackboard/remote.h>
26 #include <gui_utils/connection_dispatcher.h>
27 #include <gui_utils/interface_dispatcher.h>
28 #include <gui_utils/robot/allemaniacs_athome.h>
29 #include <gui_utils/service_chooser_dialog.h>
30 #include <interfaces/Laser360Interface.h>
31 #include <netcomm/fawkes/client.h>
32 
33 #include <gtkmm.h>
34 #include <hildonmm.h>
35 #include <libosso.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(
116  sigc::bind(sigc::mem_fun(area_, &LaserDrawingArea::set_draw_mode),
118  tb_points_.signal_toggled().connect(
119  sigc::bind(sigc::mem_fun(area_, &LaserDrawingArea::set_draw_mode),
121  tb_hull_.signal_toggled().connect(
122  sigc::bind(sigc::mem_fun(area_, &LaserDrawingArea::set_draw_mode),
124  tb_zoom_in_.signal_clicked().connect(sigc::mem_fun(area_, &LaserDrawingArea::zoom_in));
125  tb_zoom_out_.signal_clicked().connect(sigc::mem_fun(area_, &LaserDrawingArea::zoom_out));
126 
127  tb_connection_.signal_clicked().connect(
128  sigc::mem_fun(*this, &LaserGuiHildonWindow::on_connection_clicked));
129  tb_rotation_.signal_clicked().connect(
130  sigc::mem_fun(*this, &LaserGuiHildonWindow::on_rotation_toggled));
131  tb_lowres_.signal_clicked().connect(
132  sigc::mem_fun(*this, &LaserGuiHildonWindow::on_resolution_toggled));
133 
134  connection_dispatcher_.signal_connected().connect(
135  sigc::mem_fun(*this, &LaserGuiHildonWindow::on_connect));
136  connection_dispatcher_.signal_disconnected().connect(
137  sigc::mem_fun(*this, &LaserGuiHildonWindow::on_disconnect));
138 
139 #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
140  signal_key_press_event().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_key_pressed));
141  signal_window_state_event().connect(
142  sigc::mem_fun(*this, &LaserGuiHildonWindow::on_window_state_event));
143 #endif
144  }
145 
146  /** Destructor. */
148  {
149  area_.set_laser360_if(NULL);
150  if (bb_) {
151  bb_->close(laser_if_);
152  delete bb_;
153  delete ifd_;
154  }
155  }
156 
157 protected:
158  /** Event handler for key pressed events.
159  * @param event event parameters
160  * @return always false
161  */
162  virtual bool
163  on_key_pressed(GdkEventKey *event)
164  {
165  if (!event)
166  return false;
167 
168  switch (event->keyval) {
169  case GDK_F6:
170  if (fullscreen_) {
171  unfullscreen();
172  } else {
173  fullscreen();
174  }
175  break;
176  case GDK_F7: area_.zoom_in(); break;
177  case GDK_F8: area_.zoom_out(); break;
178  }
179 
180  // Returning true would stop the event now
181  return false;
182  }
183 
184  /** Event handler for window state change events.
185  * @param event event parameters
186  * @return always false
187  */
188  virtual bool
189  on_window_state_event(GdkEventWindowState *event)
190  {
191  if (event->new_window_state == GDK_WINDOW_STATE_FULLSCREEN) {
192  fullscreen_ = true;
193  } else {
194  fullscreen_ = false;
195  }
196  return false;
197  }
198 
199  /** Event handler for connection button. */
200  void
201  on_connection_clicked()
202  {
203  if (!connection_dispatcher_.get_client()->connected()) {
204  ServiceChooserDialog ssd(*this, connection_dispatcher_.get_client());
205  ssd.run_and_connect();
206  } else {
207  connection_dispatcher_.get_client()->disconnect();
208  }
209  }
210 
211  /** Event handler for connected event. */
212  virtual void
213  on_connect()
214  {
215  try {
216  bb_ = new RemoteBlackBoard(connection_dispatcher_.get_client());
217  laser_if_ = bb_->open_for_reading<Laser360Interface>("Laser");
218 
219  area_.set_laser360_if(laser_if_);
220  ifd_ = new InterfaceDispatcher("LaserInterfaceDispatcher", laser_if_);
221  ifd_->signal_data_changed().connect(
222  sigc::hide(sigc::mem_fun(area_, &LaserDrawingArea::queue_draw)));
223  ifd_->signal_writer_removed().connect(
224  sigc::hide(sigc::mem_fun(area_, &LaserDrawingArea::queue_draw)));
225  bb_->register_listener(ifd_, BlackBoard::BBIL_FLAG_DATA | BlackBoard::BBIL_FLAG_WRITER);
226 
227  area_.queue_draw();
228 
229  tb_connection_.set_stock_id(Gtk::Stock::DISCONNECT);
230  tb_lines_.set_sensitive(true);
231  tb_points_.set_sensitive(true);
232  tb_hull_.set_sensitive(true);
233  tb_lowres_.set_sensitive(true);
234  tb_rotation_.set_sensitive(true);
235  tb_zoom_in_.set_sensitive(true);
236  tb_zoom_out_.set_sensitive(true);
237  } catch (Exception &e) {
238  e.print_trace();
239  if (bb_) {
240  bb_->close(laser_if_);
241  delete ifd_;
242  delete bb_;
243  laser_if_ = NULL;
244  bb_ = NULL;
245  ifd_ = NULL;
246  }
247  }
248  }
249 
250  /** Event handler for disconnected event. */
251  virtual void
252  on_disconnect()
253  {
254  area_.set_laser360_if(NULL);
255  area_.queue_draw();
256  bb_->close(laser_if_);
257  delete bb_;
258  delete ifd_;
259  bb_ = NULL;
260  ifd_ = NULL;
261  laser_if_ = NULL;
262  tb_connection_.set_stock_id(Gtk::Stock::CONNECT);
263  tb_lines_.set_sensitive(false);
264  tb_points_.set_sensitive(false);
265  tb_hull_.set_sensitive(false);
266  tb_lowres_.set_sensitive(false);
267  tb_rotation_.set_sensitive(false);
268  tb_zoom_in_.set_sensitive(false);
269  tb_zoom_out_.set_sensitive(false);
270  }
271 
272  /** Event handler for rotation button. */
273  void
274  on_rotation_toggled()
275  {
276  if (tb_rotation_.get_active()) {
277  area_.set_rotation(M_PI / 2);
278  } else {
279  area_.set_rotation(0);
280  }
281  }
282 
283  /** Event handler for rotation button. */
284  void
285  on_resolution_toggled()
286  {
287  if (tb_lowres_.get_active()) {
288  area_.set_resolution(3);
289  } else {
290  area_.set_resolution(1);
291  }
292  }
293 
294 private:
295  AllemaniACsAtHomeCairoRobotDrawer athome_drawer_;
296  BlackBoard * bb_;
297  Laser360Interface * laser_if_;
298  InterfaceDispatcher * ifd_;
299  ConnectionDispatcher connection_dispatcher_;
300 
301  Gtk::Image img_lines_;
302  Gtk::Image img_points_;
303  Gtk::Image img_hull_;
304  Gtk::Image img_lowres_;
305  Gtk::Image img_rotation_;
306  Gtk::ToolButton tb_connection_;
307  Gtk::SeparatorToolItem sep_0_;
308  Gtk::RadioToolButton tb_lines_;
309  Gtk::RadioToolButton tb_points_;
310  Gtk::RadioToolButton tb_hull_;
311  Gtk::SeparatorToolItem sep_1_;
312  Gtk::ToggleToolButton tb_lowres_;
313  Gtk::ToggleToolButton tb_rotation_;
314  Gtk::SeparatorToolItem sep_2_;
315  Gtk::ToolButton tb_zoom_in_;
316  Gtk::ToolButton tb_zoom_out_;
317  Gtk::Toolbar tbar_;
318 
319  LaserDrawingArea area_;
320 
321  bool fullscreen_;
322 };
323 
324 int
325 main(int argc, char **argv)
326 {
327  Gtk::Main kit(argc, argv);
328  Hildon::init();
329 
330  osso_context_t *osso_context = osso_initialize("lasergui",
331  "0.1",
332  TRUE /* deprecated parameter */,
333  0 /* Use default Glib main loop context */);
334  Glib::set_application_name("Laser GUI");
335 
336  LaserGuiHildonWindow window;
337  kit.run(window);
338 
339  osso_deinitialize(osso_context);
340  return 0;
341 }
LaserDrawingArea::zoom_in
void zoom_in()
Zoom in.
Definition: laser_drawing_area.cpp:286
fawkes::BlackBoard::BBIL_FLAG_DATA
consider data events
Definition: blackboard.h:91
LaserDrawingArea::MODE_POINTS
Only draw beam end points.
Definition: laser_drawing_area.h:50
LaserGuiHildonWindow::on_key_pressed
virtual bool on_key_pressed(GdkEventKey *event)
Event handler for key pressed events.
Definition: lasergui_hildon.cpp:162
LaserDrawingArea::MODE_HULL
Draw hull of beams.
Definition: laser_drawing_area.h:51
fawkes::BlackBoard
Definition: blackboard.h:48
fawkes::RemoteBlackBoard
Definition: remote.h:51
LaserGuiHildonWindow::on_disconnect
virtual void on_disconnect()
Event handler for disconnected event.
Definition: lasergui_hildon.cpp:251
LaserDrawingArea::zoom_out
void zoom_out()
Zoom out.
Definition: laser_drawing_area.cpp:296
LaserGuiHildonWindow::on_connection_clicked
void on_connection_clicked()
Event handler for connection button.
Definition: lasergui_hildon.cpp:200
LaserGuiHildonWindow::on_connect
virtual void on_connect()
Event handler for connected event.
Definition: lasergui_hildon.cpp:212
LaserGuiHildonWindow::on_resolution_toggled
void on_resolution_toggled()
Event handler for rotation button.
Definition: lasergui_hildon.cpp:284
fawkes::ConnectionDispatcher
Definition: connection_dispatcher.h:42
fawkes
LaserGuiHildonWindow::on_window_state_event
virtual bool on_window_state_event(GdkEventWindowState *event)
Event handler for window state change events.
Definition: lasergui_hildon.cpp:188
fawkes::ServiceChooserDialog
Definition: service_chooser_dialog.h:49
LaserDrawingArea
Definition: laser_drawing_area.h:44
fawkes::Exception::print_trace
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:600
fawkes::InterfaceDispatcher
Definition: interface_dispatcher.h:40
LaserDrawingArea::set_draw_mode
void set_draw_mode(draw_mode_t mode)
Set the drawing mode.
Definition: laser_drawing_area.cpp:276
LaserDrawingArea::MODE_LINES
Draw beams as lines.
Definition: laser_drawing_area.h:49
fawkes::BlackBoard::BBIL_FLAG_WRITER
consider writer events
Definition: blackboard.h:94
LaserGuiHildonWindow::on_rotation_toggled
void on_rotation_toggled()
Event handler for rotation button.
Definition: lasergui_hildon.cpp:273
fawkes::AllemaniACsAtHomeCairoRobotDrawer
Definition: allemaniacs_athome.h:35
fawkes::Laser360Interface
Definition: Laser360Interface.h:37
fawkes::RemoteBlackBoard::open_for_reading
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)
Definition: remote.cpp:270
LaserGuiHildonWindow
Definition: lasergui_hildon.cpp:49
fawkes::ServiceChooserDialog::run_and_connect
void run_and_connect()
Run dialog and try to connect.
Definition: service_chooser_dialog.cpp:280
fawkes::Exception
Definition: exception.h:39