1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// 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_BUTTON_MENU_BUTTON_H_
#define UI_VIEWS_CONTROLS_BUTTON_MENU_BUTTON_H_
#include <string>
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
namespace views {
class MenuButtonListener;
////////////////////////////////////////////////////////////////////////////////
//
// MenuButton
//
// A button that shows a menu when the left mouse button is pushed
//
////////////////////////////////////////////////////////////////////////////////
class VIEWS_EXPORT MenuButton : public LabelButton {
public:
// A scoped lock for keeping the MenuButton in STATE_PRESSED e.g., while a
// menu is running. These are cumulative.
class VIEWS_EXPORT PressedLock {
public:
explicit PressedLock(MenuButton* menu_button);
~PressedLock();
private:
base::WeakPtr<MenuButton> menu_button_;
DISALLOW_COPY_AND_ASSIGN(PressedLock);
};
static const char kViewClassName[];
// How much padding to put on the left and right of the menu marker.
static const int kMenuMarkerPaddingLeft;
static const int kMenuMarkerPaddingRight;
// Create a Button.
MenuButton(ButtonListener* listener,
const base::string16& text,
MenuButtonListener* menu_button_listener,
bool show_menu_marker);
~MenuButton() override;
bool show_menu_marker() const { return show_menu_marker_; }
void set_menu_marker(const gfx::ImageSkia* menu_marker) {
menu_marker_ = menu_marker;
}
const gfx::ImageSkia* menu_marker() const { return menu_marker_; }
const gfx::Point& menu_offset() const { return menu_offset_; }
void set_menu_offset(int x, int y) { menu_offset_.SetPoint(x, y); }
// Activate the button (called when the button is pressed).
virtual bool Activate();
// Overridden from View:
gfx::Size GetPreferredSize() const override;
const char* GetClassName() const override;
void OnPaint(gfx::Canvas* canvas) override;
bool OnMousePressed(const ui::MouseEvent& event) override;
void OnMouseReleased(const ui::MouseEvent& event) override;
void OnMouseEntered(const ui::MouseEvent& event) override;
void OnMouseExited(const ui::MouseEvent& event) override;
void OnMouseMoved(const ui::MouseEvent& event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
bool OnKeyPressed(const ui::KeyEvent& event) override;
bool OnKeyReleased(const ui::KeyEvent& event) override;
void GetAccessibleState(ui::AXViewState* state) override;
protected:
// Paint the menu marker image.
void PaintMenuMarker(gfx::Canvas* canvas);
// Overridden from LabelButton:
gfx::Rect GetChildAreaBounds() override;
// Overridden from CustomButton:
bool ShouldEnterPushedState(const ui::Event& event) override;
// Offset of the associated menu position.
gfx::Point menu_offset_;
private:
friend class PressedLock;
// Increment/decrement the number of "pressed" locks this button has, and
// set the state accordingly.
void IncrementPressedLocked();
void DecrementPressedLocked();
// Compute the maximum X coordinate for the current screen. MenuButtons
// use this to make sure a menu is never shown off screen.
int GetMaximumScreenXCoordinate();
// We use a time object in order to keep track of when the menu was closed.
// The time is used for simulating menu behavior for the menu button; that
// is, if the menu is shown and the button is pressed, we need to close the
// menu. There is no clean way to get the second click event because the
// menu is displayed using a modal loop and, unlike regular menus in Windows,
// the button is not part of the displayed menu.
base::TimeTicks menu_closed_time_;
// Our listener. Not owned.
MenuButtonListener* listener_;
// Whether or not we're showing a drop marker.
bool show_menu_marker_;
// The down arrow used to differentiate the menu button from normal buttons.
const gfx::ImageSkia* menu_marker_;
// If non-null the destuctor sets this to true. This is set while the menu is
// showing and used to detect if the menu was deleted while running.
bool* destroyed_flag_;
// The current number of "pressed" locks this button has.
int pressed_lock_count_;
base::WeakPtrFactory<MenuButton> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(MenuButton);
};
} // namespace views
#endif // UI_VIEWS_CONTROLS_BUTTON_MENU_BUTTON_H_
|