1///////////////////////////////////////////////////////////////////////////// 2// Name: src/gtk/bmpbuttn.cpp 3// Purpose: 4// Author: Robert Roebling 5// Id: $Id: bmpbuttn.cpp 52007 2008-02-22 19:57:54Z VS $ 6// Copyright: (c) 1998 Robert Roebling 7// Licence: wxWindows licence 8///////////////////////////////////////////////////////////////////////////// 9 10// For compilers that support precompilation, includes "wx.h". 11#include "wx/wxprec.h" 12 13#if wxUSE_BMPBUTTON 14 15#include "wx/bmpbuttn.h" 16 17#include "wx/gtk/private.h" 18 19//----------------------------------------------------------------------------- 20// classes 21//----------------------------------------------------------------------------- 22 23class wxBitmapButton; 24 25//----------------------------------------------------------------------------- 26// data 27//----------------------------------------------------------------------------- 28 29extern bool g_blockEventsOnDrag; 30 31//----------------------------------------------------------------------------- 32// "clicked" 33//----------------------------------------------------------------------------- 34 35extern "C" { 36static void gtk_bmpbutton_clicked_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button ) 37{ 38 if (g_isIdle) 39 wxapp_install_idle_handler(); 40 41 if (!button->m_hasVMT) return; 42 if (g_blockEventsOnDrag) return; 43 44 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, button->GetId()); 45 event.SetEventObject(button); 46 button->GetEventHandler()->ProcessEvent(event); 47} 48} 49 50//----------------------------------------------------------------------------- 51// "enter" 52//----------------------------------------------------------------------------- 53 54extern "C" { 55static void gtk_bmpbutton_enter_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button ) 56{ 57 if (!button->m_hasVMT) return; 58 if (g_blockEventsOnDrag) return; 59 60 button->HasFocus(); 61} 62} 63 64//----------------------------------------------------------------------------- 65// "leave" 66//----------------------------------------------------------------------------- 67 68extern "C" { 69static void gtk_bmpbutton_leave_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button ) 70{ 71 if (!button->m_hasVMT) return; 72 if (g_blockEventsOnDrag) return; 73 74 button->NotFocus(); 75} 76} 77 78//----------------------------------------------------------------------------- 79// "pressed" 80//----------------------------------------------------------------------------- 81 82extern "C" { 83static void gtk_bmpbutton_press_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button ) 84{ 85 if (!button->m_hasVMT) return; 86 if (g_blockEventsOnDrag) return; 87 88 button->StartSelect(); 89} 90} 91 92//----------------------------------------------------------------------------- 93// "released" 94//----------------------------------------------------------------------------- 95 96extern "C" { 97static void gtk_bmpbutton_release_callback( GtkWidget *WXUNUSED(widget), wxBitmapButton *button ) 98{ 99 if (!button->m_hasVMT) return; 100 if (g_blockEventsOnDrag) return; 101 102 button->EndSelect(); 103} 104} 105 106//----------------------------------------------------------------------------- 107// wxBitmapButton 108//----------------------------------------------------------------------------- 109 110IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton,wxButton) 111 112void wxBitmapButton::Init() 113{ 114 m_hasFocus = 115 m_isSelected = false; 116} 117 118bool wxBitmapButton::Create( wxWindow *parent, 119 wxWindowID id, 120 const wxBitmap& bitmap, 121 const wxPoint& pos, 122 const wxSize& size, 123 long style, 124 const wxValidator& validator, 125 const wxString &name ) 126{ 127 m_needParent = true; 128 m_acceptsFocus = true; 129 130 if (!PreCreation( parent, pos, size ) || 131 !CreateBase( parent, id, pos, size, style, validator, name )) 132 { 133 wxFAIL_MSG( wxT("wxBitmapButton creation failed") ); 134 return false; 135 } 136 137 m_bmpNormal = bitmap; 138 139 m_widget = gtk_button_new(); 140 141 if (style & wxNO_BORDER) 142 gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE ); 143 144 if (m_bmpNormal.Ok()) 145 { 146 OnSetBitmap(); 147 } 148 149 g_signal_connect_after (m_widget, "clicked", 150 G_CALLBACK (gtk_bmpbutton_clicked_callback), 151 this); 152 153 g_signal_connect (m_widget, "enter", 154 G_CALLBACK (gtk_bmpbutton_enter_callback), this); 155 g_signal_connect (m_widget, "leave", 156 G_CALLBACK (gtk_bmpbutton_leave_callback), this); 157 g_signal_connect (m_widget, "pressed", 158 G_CALLBACK (gtk_bmpbutton_press_callback), this); 159 g_signal_connect (m_widget, "released", 160 G_CALLBACK (gtk_bmpbutton_release_callback), this); 161 162 m_parent->DoAddChild( this ); 163 164 PostCreation(size); 165 166 Connect(wxEVT_SET_FOCUS, 167 wxFocusEventHandler(wxBitmapButton::OnFocusChange), 168 NULL, this); 169 Connect(wxEVT_KILL_FOCUS, 170 wxFocusEventHandler(wxBitmapButton::OnFocusChange), 171 NULL, this); 172 173 return true; 174} 175 176void wxBitmapButton::SetDefault() 177{ 178 GTK_WIDGET_SET_FLAGS( m_widget, GTK_CAN_DEFAULT ); 179 gtk_widget_grab_default( m_widget ); 180 181 SetSize( m_x, m_y, m_width, m_height ); 182} 183 184void wxBitmapButton::SetLabel( const wxString &label ) 185{ 186 wxCHECK_RET( m_widget != NULL, wxT("invalid button") ); 187 188 wxControl::SetLabel( label ); 189} 190 191void wxBitmapButton::DoApplyWidgetStyle(GtkRcStyle *style) 192{ 193 if (!GTK_BIN(m_widget)->child) 194 return; 195 196 wxButton::DoApplyWidgetStyle(style); 197} 198 199void wxBitmapButton::OnSetBitmap() 200{ 201 wxCHECK_RET( m_widget != NULL, wxT("invalid bitmap button") ); 202 203 InvalidateBestSize(); 204 205 wxBitmap the_one; 206 if (!m_isEnabled) 207 the_one = m_bmpDisabled; 208 else if (m_isSelected) 209 the_one = m_bmpSelected; 210 else if (m_hasFocus) 211 { 212 // NB: this is misnomer, m_hasFocus doesn't mean "has focus", but 213 // "mouse is over the window" 214 the_one = m_bmpHover; 215 } 216 else if (FindFocus() == this) 217 the_one = m_bmpFocus; 218 else 219 the_one = m_bmpNormal; 220 221 if (!the_one.Ok()) the_one = m_bmpNormal; 222 if (!the_one.Ok()) return; 223 224 GtkWidget *child = GTK_BIN(m_widget)->child; 225 if (child == NULL) 226 { 227 // initial bitmap 228 GtkWidget *pixmap = 229 gtk_image_new_from_pixbuf(the_one.GetPixbuf()); 230 231 gtk_widget_show(pixmap); 232 gtk_container_add(GTK_CONTAINER(m_widget), pixmap); 233 } 234 else 235 { // subsequent bitmaps 236 GtkImage *pixmap = GTK_IMAGE(child); 237 gtk_image_set_from_pixbuf(pixmap, the_one.GetPixbuf()); 238 } 239} 240 241wxSize wxBitmapButton::DoGetBestSize() const 242{ 243 return wxControl::DoGetBestSize(); 244} 245 246bool wxBitmapButton::Enable( bool enable ) 247{ 248 if ( !wxWindow::Enable(enable) ) 249 return false; 250 251 OnSetBitmap(); 252 253 return true; 254} 255 256void wxBitmapButton::HasFocus() 257{ 258 m_hasFocus = true; 259 OnSetBitmap(); 260} 261 262void wxBitmapButton::NotFocus() 263{ 264 m_hasFocus = false; 265 OnSetBitmap(); 266} 267 268void wxBitmapButton::StartSelect() 269{ 270 m_isSelected = true; 271 OnSetBitmap(); 272} 273 274void wxBitmapButton::EndSelect() 275{ 276 m_isSelected = false; 277 OnSetBitmap(); 278} 279 280void wxBitmapButton::OnFocusChange(wxFocusEvent& event) 281{ 282 event.Skip(); 283 OnSetBitmap(); 284} 285 286#endif // wxUSE_BMPBUTTON 287