]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/tglbtn.cpp
reset g_delayedFocus when the window is deleted to avoid crashes when using it
[wxWidgets.git] / src / gtk1 / tglbtn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/gtk/tglbtn.cpp
3 // Purpose: Definition of the wxToggleButton class, which implements a
4 // toggle button under wxGTK.
5 // Author: John Norris, minor changes by Axel Schlueter
6 // Modified by:
7 // Created: 08.02.01
8 // RCS-ID: $Id$
9 // Copyright: (c) 2000 Johnny C. Norris II
10 // License: Rocketeer license
11 /////////////////////////////////////////////////////////////////////////////
12
13 #include "wx/tglbtn.h"
14 #include "wx/button.h"
15
16 #if wxUSE_TOGGLEBTN
17
18 #include "wx/gtk/private.h"
19
20 extern void wxapp_install_idle_handler();
21 extern bool g_isIdle;
22 extern bool g_blockEventsOnDrag;
23 extern wxCursor g_globalCursor;
24 extern wxWindowGTK *g_delayedFocus;
25
26 static void gtk_togglebutton_clicked_callback(GtkWidget *WXUNUSED(widget), wxToggleButton *cb)
27 {
28 if (g_isIdle)
29 wxapp_install_idle_handler();
30
31 if (!cb->m_hasVMT || g_blockEventsOnDrag)
32 return;
33
34 if (cb->m_blockEvent) return;
35
36 // Generate a wx event.
37 wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, cb->GetId());
38 event.SetInt(cb->GetValue());
39 event.SetEventObject(cb);
40 cb->GetEventHandler()->ProcessEvent(event);
41 }
42
43 IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
44 DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED)
45
46 bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
47 const wxString &label, const wxPoint &pos,
48 const wxSize &size, long style,
49 const wxValidator& validator,
50 const wxString &name)
51 {
52 m_needParent = TRUE;
53 m_acceptsFocus = TRUE;
54
55 m_blockEvent = FALSE;
56
57 if (!PreCreation(parent, pos, size) ||
58 !CreateBase(parent, id, pos, size, style, validator, name )) {
59 wxFAIL_MSG(wxT("wxToggleButton creation failed"));
60 return FALSE;
61 }
62
63 wxControl::SetLabel(label);
64
65 // Create the gtk widget.
66 m_widget = gtk_toggle_button_new_with_label(m_label.mbc_str());
67
68 gtk_signal_connect(GTK_OBJECT(m_widget), "clicked",
69 GTK_SIGNAL_FUNC(gtk_togglebutton_clicked_callback),
70 (gpointer *)this);
71
72 m_parent->DoAddChild(this);
73
74 PostCreation();
75
76 SetFont(parent->GetFont());
77
78 wxSize size_best(DoGetBestSize());
79 wxSize new_size(size);
80 if (new_size.x == -1)
81 new_size.x = size_best.x;
82 if (new_size.y == -1)
83 new_size.y = size_best.y;
84 if ((new_size.x != size.x) || (new_size.y != size.y))
85 SetSize(new_size.x, new_size.y);
86
87 SetBackgroundColour(parent->GetBackgroundColour());
88 SetForegroundColour(parent->GetForegroundColour());
89
90 Show(TRUE);
91
92 return TRUE;
93 }
94
95 // void SetValue(bool state)
96 // Set the value of the toggle button.
97 void wxToggleButton::SetValue(bool state)
98 {
99 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
100
101 if (state == GetValue())
102 return;
103
104 m_blockEvent = TRUE;
105
106 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), state);
107
108 m_blockEvent = FALSE;
109 }
110
111 // bool GetValue() const
112 // Get the value of the toggle button.
113 bool wxToggleButton::GetValue() const
114 {
115 wxCHECK_MSG(m_widget != NULL, FALSE, wxT("invalid toggle button"));
116
117 return GTK_TOGGLE_BUTTON(m_widget)->active;
118 }
119
120 void wxToggleButton::SetLabel(const wxString& label)
121 {
122 wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
123
124 wxControl::SetLabel(label);
125
126 gtk_label_set(GTK_LABEL(BUTTON_CHILD(m_widget)), GetLabel().mbc_str());
127 }
128
129 bool wxToggleButton::Enable(bool enable /*=TRUE*/)
130 {
131 if (!wxControl::Enable(enable))
132 return FALSE;
133
134 gtk_widget_set_sensitive(BUTTON_CHILD(m_widget), enable);
135
136 return TRUE;
137 }
138
139 void wxToggleButton::ApplyWidgetStyle()
140 {
141 SetWidgetStyle();
142 gtk_widget_set_style(m_widget, m_widgetStyle);
143 gtk_widget_set_style(BUTTON_CHILD(m_widget), m_widgetStyle);
144 }
145
146 bool wxToggleButton::IsOwnGtkWindow(GdkWindow *window)
147 {
148 return window == TOGGLE_BUTTON_EVENT_WIN(m_widget);
149 }
150
151 void wxToggleButton::OnInternalIdle()
152 {
153 wxCursor cursor = m_cursor;
154
155 if (g_globalCursor.Ok())
156 cursor = g_globalCursor;
157
158 GdkWindow *win = TOGGLE_BUTTON_EVENT_WIN(m_widget);
159 if ( win && cursor.Ok() )
160 {
161 /* I now set the cursor the anew in every OnInternalIdle call
162 as setting the cursor in a parent window also effects the
163 windows above so that checking for the current cursor is
164 not possible. */
165
166 gdk_window_set_cursor(win, cursor.GetCursor());
167 }
168
169 UpdateWindowUI();
170 }
171
172 // wxSize DoGetBestSize() const
173 // Get the "best" size for this control.
174 wxSize wxToggleButton::DoGetBestSize() const
175 {
176 wxSize ret(wxControl::DoGetBestSize());
177
178 if (!HasFlag(wxBU_EXACTFIT))
179 {
180 if (ret.x < 80) ret.x = 80;
181 }
182
183
184 return ret;
185 }
186
187 #endif // wxUSE_TOGGLEBTN
188