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