$search
00001 00002 /*************************************************************************** 00003 * throbber.cpp - Fawkes throbber 00004 * 00005 * Created: Tue Nov 04 16:38:03 2008 00006 * Copyright 2008-2010 Tim Niemueller [www.niemueller.de] 00007 * 2010 Carnegie Mellon University 00008 * 2010 Intel Labs Pittsburgh 00009 ****************************************************************************/ 00010 00011 /* This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. A runtime exception applies to 00015 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00016 * 00017 * This program is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU Library General Public License for more details. 00021 * 00022 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00023 */ 00024 00025 00026 #ifndef USE_ROS 00027 # include <gui_utils/throbber.h> 00028 # include <core/exception.h> 00029 #else 00030 # include "throbber.h" 00031 # include <ros/common.h> 00032 # if ROS_VERSION_MAJOR > 1 || ROS_VERSION_MAJOR == 1 && ROS_VERSION_MINOR >= 2 00033 # include <ros/exception.h> 00034 # else 00035 # include <ros/exceptions.h> 00036 # endif 00037 using ros::Exception; 00038 #endif 00039 #include <algorithm> 00040 00041 namespace fawkes { 00042 #if 0 /* just to make Emacs auto-indent happy */ 00043 } 00044 #endif 00045 00046 #define SPINNER_ICON_NAME "process-working" 00047 #define SPINNER_FALLBACK_ICON_NAME "gnome-spinner" 00048 #define SPINNER_DEFAULT_TIMEOUT 100 00049 00050 00059 #ifdef HAVE_GLADEMM 00060 00065 Throbber::Throbber(BaseObjectType* cobject, 00066 const Glib::RefPtr<Gnome::Glade::Xml>& refxml) 00067 : Gtk::Image(cobject) 00068 { 00069 Gtk::Container *parent = get_parent(); 00070 Gtk::ToolItem *toolitem = dynamic_cast<Gtk::ToolItem *>(parent); 00071 if ( toolitem ) { 00072 ctor(toolitem->get_icon_size()); 00073 } else { 00074 // We have no clue, just try button 00075 ctor(Gtk::IconSize(Gtk::ICON_SIZE_BUTTON)); 00076 } 00077 } 00078 #endif 00079 00080 00085 Throbber::Throbber(Gtk::IconSize &icon_size) 00086 { 00087 ctor(icon_size); 00088 } 00089 00090 00091 void 00092 Throbber::ctor(Gtk::IconSize icon_size) 00093 { 00094 __timeout = SPINNER_DEFAULT_TIMEOUT; 00095 __icon_size = icon_size; 00096 00097 int isw = 0, ish = 0; 00098 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 14 ) 00099 Glib::RefPtr<Gtk::Settings> settings = Gtk::Settings::get_for_screen(get_screen()); 00100 if ( ! Gtk::IconSize::lookup(icon_size, isw, ish, settings) ) { 00101 throw Exception("Could not get icon sizes"); 00102 } 00103 #else 00104 if ( ! Gtk::IconSize::lookup(icon_size, isw, ish) ) { 00105 throw Exception("Could not get icon sizes"); 00106 } 00107 #endif 00108 int requested_size = std::max(isw, ish); 00109 00110 Glib::RefPtr<Gtk::IconTheme> icon_theme = Gtk::IconTheme::get_for_screen(get_screen()); 00111 Gtk::IconInfo icon_info = icon_theme->lookup_icon(SPINNER_ICON_NAME, 00112 requested_size, 00113 Gtk::IconLookupFlags()); 00114 if ( ! icon_info ) { 00115 icon_info = icon_theme->lookup_icon(SPINNER_FALLBACK_ICON_NAME, 00116 requested_size, Gtk::IconLookupFlags()); 00117 if ( ! icon_info ) { 00118 throw Exception("Could not find neither default nor fallback throbber icon"); 00119 } 00120 } 00121 00122 int size = icon_info.get_base_size(); 00123 00124 #ifdef GLIBMM_EXCEPTIONS_ENABLED 00125 Glib::RefPtr<Gdk::Pixbuf> icon = icon_info.load_icon(); 00126 #else 00127 std::auto_ptr<Glib::Error> error; 00128 Glib::RefPtr<Gdk::Pixbuf> icon = icon_info.load_icon(error); 00129 #endif 00130 00131 int pixwidth = icon->get_width(); 00132 int pixheight = icon->get_height(); 00133 00134 for (int y = 0; y < pixheight; y += size) { 00135 for (int x = 0; x < pixwidth ; x += size) { 00136 if ( (x + size <= icon->get_width()) && 00137 (y + size <= icon->get_height()) ) { 00138 Glib::RefPtr<Gdk::Pixbuf> p = Gdk::Pixbuf::create_subpixbuf(icon, x, y, size, size); 00139 __pixbufs.push_back(p); 00140 } 00141 } 00142 } 00143 00144 if ( __pixbufs.empty() ) { 00145 throw Exception("Could not extract any throbber images from pixbuf"); 00146 } 00147 00148 __current = 0; 00149 set(__pixbufs.front()); 00150 } 00151 00152 00156 bool 00157 Throbber::draw_next() 00158 { 00159 __current = (__current + 1) % __pixbufs.size(); 00160 if ( (__current == 0) && (__pixbufs.size() > 1) ) { 00161 __current = 1; 00162 } 00163 set(__pixbufs[__current]); 00164 00165 return true; 00166 } 00167 00168 00173 void 00174 Throbber::set_timeout(unsigned int timeout) 00175 { 00176 __timeout = timeout; 00177 } 00178 00179 00183 bool 00184 Throbber::anim_running() 00185 { 00186 return (__timeout_connection && __timeout_connection.connected()); 00187 } 00188 00190 void 00191 Throbber::start_anim() 00192 { 00193 if ( ! __timeout_connection || ! __timeout_connection.connected()) { 00194 __timeout_connection = Glib::signal_timeout().connect( 00195 sigc::mem_fun(*this, &Throbber::draw_next), __timeout); 00196 } 00197 } 00198 00200 void 00201 Throbber::stop_anim() 00202 { 00203 if (__timeout_connection && __timeout_connection.connected()) { 00204 __timeout_connection.disconnect(); 00205 } 00206 00207 __current = 0; 00208 set(__pixbufs.front()); 00209 } 00210 00211 00218 void 00219 Throbber::set_stock(const Gtk::StockID& stock_id) 00220 { 00221 set(stock_id, __icon_size); 00222 } 00223 00224 00225 } // end namespace fawkes