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