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