1 /*
2  */
3 
4 /*
5 
6     Copyright (C) 2014 Ferrero Andrea
7 
8     This program is free software: you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21 
22  */
23 
24 /*
25 
26     These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/
27 
28  */
29 
30 #include <iostream>
31 
32 #include "imagebutton.hh"
33 
34 
ImageButton(Glib::ustring i,Glib::ustring pi)35 PF::ImageButton::ImageButton(Glib::ustring i, Glib::ustring pi)
36 {
37   img.set( i );
38   pressed_img.set( pi );
39 
40   img_align.set(0.5,0.5,0,0);
41   pressed_img_align.set(0.5,0.5,0,0);
42 
43   img_align.add(img);
44   pressed_img_align.add(pressed_img);
45 
46   button_box.pack_start( img_align, Gtk::PACK_EXPAND_WIDGET );
47   //button_box.pack_start( pressed_img, Gtk::PACK_SHRINK );
48   event_box.set_visible_window(false);
49   event_box.add( button_box );
50   event_box.add_events( Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK );
51 
52   pack_start( event_box, Gtk::PACK_EXPAND_WIDGET );
53 
54   show_all_children();
55 
56   //pressed_img.hide();
57 }
58 
59 
on_realize()60 void PF::ImageButton::on_realize()
61 {
62   //img.show();
63   //pressed_img.hide();
64   Gtk::VBox::on_realize();
65 }
66 
67 
on_map()68 void PF::ImageButton::on_map()
69 {
70   //img.show();
71   //pressed_img.hide();
72   Gtk::VBox::on_map();
73 }
74 
75 
on_button_press_event(GdkEventButton * button)76 bool PF::ImageButton::on_button_press_event( GdkEventButton* button )
77 {
78   if( button->type != GDK_BUTTON_PRESS || button->button != 1 ) return false;
79 #ifndef NDEBUG
80   std::cout<<"PF::ToggleImageButton::on_button_press_event(): button "<<button->button<<" pressed."<<std::endl;
81 #endif
82   button_box.remove( img_align );
83   button_box.pack_start( pressed_img_align, Gtk::PACK_SHRINK );
84   show_all_children();
85   return true;
86 }
87 
88 
on_button_release_event(GdkEventButton * button)89 bool PF::ImageButton::on_button_release_event( GdkEventButton* button )
90 {
91 #ifndef NDEBUG
92   std::cout<<"PF::ToggleImageButton::on_button_release_event(): button "<<button->button<<" released."<<std::endl;
93 #endif
94   if( button->button != 1 ) return false;
95 
96   signal_clicked.emit();
97 
98   button_box.remove( pressed_img_align );
99   button_box.pack_start( img_align, Gtk::PACK_SHRINK );
100   show_all_children();
101   return true;
102 }
103 
104 
105 
ToggleImageButton(Glib::ustring active,Glib::ustring inactive,bool t,bool a)106 PF::ToggleImageButton::ToggleImageButton(Glib::ustring active, Glib::ustring inactive,
107     bool t, bool a):
108 active(true),
109 do_toggle(t),
110 pressed(false)
111 {
112   active_img.set( active );
113   inactive_img.set( inactive );
114   button_box.pack_start( active_img, Gtk::PACK_SHRINK );
115   event_box.add( button_box );
116   event_box.add_events( Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK );
117 
118   pack_start( event_box, Gtk::PACK_SHRINK );
119 
120   //event_box.signal_button_release_event().connect(sigc::mem_fun(*this,
121   //    &ToggleImageButton::on_button_release_event) );
122 
123   set_active(a);
124   show_all_children();
125 }
126 
127 
128 
set_active(bool newval)129 void PF::ToggleImageButton::set_active( bool newval )
130 {
131   //std::cout<<"ToggleImageButton::set_active("<<newval<<") called (active="<<active<<")"<<std::endl;
132   if( active == newval ) return;
133   if( inactive_img.get_parent() == &button_box )
134     button_box.remove( inactive_img );
135   if( active_img.get_parent() == &button_box )
136     button_box.remove( active_img );
137   if( newval ) {
138     button_box.pack_start( active_img, Gtk::PACK_SHRINK );
139     active_img.show();
140   } else {
141     button_box.pack_start( inactive_img, Gtk::PACK_SHRINK );
142     inactive_img.show();
143   }
144   active = newval;
145 }
146 
147 
148 
toggle()149 void PF::ToggleImageButton::toggle()
150 {
151   bool new_state = !is_active();
152   //std::cout<<"ToggleImageButton::toggle(): is_active()="<<is_active()<<"  new_state="<<new_state<<std::endl;
153   set_active( new_state );
154   if( new_state ) {
155     signal_activated.emit();
156   } else {
157     signal_deactivated.emit();
158   }
159 }
160 
161 
162 
on_button_press_event(GdkEventButton * button)163 bool PF::ToggleImageButton::on_button_press_event( GdkEventButton* button )
164 {
165 #ifndef NDEBUG
166   std::cout<<"PF::ToggleImageButton::on_button_press_event(): button "<<button->button<<" pressed."<<std::endl;
167 #endif
168   if( button->button != 1 ) return false;
169   pressed = true;
170   signal_pressed.emit();
171   return true;
172 }
173 
174 
on_button_release_event(GdkEventButton * button)175 bool PF::ToggleImageButton::on_button_release_event( GdkEventButton* button )
176 {
177 #ifndef NDEBUG
178   std::cout<<"PF::ToggleImageButton::on_button_release_event(): button "<<button->button<<" released."<<std::endl;
179 #endif
180   if( button->button != 1 ) return false;
181 
182   pressed = false;
183 
184   if( do_toggle ) {
185     toggle();
186   } else {
187     if( active ) signal_clicked.emit();
188   }
189   return true;
190 }
191 
192 
add_button(PF::ToggleImageButton * button)193 void PF::ToggleImageButtonsBox::add_button( PF::ToggleImageButton* button )
194 {
195   buttons.push_back(button);
196   pack_start( *button, Gtk::PACK_SHRINK, 4 );
197 
198   button->signal_pressed.connect(sigc::mem_fun(*this,
199           &ToggleImageButtonsBox::on_button_pressed) );
200 }
201 
202 
on_button_pressed()203 void PF::ToggleImageButtonsBox::on_button_pressed()
204 {
205   for( unsigned int i = 0; i < buttons.size(); i++ ) {
206     if( buttons[i]->is_active() ) {
207       if( !(buttons[i]->is_pressed()) ) {
208         // de-activate the button, except if it is the pressed one
209         buttons[i]->toggle();
210       }
211     } else {
212       if( buttons[i]->is_pressed() ) {
213         // if it is the pressed one, activate it
214         buttons[i]->toggle();
215       }
216     }
217   }
218 }
219 
220 
221