]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/spinbutt.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxSpinButton
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "spinbutt.h"
16 #include "wx/spinbutt.h"
17 #include "wx/spinctrl.h"
21 #pragma message disable nosimpint
23 #include <Xm/ArrowBG.h>
24 #include <Xm/ArrowB.h>
26 #pragma message enable nosimpint
29 #include "wx/motif/private.h"
40 class wxArrowButtonTimer
;
43 // ----------------------------------------------------------------------------
45 // ----------------------------------------------------------------------------
47 static const unsigned int TICK_BEFORE_START
= 10;
48 static const unsigned int TICK_BEFORE_EXPONENTIAL
= 40;
49 static const unsigned int MAX_INCREMENT
= 150;
50 static const unsigned int TICK_INTERVAL
= 113;
52 class wxArrowButtonTimer
: public wxTimer
55 wxArrowButtonTimer( wxArrowButton
* btn
, int sign
)
61 void Reset() { m_ticks
= 0; m_increment
= 1; }
64 unsigned int m_increment
;
66 wxArrowButton
* m_button
;
69 // ----------------------------------------------------------------------------
71 // ----------------------------------------------------------------------------
73 class wxArrowButton
: public wxControl
75 friend class wxArrowButtonTimer
;
77 wxArrowButton( int increment
)
78 : m_increment( increment
),
81 wxArrowButton( wxSpinButton
* parent
, wxWindowID id
, ArrowDirection d
,
82 const wxPoint
& pos
= wxDefaultPosition
,
83 const wxSize
& size
= wxDefaultSize
, int increment
= 1 )
85 m_increment( increment
),
88 Create( parent
, id
, d
, pos
, size
);
94 bool Create( wxSpinButton
* parent
, wxWindowID id
, ArrowDirection d
,
95 const wxPoint
& pos
= wxDefaultPosition
,
96 const wxSize
& size
= wxDefaultSize
);
98 // creates a new timer object, or stops the currently running one
99 wxTimer
* GetFreshTimer();
100 wxSpinButton
* GetSpinButton() { return (wxSpinButton
*)GetParent(); }
101 static void SpinButtonCallback( Widget w
, XtPointer clientData
,
102 XtPointer
WXUNUSED(ptr
) );
103 static void StartTimerCallback( Widget w
, XtPointer clientData
,
104 XtPointer
WXUNUSED(ptr
) );
106 static void StopTimerCallback( Widget w
, XtPointer clientData
,
107 XtPointer
WXUNUSED(ptr
) );
110 wxArrowButtonTimer
* m_timer
;
113 // ----------------------------------------------------------------------------
114 // wxArrowButtonTimer implementation
115 // ----------------------------------------------------------------------------
117 void wxArrowButtonTimer::Notify()
120 if( m_ticks
< TICK_BEFORE_START
) return;
121 // increment every other tick
122 if( m_ticks
<= TICK_BEFORE_EXPONENTIAL
&& m_ticks
& 1 )
124 if( m_ticks
> TICK_BEFORE_EXPONENTIAL
)
125 m_increment
= 2 * m_increment
;
126 if( m_increment
>= MAX_INCREMENT
) m_increment
= MAX_INCREMENT
;
127 m_button
->GetSpinButton()->Increment( m_sign
* m_increment
);
130 // ----------------------------------------------------------------------------
131 // wxArrowButton implementation
132 // ----------------------------------------------------------------------------
134 wxTimer
* wxArrowButton::GetFreshTimer()
142 m_timer
= new wxArrowButtonTimer( this, m_increment
);
147 void wxArrowButton::SpinButtonCallback( Widget w
, XtPointer clientData
,
148 XtPointer
WXUNUSED(ptr
) )
150 if( !wxGetWindowFromTable( w
) )
151 // Widget has been deleted!
154 wxArrowButton
* btn
= (wxArrowButton
*)clientData
;
156 btn
->GetSpinButton()->Increment( btn
->m_increment
);
159 void wxArrowButton::StartTimerCallback( Widget w
, XtPointer clientData
,
160 XtPointer
WXUNUSED(ptr
) )
162 if( !wxGetWindowFromTable( w
) )
163 // Widget has been deleted!
166 wxArrowButton
* btn
= (wxArrowButton
*)clientData
;
167 btn
->GetFreshTimer()->Start( TICK_INTERVAL
);
170 void wxArrowButton::StopTimerCallback( Widget w
, XtPointer clientData
,
171 XtPointer
WXUNUSED(ptr
) )
173 if( !wxGetWindowFromTable( w
) )
174 // Widget has been deleted!
177 wxArrowButton
* btn
= (wxArrowButton
*)clientData
;
182 bool wxArrowButton::Create( wxSpinButton
* parent
, wxWindowID id
,
184 const wxPoint
& pos
, const wxSize
& size
)
191 arrow_dir
= XmARROW_UP
;
194 arrow_dir
= XmARROW_DOWN
;
197 arrow_dir
= XmARROW_LEFT
;
200 arrow_dir
= XmARROW_RIGHT
;
204 if( parent
) parent
->AddChild( this );
206 Widget parentWidget
= (Widget
) parent
->GetClientWidget();
207 m_mainWidget
= (WXWidget
) XtVaCreateManagedWidget( "XmArrowButton",
208 xmArrowButtonWidgetClass
,
210 XmNarrowDirection
, arrow_dir
,
213 XtAddCallback( (Widget
) m_mainWidget
,
214 XmNactivateCallback
, (XtCallbackProc
) SpinButtonCallback
,
216 XtAddCallback( (Widget
) m_mainWidget
,
217 XmNarmCallback
, (XtCallbackProc
) StartTimerCallback
,
219 XtAddCallback( (Widget
) m_mainWidget
,
220 XmNactivateCallback
, (XtCallbackProc
) StopTimerCallback
,
223 AttachWidget( parent
, m_mainWidget
, (WXWidget
) NULL
,
224 pos
.x
, pos
.y
, size
.x
, size
.y
);
229 // ----------------------------------------------------------------------------
231 // ----------------------------------------------------------------------------
233 IMPLEMENT_DYNAMIC_CLASS(wxSpinButton
, wxControl
);
234 IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent
, wxNotifyEvent
);
236 static void CalcSizes( wxPoint pt
, wxSize sz
,
237 wxPoint
& pt1
, wxSize
& sz1
,
238 wxPoint
& pt2
, wxSize
& sz2
,
241 typedef int wxSize::* CDPTR1
;
242 typedef int wxPoint::* CDPTR2
;
247 CDPTR1 szm
= isVertical
? &wxSize::y
: &wxSize::x
;
248 CDPTR2 ptm
= isVertical
? &wxPoint::y
: &wxPoint::x
;
249 int dim
= sz
.*szm
, half
= dim
/2;
252 sz2
.*szm
= dim
- half
;
253 pt2
.*ptm
+= half
+ 1;
256 bool wxSpinButton::Create( wxWindow
*parent
, wxWindowID id
,
257 const wxPoint
& pos
, const wxSize
& size
,
258 long style
, const wxString
& name
)
260 m_windowStyle
= style
;
262 wxSize newSize
= GetBestSize();
263 if( size
.x
!= -1 ) newSize
.x
= size
.x
;
264 if( size
.y
!= -1 ) newSize
.y
= size
.y
;
266 if( !wxControl::Create( parent
, id
, pos
, newSize
, style
) )
275 m_windowId
= ( id
== -1 ) ? NewControlId() : id
;
277 bool isVert
= IsVertical();
280 CalcSizes( wxPoint(0,0), newSize
, pt1
, sz1
, pt2
, sz2
, isVert
);
281 m_up
= new wxArrowButton( this, -1, isVert
? wxARROW_UP
: wxARROW_LEFT
,
283 m_down
= new wxArrowButton( this, -1,
284 isVert
? wxARROW_DOWN
: wxARROW_RIGHT
,
290 wxSpinButton::~wxSpinButton()
294 void wxSpinButton::DoMoveWindow(int x
, int y
, int width
, int height
)
296 wxControl::DoMoveWindow( x
, y
, width
, height
);
301 CalcSizes( wxPoint(0,0), wxSize(width
,height
), pt1
,
302 sz1
, pt2
, sz2
, IsVertical() );
303 m_up
->SetSize( pt1
.x
, pt1
.y
, sz1
.x
, sz1
.y
);
304 m_down
->SetSize( pt2
.x
, pt2
.y
, sz2
.x
, sz2
.y
);
307 void wxSpinButton::DoSetSize(int x
, int y
, int width
, int height
,
310 if( sizeFlags
& wxSIZE_AUTO_WIDTH
&& width
== -1 )
312 if( sizeFlags
& wxSIZE_AUTO_HEIGHT
&& height
== -1 )
314 if( sizeFlags
& wxSIZE_USE_EXISTING
&& width
== -1 )
316 if( sizeFlags
& wxSIZE_USE_EXISTING
&& 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
;
329 if( npos
< m_min
) npos
= m_min
;
330 if( npos
> m_max
) npos
= m_max
;
331 if( npos
== m_pos
) return;
333 wxSpinEvent
event( delta
> 0 ? wxEVT_SCROLL_LINEUP
: wxEVT_SCROLL_LINEDOWN
,
335 event
.SetPosition( npos
);
336 event
.SetEventObject( this );
338 GetEventHandler()->ProcessEvent( event
);
340 if( event
.IsAllowed() )
343 event
.SetEventType( wxEVT_SCROLL_THUMBTRACK
);
344 event
.SetPosition( m_pos
);
346 GetEventHandler()->ProcessEvent( event
);
350 wxSize
wxSpinButton::DoGetBestSize() const
352 return IsVertical() ? wxSize( 24, 34 ) : wxSize( 34, 24 );
356 ////////////////////////////////////////////////////////////////////////////
358 int wxSpinButton::GetValue() const
363 void wxSpinButton::SetValue(int val
)
368 void wxSpinButton::SetRange(int minVal
, int maxVal
)
370 wxSpinButtonBase::SetRange(minVal
, maxVal
);
373 void wxSpinButton::ChangeFont(bool WXUNUSED(keepOriginalSize
))
378 void wxSpinButton::ChangeBackgroundColour()
380 wxControl::ChangeBackgroundColour();
383 void wxSpinButton::ChangeForegroundColour()