]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/button.cpp
ignore requests to install idle handler when app instance is not valid
[wxWidgets.git] / src / gtk1 / button.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
93763ad5 2// Name: src/gtk1/button.cpp
c801d85f
KB
3// Purpose:
4// Author: Robert Roebling
dbf858b5 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling
65571936 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
14f355c2
VS
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
1e6feb95
VZ
13#if wxUSE_BUTTON
14
c801d85f 15#include "wx/button.h"
2cdcee61
WS
16
17#ifndef WX_PRECOMP
18 #include "wx/toplevel.h"
19#endif
20
5f7bcb48 21#include "wx/stockitem.h"
c801d85f 22
3cbab641
MR
23#include "wx/gtk1/private.h"
24#include "wx/gtk1/win_gtk.h"
83624f79 25
c801d85f
KB
26//-----------------------------------------------------------------------------
27// classes
28//-----------------------------------------------------------------------------
29
30class wxButton;
31
acfd422a
RR
32//-----------------------------------------------------------------------------
33// idle system
34//-----------------------------------------------------------------------------
35
36extern void wxapp_install_idle_handler();
37extern bool g_isIdle;
38
66bd6b93
RR
39//-----------------------------------------------------------------------------
40// data
41//-----------------------------------------------------------------------------
42
43extern bool g_blockEventsOnDrag;
44
c801d85f 45//-----------------------------------------------------------------------------
e1e955e1 46// "clicked"
c801d85f
KB
47//-----------------------------------------------------------------------------
48
865bb325 49extern "C" {
66bd6b93 50static void gtk_button_clicked_callback( GtkWidget *WXUNUSED(widget), wxButton *button )
c801d85f 51{
9e691f46 52 if (g_isIdle)
32ac755d 53 wxapp_install_idle_handler();
acfd422a 54
a2053b27 55 if (!button->m_hasVMT) return;
acfd422a 56 if (g_blockEventsOnDrag) return;
9e691f46 57
acfd422a
RR
58 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, button->GetId());
59 event.SetEventObject(button);
60 button->GetEventHandler()->ProcessEvent(event);
6de97a3b 61}
865bb325 62}
c801d85f 63
a90c0600
RR
64//-----------------------------------------------------------------------------
65// "style_set" from m_widget
66//-----------------------------------------------------------------------------
67
68static gint
69gtk_button_style_set_callback( GtkWidget *m_widget, GtkStyle *WXUNUSED(style), wxButton *win )
70{
71 if (g_isIdle)
72 wxapp_install_idle_handler();
b2ff89d6 73
f893066b
RR
74 int left_border = 0;
75 int right_border = 0;
76 int top_border = 0;
77 int bottom_border = 0;
b2ff89d6 78
f893066b
RR
79 /* the default button has a border around it */
80 if (GTK_WIDGET_CAN_DEFAULT(m_widget))
81 {
f893066b
RR
82 left_border = 6;
83 right_border = 6;
84 top_border = 6;
85 bottom_border = 5;
f893066b
RR
86 win->DoMoveWindow( win->m_x-top_border,
87 win->m_y-left_border,
88 win->m_width+left_border+right_border,
89 win->m_height+top_border+bottom_border );
b2ff89d6 90 }
a90c0600
RR
91
92 return FALSE;
93}
94
c801d85f 95//-----------------------------------------------------------------------------
e1e955e1
RR
96// wxButton
97//-----------------------------------------------------------------------------
98
99IMPLEMENT_DYNAMIC_CLASS(wxButton,wxControl)
c801d85f 100
fd0eed64 101wxButton::wxButton()
c801d85f 102{
6de97a3b 103}
c801d85f 104
fd0eed64
RR
105wxButton::~wxButton()
106{
fd0eed64
RR
107}
108
c801d85f 109bool wxButton::Create( wxWindow *parent, wxWindowID id, const wxString &label,
32c77a71 110 const wxPoint &pos, const wxSize &size,
6de97a3b 111 long style, const wxValidator& validator, const wxString &name )
c801d85f 112{
93763ad5
WS
113 m_needParent = true;
114 m_acceptsFocus = true;
32c77a71 115
4dcaf11a
RR
116 if (!PreCreation( parent, pos, size ) ||
117 !CreateBase( parent, id, pos, size, style, validator, name ))
118 {
223d09f6 119 wxFAIL_MSG( wxT("wxButton creation failed") );
93763ad5 120 return false;
4dcaf11a 121 }
c801d85f 122
354aa1e3
RR
123 m_widget = gtk_button_new_with_label("");
124
2e8613b7
RR
125 float x_alignment = 0.5;
126 if (HasFlag(wxBU_LEFT))
127 x_alignment = 0.0;
128 else if (HasFlag(wxBU_RIGHT))
129 x_alignment = 1.0;
130
131 float y_alignment = 0.5;
132 if (HasFlag(wxBU_TOP))
133 y_alignment = 0.0;
134 else if (HasFlag(wxBU_BOTTOM))
135 y_alignment = 1.0;
136
3cbab641
MR
137 if (GTK_IS_MISC(BUTTON_CHILD(m_widget)))
138 gtk_misc_set_alignment (GTK_MISC (BUTTON_CHILD (m_widget)),
77f70672 139 x_alignment, y_alignment);
a696db45 140
5f7bcb48 141 SetLabel(label);
354aa1e3 142
de1c750f
RR
143 if (style & wxNO_BORDER)
144 gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
de1c750f 145
58b907f6 146 gtk_signal_connect_after( GTK_OBJECT(m_widget), "clicked",
b292e2f5 147 GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this );
c801d85f 148
a90c0600
RR
149 gtk_signal_connect_after( GTK_OBJECT(m_widget), "style_set",
150 GTK_SIGNAL_FUNC(gtk_button_style_set_callback), (gpointer*) this );
b2ff89d6 151
f03fc89f 152 m_parent->DoAddChild( this );
9e691f46 153
abdeb9e7 154 PostCreation(size);
db434467 155
4fa87bd9
VS
156 return true;
157}
b2ff89d6 158
32c77a71 159
da048e3d 160void wxButton::SetDefault()
c801d85f 161{
6c20e8f8
VZ
162 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
163 wxCHECK_RET( tlw, _T("button without top level window?") );
97149f18 164
6c20e8f8 165 tlw->SetDefaultItem(this);
b2ff89d6 166
3502e687
RR
167 GTK_WIDGET_SET_FLAGS( m_widget, GTK_CAN_DEFAULT );
168 gtk_widget_grab_default( m_widget );
b2ff89d6 169
f893066b
RR
170 // resize for default border
171 gtk_button_style_set_callback( m_widget, NULL, this );
6de97a3b 172}
c801d85f 173
ebea0891 174/* static */
4fa87bd9 175wxSize wxButtonBase::GetDefaultSize()
8dbf4589
RR
176{
177 return wxSize(80,26);
178}
179
5f7bcb48 180void wxButton::SetLabel( const wxString &lbl )
c801d85f 181{
223d09f6 182 wxCHECK_RET( m_widget != NULL, wxT("invalid button") );
9e691f46 183
5f7bcb48
VS
184 wxString label(lbl);
185
5f7bcb48
VS
186 if (label.empty() && wxIsStockID(m_windowId))
187 label = wxGetStockLabel(m_windowId);
5f7bcb48
VS
188
189 wxControl::SetLabel(label);
9e691f46 190
ee6dd41a 191 const wxString labelGTK = GTKRemoveMnemonics(label);
b2ff89d6 192
b2ff89d6 193 gtk_label_set(GTK_LABEL(BUTTON_CHILD(m_widget)), wxGTK_CONV(labelGTK));
6de97a3b 194}
c801d85f 195
f03fc89f 196bool wxButton::Enable( bool enable )
a9c96bcc 197{
f03fc89f 198 if ( !wxControl::Enable( enable ) )
93763ad5 199 return false;
9e691f46
VZ
200
201 gtk_widget_set_sensitive( BUTTON_CHILD(m_widget), enable );
f03fc89f 202
93763ad5 203 return true;
a9c96bcc
RR
204}
205
2b5f62a0
VZ
206bool wxButton::IsOwnGtkWindow( GdkWindow *window )
207{
2b5f62a0 208 return (window == m_widget->window);
2b5f62a0
VZ
209}
210
f40fdaa3 211void wxButton::DoApplyWidgetStyle(GtkRcStyle *style)
868a2826 212{
f40fdaa3
VS
213 gtk_widget_modify_style(m_widget, style);
214 gtk_widget_modify_style(BUTTON_CHILD(m_widget), style);
a81258be 215}
db434467
RR
216
217wxSize wxButton::DoGetBestSize() const
218{
4f819fe4
VZ
219 // the default button in wxGTK is bigger than the other ones because of an
220 // extra border around it, but we don't want to take it into account in
221 // our size calculations (otherwsie the result is visually ugly), so
222 // always return the size of non default button from here
223 const bool isDefault = GTK_WIDGET_HAS_DEFAULT(m_widget);
224 if ( isDefault )
225 {
226 // temporarily unset default flag
227 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_DEFAULT );
228 }
229
db434467 230 wxSize ret( wxControl::DoGetBestSize() );
9e691f46 231
4f819fe4
VZ
232 if ( isDefault )
233 {
234 // set it back again
235 GTK_WIDGET_SET_FLAGS( m_widget, GTK_CAN_DEFAULT );
236 }
237
391ddf40 238 ret.x += 10; // add a few pixels for sloppy (but common) themes
b2ff89d6 239
8ab696e0
RR
240 if (!HasFlag(wxBU_EXACTFIT))
241 {
4fa87bd9
VS
242 wxSize defaultSize = GetDefaultSize();
243 if (ret.x < defaultSize.x) ret.x = defaultSize.x;
244 if (ret.y < defaultSize.y) ret.y = defaultSize.y;
8ab696e0 245 }
9e691f46 246
9f884528 247 CacheBestSize(ret);
db434467
RR
248 return ret;
249}
250
9d522606
RD
251// static
252wxVisualAttributes
253wxButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
254{
255 return GetDefaultAttributesFromGTKWidget(gtk_button_new);
256}
257
1e6feb95 258#endif // wxUSE_BUTTON