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
43using namespace fawkes;
44
45/** @class LaserGuiHildonWindow "lasergui_hildon.cpp"
46 * Laser GUI window for Hildon.
47 * @author Tim Niemueller
48 */
49
50class LaserGuiHildonWindow : public Hildon::Window
51{
52public:
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
157protected:
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
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
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
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
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
286 {
287 if (tb_lowres_.get_active()) {
288 area_.set_resolution(3);
289 } else {
290 area_.set_resolution(1);
291 }
292 }
293
294private:
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
324int
325main(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
337 kit.run(window);
338
339 osso_deinitialize(osso_context);
340 return 0;
341}
Laser drawing area.
void set_robot_drawer(fawkes::CairoRobotDrawer *robot_drawer)
Set robot drawer.
@ MODE_HULL
Draw hull of beams.
@ MODE_POINTS
Only draw beam end points.
@ MODE_LINES
Draw beams as lines.
void set_resolution(unsigned int resolution)
Set resolution.
void set_rotation(float rot_rad)
Set rotation.
void set_draw_mode(draw_mode_t mode)
Set the drawing mode.
void zoom_in()
Zoom in.
void zoom_out()
Zoom out.
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()
Constructor.
void on_rotation_toggled()
Event handler for rotation button.
~LaserGuiHildonWindow()
Destructor.
virtual void on_connect()
Event handler for connected event.
void on_connection_clicked()
Event handler for connection button.
virtual bool on_key_pressed(GdkEventKey *event)
Event handler for key pressed events.
virtual void on_disconnect()
Event handler for disconnected event.
The BlackBoard abstract class.
Definition: blackboard.h:46
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
Definition: blackboard.cpp:185
virtual void close(Interface *interface)=0
Close interface.
Watches network client events and dispatches them as signals.
sigc::signal< void > signal_connected()
Get "connected" signal.
FawkesNetworkClient * get_client()
Get client.
sigc::signal< void > signal_disconnected()
Get "disconnected" signal.
Base class for exceptions in Fawkes.
Definition: exception.h:36
void print_trace() noexcept
Prints trace to stderr.
Definition: exception.cpp:601
void disconnect()
Disconnect socket.
Definition: client.cpp:539
bool connected() const noexcept
Check if connection is alive.
Definition: client.cpp:828
Interface listener with dispatcher.
sigc::signal< void, Interface * > signal_writer_removed()
Get "writer removed" signal.
sigc::signal< void, Interface * > signal_data_changed()
Get "data changed" signal.
Laser360Interface Fawkes BlackBoard Interface.
Remote BlackBoard.
Definition: remote.h:50
void run_and_connect()
Run dialog and try to connect.
Fawkes library namespace.