lasergui_hildon.cpp

00001
00002 /***************************************************************************
00003  *  lasergui_hildon.cpp - minimalistic laser visualization on Hildon
00004  *
00005  *  Created: Sun Oct 12 17:06:06 2008
00006  *  Copyright  2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022
00023 #include "laser_drawing_area.h"
00024
00025 #include <gui_utils/robot/allemaniacs_athome.h>
00026 #include <gtkmm.h>
00027 #include <hildonmm.h>
00028
00029 #include <netcomm/fawkes/client.h>
00030 #include <blackboard/remote.h>
00031 #include <interfaces/Laser360Interface.h>
00032 #include <gui_utils/interface_dispatcher.h>
00033 #include <gui_utils/connection_dispatcher.h>
00034 #include <gui_utils/service_chooser_dialog.h>
00035
00036 using namespace fawkes;
00037 
00038 /** @class LaserGuiHildonWindow "lasergui_hildon.cpp"
00039  * Laser GUI window for Hildon.
00040  * @author Tim Niemueller
00041  */
00042
00043 class LaserGuiHildonWindow : public Hildon::Window
00044 {
00045  public:
00046   /** Constructor. */
00047   LaserGuiHildonWindow()
00048     : __athome_drawer(true),
00049       __img_lines("lines_32x32.png"),
00050       __img_points("points_32x32.png"),
00051       __img_hull("hull_32x32.png"),
00052       __img_lowres("lines_lowres_32x32.png"),
00053       __img_rotation("rotate-90.png"),
00054       __tb_connection(Gtk::Stock::CONNECT),
00055       __tb_lines(__img_lines),
00056       __tb_points(__img_points),
00057       __tb_hull(__img_hull),
00058       __tb_lowres(__img_lowres),
00059       __tb_rotation(__img_rotation),
00060       __tb_zoom_in(Gtk::Stock::ZOOM_IN),
00061       __tb_zoom_out(Gtk::Stock::ZOOM_OUT)
00062   {
00063     __fullscreen = false;
00064     __bb = NULL;
00065     __laser_if = NULL;
00066     __ifd = NULL;
00067
00068     std::auto_ptr<Glib::Error> error;
00069     set_icon_from_file("lines_32x32.png", error);
00070
00071     add(__area);
00072     __area.show();
00073     __area.set_robot_drawer(&__athome_drawer);
00074
00075     Gtk::RadioButton::Group group = __tb_lines.get_group();
00076     __tb_points.set_group(group);
00077     group = __tb_lines.get_group();
00078     __tb_hull.set_group(group);
00079     __tb_lines.set_active(true);
00080
00081     __tb_lines.set_sensitive(false);
00082     __tb_points.set_sensitive(false);
00083     __tb_hull.set_sensitive(false);
00084     __tb_lowres.set_sensitive(false);
00085     __tb_rotation.set_sensitive(false);
00086     __tb_zoom_in.set_sensitive(false);
00087     __tb_zoom_out.set_sensitive(false);
00088
00089     __tbar.append(__tb_connection);
00090     __tbar.append(__sep_0);
00091     __tbar.append(__tb_lines);
00092     __tbar.append(__tb_points);
00093     __tbar.append(__tb_hull);
00094     __tbar.append(__sep_1);
00095     __tbar.append(__tb_lowres);
00096     __tbar.append(__tb_rotation);
00097     __tbar.append(__sep_2);
00098     __tbar.append(__tb_zoom_in);
00099     __tbar.append(__tb_zoom_out);
00100
00101     add_toolbar(__tbar);
00102     __tbar.show_all();
00103
00104     __tb_lines.signal_toggled().connect(sigc::bind(sigc::mem_fun(__area, &LaserDrawingArea::set_draw_mode), LaserDrawingArea::MODE_LINES));
00105     __tb_points.signal_toggled().connect(sigc::bind(sigc::mem_fun(__area, &LaserDrawingArea::set_draw_mode), LaserDrawingArea::MODE_POINTS));
00106     __tb_hull.signal_toggled().connect(sigc::bind(sigc::mem_fun(__area, &LaserDrawingArea::set_draw_mode), LaserDrawingArea::MODE_HULL));
00107     __tb_zoom_in.signal_clicked().connect(sigc::mem_fun(__area, &LaserDrawingArea::zoom_in));
00108     __tb_zoom_out.signal_clicked().connect(sigc::mem_fun(__area, &LaserDrawingArea::zoom_out));
00109
00110     __tb_connection.signal_clicked().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_connection_clicked));
00111     __tb_rotation.signal_clicked().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_rotation_toggled));
00112     __tb_lowres.signal_clicked().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_resolution_toggled));
00113
00114     __connection_dispatcher.signal_connected().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_connect));
00115     __connection_dispatcher.signal_disconnected().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_disconnect));
00116
00117 #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
00118     signal_key_press_event().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_key_pressed));
00119     signal_window_state_event().connect(sigc::mem_fun(*this, &LaserGuiHildonWindow::on_window_state_event));
00120 #endif
00121   }
00122 
00123   /** Destructor. */
00124   ~LaserGuiHildonWindow()
00125   {
00126     __area.set_laser_if(NULL);
00127     if (__bb) {
00128       __bb->close(__laser_if);
00129       delete __bb;
00130       delete __ifd;
00131     }
00132   }
00133
00134  protected:
00135   /** Event handler for key pressed events.
00136    * @param event event parameters
00137    */
00138   virtual bool on_key_pressed(GdkEventKey* event)
00139   {
00140     if(!event)  return false;
00141
00142     switch (event->keyval) {
00143     case GDK_F6:
00144       if ( __fullscreen ) {
00145         unfullscreen();
00146       } else {
00147         fullscreen();
00148       }
00149       break;
00150     case GDK_F7:
00151       __area.zoom_in();
00152       break;
00153     case GDK_F8:
00154       __area.zoom_out();
00155       break;
00156     }
00157
00158     // Returning true would stop the event now
00159     return false;
00160   }
00161 
00162   /** Event handler for window state change events.
00163    * @param event event parameters
00164    */
00165   virtual bool on_window_state_event(GdkEventWindowState *event)
00166   {
00167     if (event->new_window_state == GDK_WINDOW_STATE_FULLSCREEN) {
00168       __fullscreen = true;
00169     } else {
00170       __fullscreen = false;
00171     }
00172     return false;
00173   }
00174 
00175   /** Event handler for connection button. */
00176   void on_connection_clicked()
00177   {
00178     if ( ! __connection_dispatcher.get_client()->connected() ) {
00179       ServiceChooserDialog ssd(*this, __connection_dispatcher.get_client());
00180       ssd.run_and_connect();
00181     } else {
00182       __connection_dispatcher.get_client()->disconnect();
00183     }
00184   }
00185 
00186   /** Event handler for connected event. */
00187   virtual void on_connect()
00188   {
00189     try {
00190       __bb = new RemoteBlackBoard(__connection_dispatcher.get_client());
00191       __laser_if = __bb->open_for_reading<Laser360Interface>("Laser");
00192
00193       __area.set_laser_if(__laser_if);
00194       __ifd = new InterfaceDispatcher("LaserInterfaceDispatcher", __laser_if);
00195       __ifd->signal_data_changed().connect(sigc::hide(sigc::mem_fun(__area, &LaserDrawingArea::queue_draw)));
00196       __ifd->signal_writer_removed().connect(sigc::hide(sigc::mem_fun(__area, &LaserDrawingArea::queue_draw)));
00197       __bb->register_listener(__ifd, BlackBoard::BBIL_FLAG_DATA | BlackBoard::BBIL_FLAG_WRITER);
00198
00199       __area.queue_draw();
00200
00201       __tb_connection.set_stock_id(Gtk::Stock::DISCONNECT);
00202       __tb_lines.set_sensitive(true);
00203       __tb_points.set_sensitive(true);
00204       __tb_hull.set_sensitive(true);
00205       __tb_lowres.set_sensitive(true);
00206       __tb_rotation.set_sensitive(true);
00207       __tb_zoom_in.set_sensitive(true);
00208       __tb_zoom_out.set_sensitive(true);
00209     } catch (Exception &e) {
00210       if ( __bb ) {
00211         __bb->close(__laser_if);
00212         delete __ifd;
00213         delete __bb;
00214         __laser_if = NULL;
00215         __bb = NULL;
00216         __ifd = NULL;
00217       }
00218     }
00219   }
00220 
00221   /** Event handler for disconnected event. */
00222   virtual void on_disconnect()
00223   {
00224     __area.set_laser_if(NULL);
00225     __area.queue_draw();
00226     __bb->close(__laser_if);
00227     delete __bb;
00228     delete __ifd;
00229     __bb = NULL;
00230     __ifd = NULL;
00231     __laser_if = NULL;
00232     __tb_connection.set_stock_id(Gtk::Stock::CONNECT);
00233     __tb_lines.set_sensitive(false);
00234     __tb_points.set_sensitive(false);
00235     __tb_hull.set_sensitive(false);
00236     __tb_lowres.set_sensitive(false);
00237     __tb_rotation.set_sensitive(false);
00238     __tb_zoom_in.set_sensitive(false);
00239     __tb_zoom_out.set_sensitive(false);
00240   }
00241 
00242   /** Event handler for rotation button. */
00243   void on_rotation_toggled()
00244   {
00245     if ( __tb_rotation.get_active() ) {
00246       __area.set_rotation(M_PI / 2);
00247     } else {
00248       __area.set_rotation(0);
00249     }
00250   }
00251 
00252   /** Event handler for rotation button. */
00253   void on_resolution_toggled()
00254   {
00255     if ( __tb_lowres.get_active() ) {
00256       __area.set_resolution(3);
00257     } else {
00258       __area.set_resolution(1);
00259     }
00260   }
00261
00262  private:
00263   AllemaniACsAtHomeCairoRobotDrawer  __athome_drawer;
00264   BlackBoard                        *__bb;
00265   Laser360Interface                 *__laser_if;
00266   InterfaceDispatcher               *__ifd;
00267   ConnectionDispatcher               __connection_dispatcher;
00268
00269   Gtk::Image                         __img_lines;
00270   Gtk::Image                         __img_points;
00271   Gtk::Image                         __img_hull;
00272   Gtk::Image                         __img_lowres;
00273   Gtk::Image                         __img_rotation;
00274   Gtk::ToolButton                    __tb_connection;
00275   Gtk::SeparatorToolItem             __sep_0;
00276   Gtk::RadioToolButton               __tb_lines;
00277   Gtk::RadioToolButton               __tb_points;
00278   Gtk::RadioToolButton               __tb_hull;
00279   Gtk::SeparatorToolItem             __sep_1;
00280   Gtk::ToggleToolButton              __tb_lowres;
00281   Gtk::ToggleToolButton              __tb_rotation;
00282   Gtk::SeparatorToolItem             __sep_2;
00283   Gtk::ToolButton                    __tb_zoom_in;
00284   Gtk::ToolButton                    __tb_zoom_out;
00285   Gtk::Toolbar                       __tbar;
00286
00287   LaserDrawingArea                   __area;
00288
00289   bool                               __fullscreen;
00290 };
00291
00292 int
00293 main(int argc, char** argv)
00294 {
00295   Gtk::Main kit(argc, argv);
00296   Hildon::init();
00297
00298   osso_context_t* osso_context = osso_initialize("lasergui", "0.1", TRUE /* deprecated parameter */, 0 /* Use default Glib main loop context */);
00299   Glib::set_application_name("Laser GUI");
00300
00301   LaserGuiHildonWindow window;
00302   kit.run(window);
00303
00304   osso_deinitialize(osso_context);
00305   return 0;
00306 }