Canola  0.8.D001
canola/retro_button.cc
Go to the documentation of this file.
00001 //
00002 // canola - canon canola 1614p emulator
00003 // Copyright (C) 2011, 2012 Peter Miller
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, version 3, as
00007 // published by the Free Software Foundation.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program. If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #include <canola/load_image.h>
00019 #include <canola/retro_button.h>
00020 
00021 
00022 retro_button::~retro_button()
00023 {
00024 }
00025 
00026 
00027 static img_ptr_t
00028 load_image(const std::string &name, const std::string &state)
00029 {
00030     std::string filename = "key-" + name + "-" + state;
00031     return load_gui_image(filename);
00032 }
00033 
00034 
00035 retro_button::retro_button(
00036     const char *caption,
00037     const char *color,
00038     const Gdk::RGBA &fg,
00039     bool a_toggle
00040 ) :
00041     text(caption),
00042     inside(false),
00043     pressed(false),
00044     toggle(a_toggle),
00045     active(false)
00046 {
00047     normal_image = load_image(color, "normal");
00048     active_image = load_image(color, "active");
00049     disabled_image = load_image(color, "disabled");
00050 
00051     text.override_color(fg, Gtk::STATE_FLAG_NORMAL);
00052     text.override_color(fg, Gtk::STATE_FLAG_ACTIVE);
00053     text.set_justify(Gtk::JUSTIFY_CENTER);
00054 
00055     appearance.set(normal_image);
00056     text_aligner.add(text);
00057     text_aligner.set_size_request(normal_image->get_width() - 1,
00058         normal_image->get_height() - 1);
00059     layout.put(appearance, 0, 0);
00060     layout.put(text_aligner, 0, 0);
00061     add(layout);
00062 
00063     signal_button_press_event().connect(sigc::mem_fun(*this,
00064         &retro_button::pressed_callback));
00065     signal_button_release_event().connect(sigc::mem_fun(*this,
00066         &retro_button::released_callback));
00067     signal_enter_notify_event().connect(sigc::mem_fun(*this,
00068         &retro_button::enter_callback));
00069     signal_leave_notify_event().connect(sigc::mem_fun(*this,
00070         &retro_button::leave_callback));
00071 
00072     override_background_color(custom_widget_background, Gtk::STATE_FLAG_NORMAL);
00073 }
00074 
00075 
00076 bool
00077 retro_button::pressed_callback(const _GdkEventButton *)
00078 {
00079     pressed = true;
00080     if (toggle)
00081     {
00082         if (active)
00083             up();
00084         else
00085             down();
00086     }
00087     else
00088     {
00089         down();
00090     }
00091     return true;
00092 }
00093 
00094 
00095 bool
00096 retro_button::released_callback(const _GdkEventButton *)
00097 {
00098     if (toggle)
00099     {
00100         if (pressed && inside)
00101         {
00102             if (active)
00103             {
00104                 signal_released_sender.emit();
00105                 up();
00106             }
00107             else
00108             {
00109                 signal_clicked_sender.emit();
00110                 down();
00111             }
00112             active = !active;
00113         }
00114         else
00115         {
00116             // restore
00117             if (active)
00118                 down();
00119             else
00120                 up();
00121         }
00122     }
00123     else
00124     {
00125         if (pressed && inside)
00126         {
00127             signal_clicked_sender.emit();
00128         }
00129         up();
00130     }
00131     pressed = false;
00132     return true;
00133 }
00134 
00135 
00136 bool
00137 retro_button::enter_callback(const _GdkEventCrossing *)
00138 {
00139     inside = true;
00140     if (toggle)
00141     {
00142         if (active)
00143             up();
00144         else
00145             down();
00146     }
00147     else
00148     {
00149         if (pressed)
00150             down();
00151         else
00152             up();
00153     }
00154     return true;
00155 }
00156 
00157 
00158 bool
00159 retro_button::leave_callback(const _GdkEventCrossing *)
00160 {
00161 
00162     inside = false;
00163     if (toggle)
00164     {
00165         if (active)
00166         {
00167             down();
00168         }
00169         else
00170         {
00171             up();
00172         }
00173     }
00174     else
00175     {
00176         up();
00177     }
00178     return true;
00179 }
00180 
00181 
00182 void
00183 retro_button::down(void)
00184 {
00185     appearance.set(active_image);
00186     layout.move(text_aligner, 1, 1);
00187 }
00188 
00189 
00190 void
00191 retro_button::up(void)
00192 {
00193     appearance.set(normal_image);
00194     layout.move(text_aligner, 0, 0);
00195 }