+public:
+ wxArrowButtonTimer( wxArrowButton* btn, int sign )
+ : m_sign( sign ),
+ m_button( btn )
+ { Reset(); };
+
+ void Notify();
+ void Reset() { m_ticks = 0; m_increment = 1; }
+private:
+ unsigned int m_ticks;
+ unsigned int m_increment;
+ int m_sign;
+ wxArrowButton* m_button;
+};
+
+// ----------------------------------------------------------------------------
+// wxArrowButton
+// ----------------------------------------------------------------------------
+
+class wxArrowButton : public wxControl
+{
+ friend class wxArrowButtonTimer;
+public:
+ wxArrowButton( int increment )
+ : m_increment( increment ),
+ m_timer( 0 ) {}
+
+ wxArrowButton( wxSpinButton* parent, wxWindowID id, ArrowDirection d,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize, int increment = 1 )
+ : wxControl(),
+ m_increment( increment ),
+ m_timer( 0 )
+ {
+ Create( parent, id, d, pos, size );
+ }
+
+ ~wxArrowButton()
+ { delete m_timer; }
+
+ bool Create( wxSpinButton* parent, wxWindowID id, ArrowDirection d,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize );
+private:
+ // creates a new timer object, or stops the currently running one
+ wxTimer* GetFreshTimer();
+ wxSpinButton* GetSpinButton() { return (wxSpinButton*)GetParent(); }
+ static void SpinButtonCallback( Widget w, XtPointer clientData,
+ XtPointer WXUNUSED(ptr) );
+ static void StartTimerCallback( Widget w, XtPointer clientData,
+ XtPointer WXUNUSED(ptr) );
+
+ static void StopTimerCallback( Widget w, XtPointer clientData,
+ XtPointer WXUNUSED(ptr) );
+
+ int m_increment;
+ wxArrowButtonTimer* m_timer;
+};
+
+// ----------------------------------------------------------------------------
+// wxArrowButtonTimer implementation
+// ----------------------------------------------------------------------------
+
+void wxArrowButtonTimer::Notify()
+{
+ ++m_ticks;
+ if( m_ticks < TICK_BEFORE_START ) return;
+ // increment every other tick
+ if( m_ticks <= TICK_BEFORE_EXPONENTIAL && m_ticks & 1 )
+ return;
+ if( m_ticks > TICK_BEFORE_EXPONENTIAL )
+ m_increment = 2 * m_increment;
+ if( m_increment >= MAX_INCREMENT ) m_increment = MAX_INCREMENT;
+ m_button->GetSpinButton()->Increment( m_sign * m_increment );