]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/spinbutt.cpp
fixed yet another memory leak in LoadGnomeDataFromKeyFile() (coverity checker CID 51)
[wxWidgets.git] / src / gtk / spinbutt.cpp
CommitLineData
8e189077
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: spinbutt.cpp
3// Purpose: wxSpinButton
4// Author: Robert
5// Modified by:
6// RCS-ID: $Id$
7// Copyright: (c) Robert Roebling
65571936 8// Licence: wxWindows licence
8e189077
RR
9/////////////////////////////////////////////////////////////////////////////
10
14f355c2
VS
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
8e189077 14#include "wx/spinbutt.h"
dcf924a3 15
2fa7c206 16#if wxUSE_SPINBTN
dcf924a3 17
8e189077 18#include "wx/utils.h"
463c4d71 19#include "wx/math.h"
9e691f46 20#include "wx/gtk/private.h"
83624f79 21
acfd422a
RR
22//-----------------------------------------------------------------------------
23// idle system
24//-----------------------------------------------------------------------------
25
26extern void wxapp_install_idle_handler();
27extern bool g_isIdle;
28
8e189077
RR
29//-----------------------------------------------------------------------------
30// data
31//-----------------------------------------------------------------------------
32
33extern bool g_blockEventsOnDrag;
34
738f9e5a 35static const float sensitivity = 0.02;
6380910c 36
8e189077
RR
37//-----------------------------------------------------------------------------
38// "value_changed"
39//-----------------------------------------------------------------------------
40
865bb325 41extern "C" {
8e189077 42static void gtk_spinbutt_callback( GtkWidget *WXUNUSED(widget), wxSpinButton *win )
6380910c 43{
acfd422a
RR
44 if (g_isIdle) wxapp_install_idle_handler();
45
a2053b27 46 if (!win->m_hasVMT) return;
83624f79 47 if (g_blockEventsOnDrag) return;
828f655f 48
83624f79 49 float diff = win->m_adjust->value - win->m_oldPos;
6380910c 50 if (fabs(diff) < sensitivity) return;
6380910c 51
83624f79 52 wxEventType command = wxEVT_NULL;
6380910c 53
83624f79 54 float line_step = win->m_adjust->step_increment;
6380910c 55
0f42a871
RR
56 if (fabs(diff-line_step) < sensitivity) command = wxEVT_SCROLL_LINEUP;
57 else if (fabs(diff+line_step) < sensitivity) command = wxEVT_SCROLL_LINEDOWN;
83624f79 58 else command = wxEVT_SCROLL_THUMBTRACK;
8e189077 59
66d78146 60 int value = (int)ceil(win->m_adjust->value);
6380910c 61
83624f79
RR
62 wxSpinEvent event( command, win->GetId());
63 event.SetPosition( value );
83624f79 64 event.SetEventObject( win );
0f42a871
RR
65
66 if ((win->GetEventHandler()->ProcessEvent( event )) &&
67 !event.IsAllowed() )
68 {
69 /* program has vetoed */
70 win->m_adjust->value = win->m_oldPos;
88d19775 71
9fa72bd2
MR
72 g_signal_handlers_disconnect_by_func (win->m_adjust,
73 (gpointer) gtk_spinbutt_callback,
74 win);
88d19775 75
9fa72bd2 76 g_signal_emit_by_name (win->m_adjust, "value_changed");
0f42a871 77
9fa72bd2
MR
78 g_signal_connect (win->m_adjust, "value_changed",
79 G_CALLBACK (gtk_spinbutt_callback), win);
0f42a871
RR
80 return;
81 }
88d19775 82
0f42a871 83 win->m_oldPos = win->m_adjust->value;
88d19775 84
e65cc56a
RR
85 /* always send a thumbtrack event */
86 if (command != wxEVT_SCROLL_THUMBTRACK)
87 {
88 command = wxEVT_SCROLL_THUMBTRACK;
89 wxSpinEvent event2( command, win->GetId());
90 event2.SetPosition( value );
91 event2.SetEventObject( win );
92 win->GetEventHandler()->ProcessEvent( event2 );
93 }
8e189077 94}
865bb325 95}
8e189077
RR
96
97//-----------------------------------------------------------------------------
98// wxSpinButton
99//-----------------------------------------------------------------------------
100
101IMPLEMENT_DYNAMIC_CLASS(wxSpinButton,wxControl)
2fa7c206 102IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent, wxNotifyEvent)
8e189077
RR
103
104BEGIN_EVENT_TABLE(wxSpinButton, wxControl)
105 EVT_SIZE(wxSpinButton::OnSize)
106END_EVENT_TABLE()
107
31528cd3
VZ
108bool wxSpinButton::Create(wxWindow *parent,
109 wxWindowID id,
110 const wxPoint& pos,
111 const wxSize& size,
112 long style,
113 const wxString& name)
8e189077 114{
83624f79 115 m_needParent = TRUE;
6380910c 116
9d9b7755
VZ
117 wxSize new_size = size,
118 sizeBest = DoGetBestSize();
119 new_size.x = sizeBest.x; // override width always
6380910c 120 if (new_size.y == -1)
9d9b7755 121 new_size.y = sizeBest.y;
6380910c 122
2259e007 123 if (!PreCreation( parent, pos, new_size ) ||
4dcaf11a
RR
124 !CreateBase( parent, id, pos, new_size, style, wxDefaultValidator, name ))
125 {
223d09f6 126 wxFAIL_MSG( wxT("wxXX creation failed") );
88d19775 127 return FALSE;
4dcaf11a 128 }
8e189077 129
83624f79 130 m_oldPos = 0.0;
8e189077 131
83624f79 132 m_adjust = (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 100.0, 1.0, 5.0, 0.0);
6380910c 133
83624f79 134 m_widget = gtk_spin_button_new( m_adjust, 0, 0 );
6380910c 135
b02da6b1
VZ
136 gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(m_widget),
137 (int)(m_windowStyle & wxSP_WRAP) );
6380910c 138
9fa72bd2
MR
139 g_signal_connect (m_adjust, "value_changed",
140 G_CALLBACK (gtk_spinbutt_callback), this);
6380910c 141
f03fc89f 142 m_parent->DoAddChild( this );
6380910c 143
abdeb9e7 144 PostCreation(new_size);
6380910c 145
83624f79 146 return TRUE;
8e189077
RR
147}
148
8e189077
RR
149int wxSpinButton::GetMin() const
150{
223d09f6 151 wxCHECK_MSG( (m_widget != NULL), 0, wxT("invalid spin button") );
6380910c 152
66d78146 153 return (int)ceil(m_adjust->lower);
8e189077
RR
154}
155
156int wxSpinButton::GetMax() const
157{
223d09f6 158 wxCHECK_MSG( (m_widget != NULL), 0, wxT("invalid spin button") );
6380910c 159
66d78146 160 return (int)ceil(m_adjust->upper);
8e189077
RR
161}
162
163int wxSpinButton::GetValue() const
164{
223d09f6 165 wxCHECK_MSG( (m_widget != NULL), 0, wxT("invalid spin button") );
6380910c 166
66d78146 167 return (int)ceil(m_adjust->value);
8e189077
RR
168}
169
170void wxSpinButton::SetValue( int value )
171{
223d09f6 172 wxCHECK_RET( (m_widget != NULL), wxT("invalid spin button") );
6380910c 173
83624f79
RR
174 float fpos = (float)value;
175 m_oldPos = fpos;
6380910c
VZ
176 if (fabs(fpos-m_adjust->value) < sensitivity) return;
177
83624f79 178 m_adjust->value = fpos;
6380910c 179
9fa72bd2 180 g_signal_emit_by_name (m_adjust, "value_changed");
8e189077
RR
181}
182
183void wxSpinButton::SetRange(int minVal, int maxVal)
184{
223d09f6 185 wxCHECK_RET( (m_widget != NULL), wxT("invalid spin button") );
6380910c 186
83624f79
RR
187 float fmin = (float)minVal;
188 float fmax = (float)maxVal;
6380910c
VZ
189
190 if ((fabs(fmin-m_adjust->lower) < sensitivity) &&
191 (fabs(fmax-m_adjust->upper) < sensitivity))
83624f79
RR
192 {
193 return;
194 }
6380910c 195
83624f79
RR
196 m_adjust->lower = fmin;
197 m_adjust->upper = fmax;
8e189077 198
9fa72bd2 199 g_signal_emit_by_name (m_adjust, "changed");
88d19775 200
65045edd
RR
201 // these two calls are required due to some bug in GTK
202 Refresh();
203 SetFocus();
8e189077
RR
204}
205
206void wxSpinButton::OnSize( wxSizeEvent &WXUNUSED(event) )
207{
223d09f6 208 wxCHECK_RET( (m_widget != NULL), wxT("invalid spin button") );
6380910c 209
9d9b7755 210 m_width = DoGetBestSize().x;
370dc79c 211 gtk_widget_set_size_request( m_widget, m_width, m_height );
8e189077
RR
212}
213
214bool wxSpinButton::IsOwnGtkWindow( GdkWindow *window )
215{
83624f79 216 return GTK_SPIN_BUTTON(m_widget)->panel == window;
8e189077
RR
217}
218
9d9b7755
VZ
219wxSize wxSpinButton::DoGetBestSize() const
220{
9f884528
RD
221 wxSize best(15, 26); // FIXME
222 CacheBestSize(best);
223 return best;
9d9b7755
VZ
224}
225
9d522606
RD
226// static
227wxVisualAttributes
228wxSpinButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
229{
230 // TODO: overload to accept functions like gtk_spin_button_new?
231 // Until then use a similar type
232 return GetDefaultAttributesFromGTKWidget(gtk_button_new);
233}
234
31528cd3 235#endif