throbber.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <gui_utils/throbber.h>
00025
00026 #include <core/exception.h>
00027 #include <algorithm>
00028
00029 namespace fawkes {
00030 #if 0
00031 }
00032 #endif
00033
00034 #define SPINNER_ICON_NAME "process-working"
00035 #define SPINNER_FALLBACK_ICON_NAME "gnome-spinner"
00036 #define SPINNER_DEFAULT_TIMEOUT 100
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #ifdef HAVE_GLADEMM
00048
00049
00050
00051
00052
00053 Throbber::Throbber(BaseObjectType* cobject,
00054 const Glib::RefPtr<Gnome::Glade::Xml>& refxml)
00055 : Gtk::Image(cobject)
00056 {
00057 Gtk::Container *parent = get_parent();
00058 Gtk::ToolItem *toolitem = dynamic_cast<Gtk::ToolItem *>(parent);
00059 if ( toolitem ) {
00060 ctor(toolitem->get_icon_size());
00061 } else {
00062
00063 ctor(Gtk::IconSize(Gtk::ICON_SIZE_BUTTON));
00064 }
00065 }
00066 #endif
00067
00068
00069
00070
00071
00072
00073 Throbber::Throbber(Gtk::IconSize &icon_size)
00074 {
00075 ctor(icon_size);
00076 }
00077
00078
00079 void
00080 Throbber::ctor(Gtk::IconSize icon_size)
00081 {
00082 __timeout = SPINNER_DEFAULT_TIMEOUT;
00083 __icon_size = icon_size;
00084
00085 int isw = 0, ish = 0;
00086 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 14 )
00087 Glib::RefPtr<Gtk::Settings> settings = Gtk::Settings::get_for_screen(get_screen());
00088 if ( ! Gtk::IconSize::lookup(icon_size, isw, ish, settings) ) {
00089 throw Exception("Could not get icon sizes");
00090 }
00091 #else
00092 if ( ! Gtk::IconSize::lookup(icon_size, isw, ish) ) {
00093 throw Exception("Could not get icon sizes");
00094 }
00095 #endif
00096 int requested_size = std::max(isw, ish);
00097
00098 Glib::RefPtr<Gtk::IconTheme> icon_theme = Gtk::IconTheme::get_for_screen(get_screen());
00099 Gtk::IconInfo icon_info = icon_theme->lookup_icon(SPINNER_ICON_NAME,
00100 requested_size,
00101 Gtk::IconLookupFlags());
00102 if ( ! icon_info ) {
00103 icon_info = icon_theme->lookup_icon(SPINNER_FALLBACK_ICON_NAME,
00104 requested_size, Gtk::IconLookupFlags());
00105 if ( ! icon_info ) {
00106 throw Exception("Could not find neither default nor fallback throbber icon");
00107 }
00108 }
00109
00110 int size = icon_info.get_base_size();
00111
00112 #ifdef GLIBMM_EXCEPTIONS_ENABLED
00113 Glib::RefPtr<Gdk::Pixbuf> icon = icon_info.load_icon();
00114 #else
00115 std::auto_ptr<Glib::Error> error;
00116 Glib::RefPtr<Gdk::Pixbuf> icon = icon_info.load_icon(error);
00117 #endif
00118
00119 int pixwidth = icon->get_width();
00120 int pixheight = icon->get_height();
00121
00122 for (int y = 0; y < pixheight; y += size) {
00123 for (int x = 0; x < pixwidth ; x += size) {
00124 if ( (x + size <= icon->get_width()) &&
00125 (y + size <= icon->get_height()) ) {
00126 Glib::RefPtr<Gdk::Pixbuf> p = Gdk::Pixbuf::create_subpixbuf(icon, x, y, size, size);
00127 __pixbufs.push_back(p);
00128 }
00129 }
00130 }
00131
00132 if ( __pixbufs.empty() ) {
00133 throw Exception("Could not extract any throbber images from pixbuf");
00134 }
00135
00136 __current = 0;
00137 set(__pixbufs.front());
00138 }
00139
00140
00141
00142
00143
00144 bool
00145 Throbber::draw_next()
00146 {
00147 __current = (__current + 1) % __pixbufs.size();
00148 if ( (__current == 0) && (__pixbufs.size() > 1) ) {
00149 __current = 1;
00150 }
00151 set(__pixbufs[__current]);
00152
00153 return true;
00154 }
00155
00156
00157
00158
00159
00160
00161 void
00162 Throbber::set_timeout(unsigned int timeout)
00163 {
00164 __timeout = timeout;
00165 }
00166
00167
00168
00169
00170
00171 bool
00172 Throbber::anim_running()
00173 {
00174 return (__timeout_connection && __timeout_connection.connected());
00175 }
00176
00177
00178 void
00179 Throbber::start_anim()
00180 {
00181 if ( ! __timeout_connection || ! __timeout_connection.connected()) {
00182 __timeout_connection = Glib::signal_timeout().connect(
00183 sigc::mem_fun(*this, &Throbber::draw_next), __timeout);
00184 }
00185 }
00186
00187
00188 void
00189 Throbber::stop_anim()
00190 {
00191 if (__timeout_connection && __timeout_connection.connected()) {
00192 __timeout_connection.disconnect();
00193 }
00194
00195 __current = 0;
00196 set(__pixbufs.front());
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206 void
00207 Throbber::set_stock(const Gtk::StockID& stock_id)
00208 {
00209 set(stock_id, __icon_size);
00210 }
00211
00212
00213 }