~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to src/gtk/spinbutt.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/gtk/spinbutt.cpp
 
3
// Purpose:     wxSpinButton
 
4
// Author:      Robert
 
5
// Modified by:
 
6
// RCS-ID:      $Id: spinbutt.cpp 71894 2012-06-30 20:39:06Z PC $
 
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
#if wxUSE_SPINBTN
 
15
 
 
16
#include "wx/spinbutt.h"
 
17
 
 
18
#ifndef WX_PRECOMP
 
19
    #include "wx/utils.h"
 
20
#endif
 
21
 
 
22
#include <gtk/gtk.h>
 
23
 
 
24
//-----------------------------------------------------------------------------
 
25
// data
 
26
//-----------------------------------------------------------------------------
 
27
 
 
28
extern bool   g_blockEventsOnDrag;
 
29
 
 
30
//-----------------------------------------------------------------------------
 
31
// "value_changed"
 
32
//-----------------------------------------------------------------------------
 
33
 
 
34
extern "C" {
 
35
static void
 
36
gtk_value_changed(GtkSpinButton* spinbutton, wxSpinButton* win)
 
37
{
 
38
    const double value = gtk_spin_button_get_value(spinbutton);
 
39
    const int pos = int(value);
 
40
    const int oldPos = win->m_pos;
 
41
    if (!win->m_hasVMT || g_blockEventsOnDrag || pos == oldPos)
 
42
    {
 
43
        win->m_pos = pos;
 
44
        return;
 
45
    }
 
46
 
 
47
    wxSpinEvent event(pos > oldPos ? wxEVT_SCROLL_LINEUP : wxEVT_SCROLL_LINEDOWN, win->GetId());
 
48
    event.SetPosition(pos);
 
49
    event.SetEventObject(win);
 
50
 
 
51
    if ((win->HandleWindowEvent( event )) &&
 
52
        !event.IsAllowed() )
 
53
    {
 
54
        /* program has vetoed */
 
55
        // this will cause another "value_changed" signal,
 
56
        // but because pos == oldPos nothing will happen
 
57
        gtk_spin_button_set_value(spinbutton, oldPos);
 
58
        return;
 
59
    }
 
60
 
 
61
    win->m_pos = pos;
 
62
 
 
63
    /* always send a thumbtrack event */
 
64
    wxSpinEvent event2(wxEVT_SCROLL_THUMBTRACK, win->GetId());
 
65
    event2.SetPosition(pos);
 
66
    event2.SetEventObject(win);
 
67
    win->HandleWindowEvent(event2);
 
68
}
 
69
}
 
70
 
 
71
//-----------------------------------------------------------------------------
 
72
// wxSpinButton
 
73
//-----------------------------------------------------------------------------
 
74
 
 
75
BEGIN_EVENT_TABLE(wxSpinButton, wxControl)
 
76
    EVT_SIZE(wxSpinButton::OnSize)
 
77
END_EVENT_TABLE()
 
78
 
 
79
wxSpinButton::wxSpinButton()
 
80
{
 
81
    m_pos = 0;
 
82
}
 
83
 
 
84
bool wxSpinButton::Create(wxWindow *parent,
 
85
                          wxWindowID id,
 
86
                          const wxPoint& pos,
 
87
                          const wxSize& size,
 
88
                          long style,
 
89
                          const wxString& name)
 
90
{
 
91
    wxSize new_size = size,
 
92
           sizeBest = DoGetBestSize();
 
93
    new_size.x = sizeBest.x;            // override width always
 
94
    if (new_size.y == -1)
 
95
        new_size.y = sizeBest.y;
 
96
 
 
97
    if (!PreCreation( parent, pos, new_size ) ||
 
98
        !CreateBase( parent, id, pos, new_size, style, wxDefaultValidator, name ))
 
99
    {
 
100
        wxFAIL_MSG( wxT("wxSpinButton creation failed") );
 
101
        return false;
 
102
    }
 
103
 
 
104
    m_pos = 0;
 
105
 
 
106
    m_widget = gtk_spin_button_new_with_range(0, 100, 1);
 
107
    g_object_ref(m_widget);
 
108
 
 
109
    gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(m_widget),
 
110
                              (int)(m_windowStyle & wxSP_WRAP) );
 
111
 
 
112
    g_signal_connect_after(
 
113
        m_widget, "value_changed", G_CALLBACK(gtk_value_changed), this);
 
114
 
 
115
    m_parent->DoAddChild( this );
 
116
 
 
117
    PostCreation(new_size);
 
118
 
 
119
    return true;
 
120
}
 
121
 
 
122
int wxSpinButton::GetMin() const
 
123
{
 
124
    wxCHECK_MSG( (m_widget != NULL), 0, wxT("invalid spin button") );
 
125
 
 
126
    double min;
 
127
    gtk_spin_button_get_range((GtkSpinButton*)m_widget, &min, NULL);
 
128
    return int(min);
 
129
}
 
130
 
 
131
int wxSpinButton::GetMax() const
 
132
{
 
133
    wxCHECK_MSG( (m_widget != NULL), 0, wxT("invalid spin button") );
 
134
 
 
135
    double max;
 
136
    gtk_spin_button_get_range((GtkSpinButton*)m_widget, NULL, &max);
 
137
    return int(max);
 
138
}
 
139
 
 
140
int wxSpinButton::GetValue() const
 
141
{
 
142
    wxCHECK_MSG( (m_widget != NULL), 0, wxT("invalid spin button") );
 
143
 
 
144
    return m_pos;
 
145
}
 
146
 
 
147
void wxSpinButton::SetValue( int value )
 
148
{
 
149
    wxCHECK_RET( (m_widget != NULL), wxT("invalid spin button") );
 
150
 
 
151
    GtkDisableEvents();
 
152
    gtk_spin_button_set_value((GtkSpinButton*)m_widget, value);
 
153
    m_pos = int(gtk_spin_button_get_value((GtkSpinButton*)m_widget));
 
154
    GtkEnableEvents();
 
155
}
 
156
 
 
157
void wxSpinButton::SetRange(int minVal, int maxVal)
 
158
{
 
159
    wxCHECK_RET( (m_widget != NULL), wxT("invalid spin button") );
 
160
 
 
161
    GtkDisableEvents();
 
162
    gtk_spin_button_set_range((GtkSpinButton*)m_widget, minVal, maxVal);
 
163
    m_pos = int(gtk_spin_button_get_value((GtkSpinButton*)m_widget));
 
164
    GtkEnableEvents();
 
165
}
 
166
 
 
167
void wxSpinButton::OnSize( wxSizeEvent &WXUNUSED(event) )
 
168
{
 
169
    wxCHECK_RET( (m_widget != NULL), wxT("invalid spin button") );
 
170
 
 
171
    m_width = DoGetBestSize().x;
 
172
    gtk_widget_set_size_request( m_widget, m_width, m_height );
 
173
}
 
174
 
 
175
bool wxSpinButton::Enable( bool enable )
 
176
{
 
177
    if (!base_type::Enable(enable))
 
178
        return false;
 
179
 
 
180
    // Work around lack of visual update when enabling
 
181
    if (enable)
 
182
        GTKFixSensitivity(false /* fix even if not under mouse */);
 
183
 
 
184
    return true;
 
185
}
 
186
 
 
187
void wxSpinButton::GtkDisableEvents() const
 
188
{
 
189
    g_signal_handlers_block_by_func(m_widget,
 
190
        (gpointer)gtk_value_changed, (void*) this);
 
191
}
 
192
 
 
193
void wxSpinButton::GtkEnableEvents() const
 
194
{
 
195
    g_signal_handlers_unblock_by_func(m_widget,
 
196
        (gpointer)gtk_value_changed, (void*) this);
 
197
}
 
198
 
 
199
GdkWindow *wxSpinButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 
200
{
 
201
#ifdef __WXGTK3__
 
202
    // no access to internal GdkWindows
 
203
    return NULL;
 
204
#else
 
205
    return GTK_SPIN_BUTTON(m_widget)->panel;
 
206
#endif
 
207
}
 
208
 
 
209
wxSize wxSpinButton::DoGetBestSize() const
 
210
{
 
211
    wxSize best(15, 26); // FIXME
 
212
    CacheBestSize(best);
 
213
    return best;
 
214
}
 
215
 
 
216
// static
 
217
wxVisualAttributes
 
218
wxSpinButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 
219
{
 
220
    // TODO: overload to accept functions like gtk_spin_button_new?
 
221
    // Until then use a similar type
 
222
    return GetDefaultAttributesFromGTKWidget(gtk_button_new);
 
223
}
 
224
 
 
225
#endif