]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/spinbutt.cpp
Fix accelerstors with down and left
[wxWidgets.git] / src / gtk / spinbutt.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: spinbutt.cpp
3// Purpose: wxSpinButton
4// Author: Robert
5// Modified by:
6// RCS-ID: $Id$
7// Copyright: (c) Robert Roebling
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#include "wx/spinbutt.h"
15
16#if wxUSE_SPINBTN
17
18#include "wx/utils.h"
19#include "wx/math.h"
20#include "wx/gtk/private.h"
21
22//-----------------------------------------------------------------------------
23// data
24//-----------------------------------------------------------------------------
25
26extern bool g_blockEventsOnDrag;
27
28static const float sensitivity = 0.02;
29
30//-----------------------------------------------------------------------------
31// "value_changed"
32//-----------------------------------------------------------------------------
33
34extern "C" {
35static void gtk_spinbutt_callback( GtkWidget *WXUNUSED(widget), wxSpinButton *win )
36{
37 if (g_isIdle) wxapp_install_idle_handler();
38
39 if (!win->m_hasVMT) return;
40 if (g_blockEventsOnDrag) return;
41
42 float diff = win->m_adjust->value - win->m_oldPos;
43 if (fabs(diff) < sensitivity) return;
44
45 wxEventType command = wxEVT_NULL;
46
47 float line_step = win->m_adjust->step_increment;
48
49 if (fabs(diff-line_step) < sensitivity) command = wxEVT_SCROLL_LINEUP;
50 else if (fabs(diff+line_step) < sensitivity) command = wxEVT_SCROLL_LINEDOWN;
51 else command = wxEVT_SCROLL_THUMBTRACK;
52
53 int value = (int)ceil(win->m_adjust->value);
54
55 wxSpinEvent event( command, win->GetId());
56 event.SetPosition( value );
57 event.SetEventObject( win );
58
59 if ((win->GetEventHandler()->ProcessEvent( event )) &&
60 !event.IsAllowed() )
61 {
62 /* program has vetoed */
63 win->m_adjust->value = win->m_oldPos;
64
65 g_signal_handlers_disconnect_by_func (win->m_adjust,
66 (gpointer) gtk_spinbutt_callback,
67 win);
68
69 g_signal_emit_by_name (win->m_adjust, "value_changed");
70
71 g_signal_connect (win->m_adjust, "value_changed",
72 G_CALLBACK (gtk_spinbutt_callback), win);
73 return;
74 }
75
76 win->m_oldPos = win->m_adjust->value;
77
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 }
87}
88}
89
90//-----------------------------------------------------------------------------
91// wxSpinButton
92//-----------------------------------------------------------------------------
93
94IMPLEMENT_DYNAMIC_CLASS(wxSpinButton,wxControl)
95IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent, wxNotifyEvent)
96
97BEGIN_EVENT_TABLE(wxSpinButton, wxControl)
98 EVT_SIZE(wxSpinButton::OnSize)
99END_EVENT_TABLE()
100
101bool wxSpinButton::Create(wxWindow *parent,
102 wxWindowID id,
103 const wxPoint& pos,
104 const wxSize& size,
105 long style,
106 const wxString& name)
107{
108 m_needParent = TRUE;
109
110 wxSize new_size = size,
111 sizeBest = DoGetBestSize();
112 new_size.x = sizeBest.x; // override width always
113 if (new_size.y == -1)
114 new_size.y = sizeBest.y;
115
116 if (!PreCreation( parent, pos, new_size ) ||
117 !CreateBase( parent, id, pos, new_size, style, wxDefaultValidator, name ))
118 {
119 wxFAIL_MSG( wxT("wxXX creation failed") );
120 return FALSE;
121 }
122
123 m_oldPos = 0.0;
124
125 m_adjust = (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 100.0, 1.0, 5.0, 0.0);
126
127 m_widget = gtk_spin_button_new( m_adjust, 0, 0 );
128
129 gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(m_widget),
130 (int)(m_windowStyle & wxSP_WRAP) );
131
132 g_signal_connect (m_adjust, "value_changed",
133 G_CALLBACK (gtk_spinbutt_callback), this);
134
135 m_parent->DoAddChild( this );
136
137 PostCreation(new_size);
138
139 return TRUE;
140}
141
142int wxSpinButton::GetMin() const
143{
144 wxCHECK_MSG( (m_widget != NULL), 0, wxT("invalid spin button") );
145
146 return (int)ceil(m_adjust->lower);
147}
148
149int wxSpinButton::GetMax() const
150{
151 wxCHECK_MSG( (m_widget != NULL), 0, wxT("invalid spin button") );
152
153 return (int)ceil(m_adjust->upper);
154}
155
156int wxSpinButton::GetValue() const
157{
158 wxCHECK_MSG( (m_widget != NULL), 0, wxT("invalid spin button") );
159
160 return (int)ceil(m_adjust->value);
161}
162
163void wxSpinButton::SetValue( int value )
164{
165 wxCHECK_RET( (m_widget != NULL), wxT("invalid spin button") );
166
167 float fpos = (float)value;
168 m_oldPos = fpos;
169 if (fabs(fpos-m_adjust->value) < sensitivity) return;
170
171 m_adjust->value = fpos;
172
173 g_signal_emit_by_name (m_adjust, "value_changed");
174}
175
176void wxSpinButton::SetRange(int minVal, int maxVal)
177{
178 wxCHECK_RET( (m_widget != NULL), wxT("invalid spin button") );
179
180 float fmin = (float)minVal;
181 float fmax = (float)maxVal;
182
183 if ((fabs(fmin-m_adjust->lower) < sensitivity) &&
184 (fabs(fmax-m_adjust->upper) < sensitivity))
185 {
186 return;
187 }
188
189 m_adjust->lower = fmin;
190 m_adjust->upper = fmax;
191
192 g_signal_emit_by_name (m_adjust, "changed");
193
194 // these two calls are required due to some bug in GTK
195 Refresh();
196 SetFocus();
197}
198
199void wxSpinButton::OnSize( wxSizeEvent &WXUNUSED(event) )
200{
201 wxCHECK_RET( (m_widget != NULL), wxT("invalid spin button") );
202
203 m_width = DoGetBestSize().x;
204 gtk_widget_set_size_request( m_widget, m_width, m_height );
205}
206
207bool wxSpinButton::IsOwnGtkWindow( GdkWindow *window )
208{
209 return GTK_SPIN_BUTTON(m_widget)->panel == window;
210}
211
212wxSize wxSpinButton::DoGetBestSize() const
213{
214 wxSize best(15, 26); // FIXME
215 CacheBestSize(best);
216 return best;
217}
218
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
228#endif