// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef UI_VIEWS_CONTROLS_SLIDER_H_ #define UI_VIEWS_CONTROLS_SLIDER_H_ #include #include "base/containers/flat_set.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/animation/slide_animation.h" #include "ui/views/view.h" #include "ui/views/views_export.h" namespace views { namespace test { class SliderTestApi; } class Slider; enum class SliderChangeReason { kByUser, // value was changed by the user (e.g. by clicking) kByApi, // value was changed by a call to SetValue. }; class VIEWS_EXPORT SliderListener { public: virtual void SliderValueChanged(Slider* sender, float value, float old_value, SliderChangeReason reason) = 0; // Invoked when a drag starts or ends (more specifically, when the mouse // button is pressed or released). virtual void SliderDragStarted(Slider* sender) {} virtual void SliderDragEnded(Slider* sender) {} protected: virtual ~SliderListener() = default; }; // Slider operates in interval [0,1] by default, but can also switch between a // predefined set of values, see SetAllowedValues method below. class VIEWS_EXPORT Slider : public View, public gfx::AnimationDelegate { public: METADATA_HEADER(Slider); explicit Slider(SliderListener* listener = nullptr); Slider(const Slider&) = delete; Slider& operator=(const Slider&) = delete; ~Slider() override; float GetValue() const; void SetValue(float value); bool GetEnableAccessibilityEvents() const; void SetEnableAccessibilityEvents(bool enabled); // Represents the visual style of the slider. enum class RenderingStyle { kDefaultStyle, kMinimalStyle, }; // Set rendering style and schedule paint since the colors for the slider // may change. void SetRenderingStyle(RenderingStyle style); RenderingStyle style() const { return style_; } // Sets discrete set of allowed slider values. Each value must be in [0,1]. // Sets active value to the lower bound of the current value in allowed set. // nullptr will drop currently active set and allow full [0,1] interval. void SetAllowedValues(const base::flat_set* allowed_values); const base::flat_set& allowed_values() const { return allowed_values_; } protected: // Returns the current position of the thumb on the slider. float GetAnimatingValue() const; // Shows or hides the highlight on the slider thumb. The default // implementation does nothing. void SetHighlighted(bool is_highlighted); // gfx::AnimationDelegate: void AnimationProgressed(const gfx::Animation* animation) override; void AnimationEnded(const gfx::Animation* animation) override; // views::View: void OnPaint(gfx::Canvas* canvas) override; private: friend class test::SliderTestApi; void SetValueInternal(float value, SliderChangeReason reason); // Should be called on the Mouse Down event. Used to calculate relative // position of the mouse cursor (or the touch point) on the button to // accurately move the button using the MoveButtonTo() method. void PrepareForMove(const int new_x); // Moves the button to the specified point and updates the value accordingly. void MoveButtonTo(const gfx::Point& point); // Notify the listener_, if not NULL, that dragging started. void OnSliderDragStarted(); // Notify the listener_, if not NULL, that dragging ended. void OnSliderDragEnded(); // views::View: gfx::Size CalculatePreferredSize() const override; bool OnMousePressed(const ui::MouseEvent& event) override; bool OnMouseDragged(const ui::MouseEvent& event) override; void OnMouseReleased(const ui::MouseEvent& event) override; bool OnKeyPressed(const ui::KeyEvent& event) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; bool HandleAccessibleAction(const ui::AXActionData& action_data) override; void OnFocus() override; void OnBlur() override; void VisibilityChanged(View* starting_from, bool is_visible) override; void AddedToWidget() override; // ui::EventHandler: void OnGestureEvent(ui::GestureEvent* event) override; void set_listener(SliderListener* listener) { listener_ = listener; } void NotifyPendingAccessibilityValueChanged(); virtual SkColor GetThumbColor() const; virtual SkColor GetTroughColor() const; int GetSliderExtraPadding() const; SliderListener* listener_; std::unique_ptr move_animation_; // When |allowed_values_| is not empty, slider will allow moving only between // these values. I.e. it will become discrete slider. base::flat_set allowed_values_; // Allowed values. float value_ = 0.f; float keyboard_increment_ = 0.1f; float initial_animating_value_ = 0.f; bool value_is_valid_ = false; bool accessibility_events_enabled_ = true; // Relative position of the mouse cursor (or the touch point) on the slider's // button. int initial_button_offset_ = 0; RenderingStyle style_ = RenderingStyle::kDefaultStyle; // Animating value of the current radius of the thumb's highlight. float thumb_highlight_radius_ = 0.f; gfx::SlideAnimation highlight_animation_{this}; bool pending_accessibility_value_change_ = false; }; } // namespace views #endif // UI_VIEWS_CONTROLS_SLIDER_H_