diff --git a/include/wx/gtk/slider.h b/include/wx/gtk/slider.h index 7dfc2ac772..94132f9833 100644 --- a/include/wx/gtk/slider.h +++ b/include/wx/gtk/slider.h @@ -56,6 +56,10 @@ public: virtual void SetThumbLength(int lenPixels) wxOVERRIDE; virtual int GetThumbLength() const wxOVERRIDE; + virtual void ClearTicks() wxOVERRIDE; + virtual void SetTick(int tickPos) wxOVERRIDE; + int GetTickFreq() const wxOVERRIDE; + static wxVisualAttributes GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); @@ -73,11 +77,20 @@ protected: GtkWidget *m_minLabel,*m_maxLabel; bool m_blockScrollEvent; + // Note the following member is not used in GTK+2 < 2.16. + int m_tickFreq; + virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const wxOVERRIDE; // set the slider value unconditionally void GTKSetValue(int value); + // Platform-specific implementation of SetTickFreq + virtual void DoSetTickFreq(int freq) wxOVERRIDE; + +private: + void Init(); + wxDECLARE_DYNAMIC_CLASS(wxSlider); }; diff --git a/interface/wx/slider.h b/interface/wx/slider.h index 0c35d97224..3e5529c8fc 100644 --- a/interface/wx/slider.h +++ b/interface/wx/slider.h @@ -30,6 +30,8 @@ On Windows, the track bar control is used. + On GTK+, tick marks are only available for version 2.16 and later. + Slider generates the same events as wxScrollBar but in practice the most convenient way to process wxSlider updates is by handling the slider-specific @c wxEVT_SLIDER event which carries wxCommandEvent @@ -41,7 +43,7 @@ @style{wxSL_VERTICAL} Displays the slider vertically. @style{wxSL_AUTOTICKS} - Displays tick marks. Windows only. + Displays tick marks (Windows, GTK+ 2.16 and later). @style{wxSL_MIN_MAX_LABELS} Displays minimum, maximum labels (new since wxWidgets 2.9.1). @style{wxSL_VALUE_LABEL} @@ -50,11 +52,11 @@ Displays minimum, maximum and value labels (same as wxSL_VALUE_LABEL and wxSL_MIN_MAX_LABELS together). @style{wxSL_LEFT} - Displays ticks on the left and forces the slider to be vertical. + Displays ticks on the left and forces the slider to be vertical (Windows and GTK+ 3 only). @style{wxSL_RIGHT} Displays ticks on the right and forces the slider to be vertical. @style{wxSL_TOP} - Displays ticks on the top. + Displays ticks on the top (Windows and GTK+ 3 only). @style{wxSL_BOTTOM} Displays ticks on the bottom (this is the default). @style{wxSL_BOTH} @@ -67,11 +69,11 @@ @endStyleTable Notice that @c wxSL_LEFT, @c wxSL_TOP, @c wxSL_RIGHT and @c wxSL_BOTTOM - specify the position of the slider ticks in MSW implementation and that the - slider labels, if any, are positioned on the opposite side. So, to have a - label on the left side of a vertical slider, @b wxSL_RIGHT must be used (or - none of these styles at all should be specified as left and top are default - positions for the vertical and horizontal sliders respectively). + specify the position of the slider ticks and that the slider labels, if any, + are positioned on the opposite side. So, to have a label on the left side of + a vertical slider, @b wxSL_RIGHT must be used (or none of these styles at all + should be specified as left and top are default positions for the vertical + and horizontal sliders respectively). @beginEventEmissionTable{wxScrollEvent} You can use EVT_COMMAND_SCROLL... macros with window IDs for when intercepting @@ -206,7 +208,7 @@ public: /** Clears the ticks. - @onlyfor{wxmsw} + @onlyfor{wxmsw,wxgtk} */ virtual void ClearTicks(); @@ -278,7 +280,7 @@ public: /** Returns the tick frequency. - @onlyfor{wxmsw} + @onlyfor{wxmsw,wxgtk} @see SetTickFreq() */ @@ -372,7 +374,7 @@ public: @param tickPos The tick position. - @onlyfor{wxmsw} + @onlyfor{wxmsw,wxgtk} @see SetTickFreq() */ @@ -385,11 +387,11 @@ public: Frequency. For example, if the frequency is set to two, a tick mark is displayed for every other increment in the slider's range. - @onlyfor{wxmsw} + @onlyfor{wxmsw,wxgtk} @see GetTickFreq() */ - virtual void SetTickFreq(int n); + virtual void SetTickFreq(int freq); /** Sets the slider position. diff --git a/src/gtk/slider.cpp b/src/gtk/slider.cpp index 2d86c965cf..3b59de161c 100644 --- a/src/gtk/slider.cpp +++ b/src/gtk/slider.cpp @@ -273,7 +273,7 @@ static gchar* gtk_format_value(GtkScale*, double value, void*) wxSlider::wxSlider() { - m_scale = NULL; + Init(); } wxSlider::~wxSlider() @@ -282,6 +282,15 @@ wxSlider::~wxSlider() GTKDisconnect(m_scale); } +void wxSlider::Init() +{ + m_scrollEventType = GTK_SCROLL_NONE; + m_needThumbRelease = false; + m_blockScrollEvent = false; + m_tickFreq = 0; + m_scale = NULL; +} + bool wxSlider::Create(wxWindow *parent, wxWindowID id, int value, @@ -293,10 +302,8 @@ bool wxSlider::Create(wxWindow *parent, const wxValidator& validator, const wxString& name) { + Init(); m_pos = value; - m_scrollEventType = GTK_SCROLL_NONE; - m_needThumbRelease = false; - m_blockScrollEvent = false; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, validator, name )) @@ -344,9 +351,9 @@ bool wxSlider::Create(wxWindow *parent, gtk_scale_set_draw_value(GTK_SCALE (m_scale), showValueLabel ); if ( showValueLabel ) { - // position the label appropriately: notice that wxSL_DIRECTION flags - // specify the position of the ticks, not label, under MSW and so the - // label is on the opposite side + // Position the label appropriately: notice that wxSL_DIRECTION flags + // specify the position of the ticks, not label, and so the + // label is on the opposite side. GtkPositionType posLabel; if ( style & wxSL_VERTICAL ) { @@ -501,6 +508,69 @@ int wxSlider::GetLineSize() const return int(gtk_adjustment_get_step_increment(adj)); } +void wxSlider::ClearTicks() +{ +#if GTK_CHECK_VERSION(2,16,0) + if (wx_is_at_least_gtk2(16)) + gtk_scale_clear_marks(GTK_SCALE (m_scale)); +#endif +} + +void wxSlider::SetTick(int tickPos) +{ +#if GTK_CHECK_VERSION(2,16,0) + if ( wx_is_at_least_gtk2(16) ) + { + GtkPositionType posTicks; + long style = GetWindowStyle(); + + if ( style & wxSL_VERTICAL ) + { + if ( style & wxSL_LEFT ) + posTicks = GTK_POS_LEFT; + else + posTicks = GTK_POS_RIGHT; + } + else // horizontal slider + { + if ( style & wxSL_TOP ) + posTicks = GTK_POS_TOP; + else + posTicks = GTK_POS_BOTTOM; + } + + gtk_scale_add_mark(GTK_SCALE (m_scale), (double)tickPos, posTicks, NULL); + } +#else + wxUnusedVar(tickPos); +#endif +} + +void wxSlider::DoSetTickFreq(int freq) +{ +#if GTK_CHECK_VERSION(2,16,0) + if ( wx_is_at_least_gtk2(16) ) + { + m_tickFreq = freq; + gtk_scale_clear_marks(GTK_SCALE (m_scale)); + + for (int i = GetMin() + freq; i < GetMax(); i += freq) + SetTick(i); + } +#else + wxUnusedVar(freq); +#endif +} + +int wxSlider::GetTickFreq() const +{ +#if GTK_CHECK_VERSION(2,16,0) + return wx_is_at_least_gtk2(16) ? m_tickFreq : -1; +#else + return -1; +#endif +} + GdkWindow *wxSlider::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const { #ifdef __WXGTK3__