]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/spinbutt.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/spinbutt.cpp
3 // Purpose: wxSpinButton
4 // Author: Julian Smart
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
16 #include "wx/spinbutt.h"
22 #include "wx/spinctrl.h"
25 #pragma message disable nosimpint
27 #include <Xm/ArrowBG.h>
28 #include <Xm/ArrowB.h>
30 #pragma message enable nosimpint
33 #include "wx/motif/private.h"
44 class wxArrowButtonTimer
;
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 static const unsigned int TICK_BEFORE_START
= 10;
52 static const unsigned int TICK_BEFORE_EXPONENTIAL
= 40;
53 static const unsigned int MAX_INCREMENT
= 150;
54 static const unsigned int TICK_INTERVAL
= 113;
56 class wxArrowButtonTimer
: public wxTimer
59 wxArrowButtonTimer( wxArrowButton
* btn
, int sign
)
65 void Reset() { m_ticks
= 0; m_increment
= 1; }
68 unsigned int m_increment
;
70 wxArrowButton
* m_button
;
73 // ----------------------------------------------------------------------------
75 // ----------------------------------------------------------------------------
77 class wxArrowButton
: public wxControl
79 friend class wxArrowButtonTimer
;
81 wxArrowButton( int increment
)
82 : m_increment( increment
),
85 wxArrowButton( wxSpinButton
* parent
, wxWindowID id
, ArrowDirection d
,
86 const wxPoint
& pos
= wxDefaultPosition
,
87 const wxSize
& size
= wxDefaultSize
, int increment
= 1 )
89 m_increment( increment
),
92 Create( parent
, id
, d
, pos
, size
);
95 virtual ~wxArrowButton()
98 bool Create( wxSpinButton
* parent
, wxWindowID id
, ArrowDirection d
,
99 const wxPoint
& pos
= wxDefaultPosition
,
100 const wxSize
& size
= wxDefaultSize
);
102 // creates a new timer object, or stops the currently running one
103 wxTimer
* GetFreshTimer();
104 wxSpinButton
* GetSpinButton() { return (wxSpinButton
*)GetParent(); }
105 static void SpinButtonCallback( Widget w
, XtPointer clientData
,
106 XtPointer
WXUNUSED(ptr
) );
107 static void StartTimerCallback( Widget w
, XtPointer clientData
,
108 XtPointer
WXUNUSED(ptr
) );
110 static void StopTimerCallback( Widget w
, XtPointer clientData
,
111 XtPointer
WXUNUSED(ptr
) );
114 wxArrowButtonTimer
* m_timer
;
117 // ----------------------------------------------------------------------------
118 // wxArrowButtonTimer implementation
119 // ----------------------------------------------------------------------------
121 void wxArrowButtonTimer::Notify()
124 if( m_ticks
< TICK_BEFORE_START
) return;
125 // increment every other tick
126 if( m_ticks
<= TICK_BEFORE_EXPONENTIAL
&& m_ticks
& 1 )
128 if( m_ticks
> TICK_BEFORE_EXPONENTIAL
)
129 m_increment
= 2 * m_increment
;
130 if( m_increment
>= MAX_INCREMENT
) m_increment
= MAX_INCREMENT
;
131 m_button
->GetSpinButton()->Increment( m_sign
* m_increment
);
134 // ----------------------------------------------------------------------------
135 // wxArrowButton implementation
136 // ----------------------------------------------------------------------------
138 wxTimer
* wxArrowButton::GetFreshTimer()
146 m_timer
= new wxArrowButtonTimer( this, m_increment
);
151 void wxArrowButton::SpinButtonCallback( Widget w
, XtPointer clientData
,
152 XtPointer
WXUNUSED(ptr
) )
154 if( !wxGetWindowFromTable( w
) )
155 // Widget has been deleted!
158 wxArrowButton
* btn
= (wxArrowButton
*)clientData
;
160 btn
->GetSpinButton()->Increment( btn
->m_increment
);
163 void wxArrowButton::StartTimerCallback( Widget w
, XtPointer clientData
,
164 XtPointer
WXUNUSED(ptr
) )
166 if( !wxGetWindowFromTable( w
) )
167 // Widget has been deleted!
170 wxArrowButton
* btn
= (wxArrowButton
*)clientData
;
171 btn
->GetFreshTimer()->Start( TICK_INTERVAL
);
174 void wxArrowButton::StopTimerCallback( Widget w
, XtPointer clientData
,
175 XtPointer
WXUNUSED(ptr
) )
177 if( !wxGetWindowFromTable( w
) )
178 // Widget has been deleted!
181 wxArrowButton
* btn
= (wxArrowButton
*)clientData
;
182 wxDELETE(btn
->m_timer
);
185 bool wxArrowButton::Create( wxSpinButton
* parent
,
186 wxWindowID
WXUNUSED(id
),
188 const wxPoint
& pos
, const wxSize
& size
)
190 wxCHECK_MSG( parent
, false, wxT("must have a valid parent") );
192 int arrow_dir
= XmARROW_UP
;
197 arrow_dir
= XmARROW_UP
;
200 arrow_dir
= XmARROW_DOWN
;
203 arrow_dir
= XmARROW_LEFT
;
206 arrow_dir
= XmARROW_RIGHT
;
210 parent
->AddChild( this );
213 Widget parentWidget
= (Widget
) parent
->GetClientWidget();
214 m_mainWidget
= (WXWidget
) XtVaCreateManagedWidget( "XmArrowButton",
215 xmArrowButtonWidgetClass
,
217 XmNarrowDirection
, arrow_dir
,
219 XmNshadowThickness
, 0,
222 XtAddCallback( (Widget
) m_mainWidget
,
223 XmNactivateCallback
, (XtCallbackProc
) SpinButtonCallback
,
225 XtAddCallback( (Widget
) m_mainWidget
,
226 XmNarmCallback
, (XtCallbackProc
) StartTimerCallback
,
228 XtAddCallback( (Widget
) m_mainWidget
,
229 XmNactivateCallback
, (XtCallbackProc
) StopTimerCallback
,
233 AttachWidget( parent
, m_mainWidget
, (WXWidget
) NULL
,
234 pos
.x
, pos
.y
, size
.x
, size
.y
);
239 // ----------------------------------------------------------------------------
241 // ----------------------------------------------------------------------------
243 static void CalcSizes( const wxPoint
& pt
, const wxSize
& sz
,
244 wxPoint
& pt1
, wxSize
& sz1
,
245 wxPoint
& pt2
, wxSize
& sz2
,
248 typedef int wxSize::* CDPTR1
;
249 typedef int wxPoint::* CDPTR2
;
254 CDPTR1 szm
= isVertical
? &wxSize::y
: &wxSize::x
;
255 CDPTR2 ptm
= isVertical
? &wxPoint::y
: &wxPoint::x
;
256 int dim
= sz
.*szm
, half
= dim
/2;
259 sz2
.*szm
= dim
- half
;
260 pt2
.*ptm
+= half
+ 1;
263 bool wxSpinButton::Create( wxWindow
*parent
, wxWindowID id
,
264 const wxPoint
& pos
, const wxSize
& size
,
265 long style
, const wxString
& name
)
267 m_windowStyle
= style
;
269 wxSize newSize
= GetBestSize();
270 if( size
.x
!= -1 ) newSize
.x
= size
.x
;
271 if( size
.y
!= -1 ) newSize
.y
= size
.y
;
273 if( !wxControl::Create( parent
, id
, pos
, newSize
, style
) )
280 m_windowId
= ( id
== wxID_ANY
) ? NewControlId() : id
;
282 bool isVert
= IsVertical();
285 CalcSizes( wxPoint(0,0), newSize
, pt1
, sz1
, pt2
, sz2
, isVert
);
286 m_up
= new wxArrowButton( this, -1, isVert
? wxARROW_UP
: wxARROW_RIGHT
,
288 m_down
= new wxArrowButton( this, -1,
289 isVert
? wxARROW_DOWN
: wxARROW_LEFT
,
295 wxSpinButton::~wxSpinButton()
299 void wxSpinButton::DoMoveWindow(int x
, int y
, int width
, int height
)
301 wxControl::DoMoveWindow( x
, y
, width
, height
);
306 CalcSizes( wxPoint(0,0), wxSize(width
,height
), pt1
,
307 sz1
, pt2
, sz2
, IsVertical() );
308 m_up
->SetSize( pt1
.x
, pt1
.y
, sz1
.x
, sz1
.y
);
309 m_down
->SetSize( pt2
.x
, pt2
.y
, sz2
.x
, sz2
.y
);
312 void wxSpinButton::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
314 if ( (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) && width
== -1 )
316 if ( (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) && height
== -1 )
317 height
= GetSize().y
;
319 wxControl::DoSetSize(x
, y
, width
, height
, 0);
322 void wxSpinButton::Increment( int delta
)
324 if( m_pos
< m_min
) m_pos
= m_min
;
325 if( m_pos
> m_max
) m_pos
= m_max
;
327 int npos
= m_pos
+ delta
;
331 if( GetWindowStyle() & wxSP_WRAP
)
338 if( GetWindowStyle() & wxSP_WRAP
)
343 if( npos
== m_pos
) return;
345 wxSpinEvent
event( delta
> 0 ? wxEVT_SCROLL_LINEUP
: wxEVT_SCROLL_LINEDOWN
,
347 event
.SetPosition( npos
);
348 event
.SetEventObject( this );
350 HandleWindowEvent( event
);
352 if( event
.IsAllowed() )
355 event
.SetEventType( wxEVT_SCROLL_THUMBTRACK
);
356 event
.SetPosition( m_pos
);
358 HandleWindowEvent( event
);
362 wxSize
wxSpinButton::DoGetBestSize() const
364 return IsVertical() ? wxSize( 20, 30 ) : wxSize( 30, 20 );
368 ////////////////////////////////////////////////////////////////////////////
370 int wxSpinButton::GetValue() const
375 void wxSpinButton::SetValue(int val
)
380 void wxSpinButton::SetRange(int minVal
, int maxVal
)
382 wxSpinButtonBase::SetRange(minVal
, maxVal
);
385 void wxSpinButton::ChangeFont(bool WXUNUSED(keepOriginalSize
))
390 void wxSpinButton::ChangeBackgroundColour()
392 wxControl::ChangeBackgroundColour();
395 void wxSpinButton::ChangeForegroundColour()
400 #endif // wxUSE_SPINBTN