1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/gtk1/bmpbuttn.cpp
3 // Purpose:
4 // Author:      Robert Roebling
5 // Copyright:   (c) 1998 Robert Roebling
6 // Licence:     wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8 
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
11 
12 #if wxUSE_BMPBUTTON
13 
14 #include "wx/bmpbuttn.h"
15 
16 #include "wx/gtk1/private.h"
17 
18 //-----------------------------------------------------------------------------
19 // classes
20 //-----------------------------------------------------------------------------
21 
22 class wxBitmapButton;
23 
24 //-----------------------------------------------------------------------------
25 // idle system
26 //-----------------------------------------------------------------------------
27 
28 extern void wxapp_install_idle_handler();
29 extern bool g_isIdle;
30 
31 //-----------------------------------------------------------------------------
32 // data
33 //-----------------------------------------------------------------------------
34 
35 extern bool   g_blockEventsOnDrag;
36 
37 //-----------------------------------------------------------------------------
38 // "clicked"
39 //-----------------------------------------------------------------------------
40 
41 extern "C" {
gtk_bmpbutton_clicked_callback(GtkWidget * WXUNUSED (widget),wxBitmapButton * button)42 static void gtk_bmpbutton_clicked_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
43 {
44     if (g_isIdle)
45         wxapp_install_idle_handler();
46 
47     if (!button->m_hasVMT) return;
48     if (g_blockEventsOnDrag) return;
49 
50     wxCommandEvent event(wxEVT_BUTTON, button->GetId());
51     event.SetEventObject(button);
52     button->HandleWindowEvent(event);
53 }
54 }
55 
56 //-----------------------------------------------------------------------------
57 // "enter"
58 //-----------------------------------------------------------------------------
59 
60 extern "C" {
gtk_bmpbutton_enter_callback(GtkWidget * WXUNUSED (widget),wxBitmapButton * button)61 static void gtk_bmpbutton_enter_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
62 {
63     if (!button->m_hasVMT) return;
64     if (g_blockEventsOnDrag) return;
65 
66     button->GTKSetHasFocus();
67 }
68 }
69 
70 //-----------------------------------------------------------------------------
71 // "leave"
72 //-----------------------------------------------------------------------------
73 
74 extern "C" {
gtk_bmpbutton_leave_callback(GtkWidget * WXUNUSED (widget),wxBitmapButton * button)75 static void gtk_bmpbutton_leave_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
76 {
77     if (!button->m_hasVMT) return;
78     if (g_blockEventsOnDrag) return;
79 
80     button->GTKSetNotFocus();
81 }
82 }
83 
84 //-----------------------------------------------------------------------------
85 // "pressed"
86 //-----------------------------------------------------------------------------
87 
88 extern "C" {
gtk_bmpbutton_press_callback(GtkWidget * WXUNUSED (widget),wxBitmapButton * button)89 static void gtk_bmpbutton_press_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
90 {
91     if (!button->m_hasVMT) return;
92     if (g_blockEventsOnDrag) return;
93 
94     button->StartSelect();
95 }
96 }
97 
98 //-----------------------------------------------------------------------------
99 // "released"
100 //-----------------------------------------------------------------------------
101 
102 extern "C" {
gtk_bmpbutton_release_callback(GtkWidget * WXUNUSED (widget),wxBitmapButton * button)103 static void gtk_bmpbutton_release_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button )
104 {
105     if (!button->m_hasVMT) return;
106     if (g_blockEventsOnDrag) return;
107 
108     button->EndSelect();
109 }
110 }
111 
112 //-----------------------------------------------------------------------------
113 // wxBitmapButton
114 //-----------------------------------------------------------------------------
115 
Init()116 void wxBitmapButton::Init()
117 {
118     m_hasFocus =
119     m_isSelected = false;
120 }
121 
Create(wxWindow * parent,wxWindowID id,const wxBitmap & bitmap,const wxPoint & pos,const wxSize & size,long style,const wxValidator & validator,const wxString & name)122 bool wxBitmapButton::Create( wxWindow *parent,
123                              wxWindowID id,
124                              const wxBitmap& bitmap,
125                              const wxPoint& pos,
126                              const wxSize& size,
127                              long style,
128                              const wxValidator& validator,
129                              const wxString &name )
130 {
131     m_needParent = true;
132     m_acceptsFocus = true;
133 
134     if (!PreCreation( parent, pos, size ) ||
135         !CreateBase( parent, id, pos, size, style, validator, name ))
136     {
137         wxFAIL_MSG( wxT("wxBitmapButton creation failed") );
138         return false;
139     }
140 
141     m_bitmaps[State_Normal] = bitmap;
142 
143     m_widget = gtk_button_new();
144 
145     if (style & wxNO_BORDER)
146        gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
147 
148     if (bitmap.IsOk())
149     {
150         OnSetBitmap();
151     }
152 
153     gtk_signal_connect_after( GTK_OBJECT(m_widget), "clicked",
154       GTK_SIGNAL_FUNC(gtk_bmpbutton_clicked_callback), (gpointer*)this );
155 
156     gtk_signal_connect( GTK_OBJECT(m_widget), "enter",
157       GTK_SIGNAL_FUNC(gtk_bmpbutton_enter_callback), (gpointer*)this );
158     gtk_signal_connect( GTK_OBJECT(m_widget), "leave",
159       GTK_SIGNAL_FUNC(gtk_bmpbutton_leave_callback), (gpointer*)this );
160     gtk_signal_connect( GTK_OBJECT(m_widget), "pressed",
161       GTK_SIGNAL_FUNC(gtk_bmpbutton_press_callback), (gpointer*)this );
162     gtk_signal_connect( GTK_OBJECT(m_widget), "released",
163       GTK_SIGNAL_FUNC(gtk_bmpbutton_release_callback), (gpointer*)this );
164 
165     m_parent->DoAddChild( this );
166 
167     PostCreation(size);
168 
169     return true;
170 }
171 
SetLabel(const wxString & label)172 void wxBitmapButton::SetLabel( const wxString &label )
173 {
174     wxCHECK_RET( m_widget != NULL, wxT("invalid button") );
175 
176     wxControl::SetLabel( label );
177 }
178 
DoApplyWidgetStyle(GtkRcStyle * style)179 void wxBitmapButton::DoApplyWidgetStyle(GtkRcStyle *style)
180 {
181     if ( !BUTTON_CHILD(m_widget) )
182         return;
183 
184     wxButton::DoApplyWidgetStyle(style);
185 }
186 
OnSetBitmap()187 void wxBitmapButton::OnSetBitmap()
188 {
189     wxCHECK_RET( m_widget != NULL, wxT("invalid bitmap button") );
190 
191     InvalidateBestSize();
192 
193     wxBitmap the_one;
194     if (!IsThisEnabled())
195         the_one = GetBitmapDisabled();
196    else if (m_isSelected)
197      the_one = GetBitmapPressed();
198    else if (HasFocus())
199      the_one = GetBitmapFocus();
200 
201    if (!the_one.IsOk())
202      {
203          the_one = GetBitmapLabel();
204          if (!the_one.IsOk())
205              return;
206      }
207 
208     GdkBitmap *mask = NULL;
209     if (the_one.GetMask()) mask = the_one.GetMask()->GetBitmap();
210 
211     GtkWidget *child = BUTTON_CHILD(m_widget);
212     if (child == NULL)
213     {
214         // initial bitmap
215         GtkWidget *pixmap;
216         pixmap = gtk_pixmap_new(the_one.GetPixmap(), mask);
217         gtk_widget_show(pixmap);
218         gtk_container_add(GTK_CONTAINER(m_widget), pixmap);
219     }
220     else
221     {   // subsequent bitmaps
222         GtkPixmap *pixmap = GTK_PIXMAP(child);
223         gtk_pixmap_set(pixmap, the_one.GetPixmap(), mask);
224     }
225 }
226 
DoGetBestSize() const227 wxSize wxBitmapButton::DoGetBestSize() const
228 {
229     return wxControl::DoGetBestSize();
230 }
231 
Enable(bool enable)232 bool wxBitmapButton::Enable( bool enable )
233 {
234     if ( !wxWindow::Enable(enable) )
235         return false;
236 
237     OnSetBitmap();
238 
239     return true;
240 }
241 
GTKSetHasFocus()242 void wxBitmapButton::GTKSetHasFocus()
243 {
244     m_hasFocus = true;
245     OnSetBitmap();
246 }
247 
GTKSetNotFocus()248 void wxBitmapButton::GTKSetNotFocus()
249 {
250     m_hasFocus = false;
251     OnSetBitmap();
252 }
253 
StartSelect()254 void wxBitmapButton::StartSelect()
255 {
256     m_isSelected = true;
257     OnSetBitmap();
258 }
259 
EndSelect()260 void wxBitmapButton::EndSelect()
261 {
262     m_isSelected = false;
263     OnSetBitmap();
264 }
265 
266 #endif // wxUSE_BMPBUTTON
267