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