15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef UI_VIEWS_CONTROLS_BUTTON_CUSTOM_BUTTON_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_VIEWS_CONTROLS_BUTTON_CUSTOM_BUTTON_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_constants.h"
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/animation_delegate.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/button.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace gfx {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ThrobAnimation;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CustomButtonStateChangedDelegate;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A button with custom rendering. The common base class of ImageButton and
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TextButton.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that this type of button is not focusable by default and will not be
24d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// part of the focus chain.  Call SetFocusable(true) to make it part of the
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// focus chain.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VIEWS_EXPORT CustomButton : public Button,
27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                  public gfx::AnimationDelegate {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The menu button's class name.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kViewClassName[];
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const CustomButton* AsCustomButton(const views::View* view);
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static CustomButton* AsCustomButton(views::View* view);
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CustomButton();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get/sets the current display state of the button.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ButtonState state() const { return state_; }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetState(ButtonState state);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts throbbing. See HoverAnimation for a description of cycles_til_stop.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartThrobbing(int cycles_til_stop);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stops throbbing immediately.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StopThrobbing();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set how long the hover animation will last for.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetAnimationDuration(int duration);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_triggerable_event_flags(int triggerable_event_flags) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    triggerable_event_flags_ = triggerable_event_flags;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int triggerable_event_flags() const { return triggerable_event_flags_; }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets whether |RequestFocus| should be invoked on a mouse press. The default
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is true.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_request_focus_on_press(bool value) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_focus_on_press_ = value;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool request_focus_on_press() const { return request_focus_on_press_; }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above field.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_animate_on_state_change(bool value) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    animate_on_state_change_ = value;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetHotTracked(bool is_hot_tracked);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsHotTracked() const;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from View:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnEnabledChanged() OVERRIDE;
72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual const char* GetClassName() const OVERRIDE;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseCaptureLost() OVERRIDE;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowContextMenu(const gfx::Point& p,
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               ui::MenuSourceType source_type) OVERRIDE;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnDragDone() OVERRIDE;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void VisibilityChanged(View* starting_from, bool is_visible) OVERRIDE;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Overridden from gfx::AnimationDelegate:
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Takes ownership of the delegate.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_state_changed_delegate(CustomButtonStateChangedDelegate* delegate) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state_changed_delegate_.reset(delegate);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct the Button with a Listener. See comment for Button's ctor.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit CustomButton(ButtonListener* listener);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked from SetState() when SetState() is passed a value that differs from
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the current state. CustomButton's implementation of StateChanged() does
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // nothing; this method is provided for subclasses that wish to do something
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on state changes.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StateChanged();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the event is one that can trigger notifying the listener.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This implementation returns true if the left mouse button is down.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsTriggerableEvent(const ui::Event& event);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the button should become pressed when the user
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // holds the mouse down over the button. For this implementation,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we simply return IsTriggerableEvent(event).
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool ShouldEnterPushedState(const ui::Event& event);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from View:
118a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  virtual void ViewHierarchyChanged(
119a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const ViewHierarchyChangedDetails& details) OVERRIDE;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnBlur() OVERRIDE;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The button state (defined in implementation)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ButtonState state_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hover animation.
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scoped_ptr<gfx::ThrobAnimation> hover_animation_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should we animate when the state changes? Defaults to true.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool animate_on_state_change_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is the hover animation running because StartThrob was invoked?
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_throbbing_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mouse event flags which can trigger button actions.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int triggerable_event_flags_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See description above setter.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool request_focus_on_press_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<CustomButtonStateChangedDelegate> state_changed_delegate_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CustomButton);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delegate for actions taken on state changes by CustomButton.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VIEWS_EXPORT CustomButtonStateChangedDelegate {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CustomButtonStateChangedDelegate() {}
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void StateChanged(Button::ButtonState state) = 0;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CustomButtonStateChangedDelegate() {}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private:
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CustomButtonStateChangedDelegate);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // UI_VIEWS_CONTROLS_BUTTON_CUSTOM_BUTTON_H_
162