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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
|
// 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_COMBOBOX_COMBOBOX_H_
#define UI_VIEWS_CONTROLS_COMBOBOX_COMBOBOX_H_
#include <string>
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "ui/base/models/combobox_model_observer.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/menu/menu_delegate.h"
#include "ui/views/controls/prefix_delegate.h"
namespace gfx {
class FontList;
class SlideAnimation;
}
namespace ui {
class ComboboxModel;
}
namespace views {
class ComboboxListener;
class ComboboxMenuRunner;
class CustomButton;
class FocusableBorder;
class MenuRunner;
class MenuRunnerHandler;
class Painter;
class PrefixSelector;
// A non-editable combobox (aka a drop-down list or selector).
// Combobox has two distinct parts, the drop down arrow and the text. Combobox
// offers two distinct behaviors:
// * STYLE_NORMAL: typical combobox, clicking on the text and/or button shows
// the drop down, arrow keys change selection, selected index can be changed by
// the user to something other than the first item.
// * STYLE_ACTION: clicking on the text notifies the listener. The menu can be
// shown only by clicking on the arrow. The selected index is always reverted to
// 0 after the listener is notified.
class VIEWS_EXPORT Combobox : public MenuDelegate,
public PrefixDelegate,
public ui::ComboboxModelObserver,
public ButtonListener {
public:
// The style of the combobox.
enum Style {
STYLE_NORMAL,
STYLE_ACTION,
};
// The combobox's class name.
static const char kViewClassName[];
// |model| is not owned by the combobox.
explicit Combobox(ui::ComboboxModel* model);
~Combobox() override;
static const gfx::FontList& GetFontList();
// Sets the listener which will be called when a selection has been made.
void set_listener(ComboboxListener* listener) { listener_ = listener; }
void SetStyle(Style style);
// Informs the combobox that its model changed.
void ModelChanged();
// Gets/Sets the selected index.
int selected_index() const { return selected_index_; }
void SetSelectedIndex(int index);
// Looks for the first occurrence of |value| in |model()|. If found, selects
// the found index and returns true. Otherwise simply noops and returns false.
bool SelectValue(const base::string16& value);
ui::ComboboxModel* model() const { return model_; }
// Set the accessible name of the combobox.
void SetAccessibleName(const base::string16& name);
// Visually marks the combobox as having an invalid value selected.
// When invalid, it paints with white text on a red background.
// Callers are responsible for restoring validity with selection changes.
void SetInvalid(bool invalid);
bool invalid() const { return invalid_; }
// Overridden from View:
gfx::Size GetPreferredSize() const override;
const char* GetClassName() const override;
bool SkipDefaultKeyEventProcessing(const ui::KeyEvent& e) override;
bool OnKeyPressed(const ui::KeyEvent& e) override;
bool OnKeyReleased(const ui::KeyEvent& e) override;
void OnPaint(gfx::Canvas* canvas) override;
void OnFocus() override;
void OnBlur() override;
void GetAccessibleState(ui::AXViewState* state) override;
ui::TextInputClient* GetTextInputClient() override;
void Layout() override;
// Overridden from MenuDelegate:
bool IsItemChecked(int id) const override;
bool IsCommandEnabled(int id) const override;
void ExecuteCommand(int id) override;
bool GetAccelerator(int id, ui::Accelerator* accelerator) const override;
// Overridden from PrefixDelegate:
int GetRowCount() override;
int GetSelectedRow() override;
void SetSelectedRow(int row) override;
base::string16 GetTextForRow(int row) override;
// Overriden from ComboboxModelObserver:
void OnComboboxModelChanged(ui::ComboboxModel* model) override;
// Overriden from ButtonListener:
void ButtonPressed(Button* sender, const ui::Event& event) override;
private:
FRIEND_TEST_ALL_PREFIXES(ComboboxTest, Click);
FRIEND_TEST_ALL_PREFIXES(ComboboxTest, ClickButDisabled);
FRIEND_TEST_ALL_PREFIXES(ComboboxTest, NotifyOnClickWithMouse);
FRIEND_TEST_ALL_PREFIXES(ComboboxTest, ContentWidth);
// Updates the combobox's content from its model.
void UpdateFromModel();
// Updates the border according to the current state.
void UpdateBorder();
// Given bounds within our View, this helper mirrors the bounds if necessary.
void AdjustBoundsForRTLUI(gfx::Rect* rect) const;
// Draws the selected value of the drop down list
void PaintText(gfx::Canvas* canvas);
// Draws the button images.
void PaintButtons(gfx::Canvas* canvas);
// Show the drop down list
void ShowDropDownMenu(ui::MenuSourceType source_type);
// Called when the selection is changed by the user.
void OnPerformAction();
void NotifyPerformAction();
void AfterPerformAction();
// Converts a menu command ID to a menu item index.
int MenuCommandToIndex(int menu_command_id) const;
int GetDisclosureArrowLeftPadding() const;
int GetDisclosureArrowRightPadding() const;
// Returns the size of the disclosure arrow.
gfx::Size ArrowSize() const;
// Handles the clicking event.
void HandleClickEvent();
// Our model. Not owned.
ui::ComboboxModel* model_;
// The visual style of this combobox.
Style style_;
// Our listener. Not owned. Notified when the selected index change.
ComboboxListener* listener_;
// The current selected index; -1 and means no selection.
int selected_index_;
// True when the selection is visually denoted as invalid.
bool invalid_;
// The accessible name of this combobox.
base::string16 accessible_name_;
// A helper used to select entries by keyboard input.
scoped_ptr<PrefixSelector> selector_;
// Responsible for showing the context menu.
scoped_ptr<MenuRunner> dropdown_list_menu_runner_;
// Weak. Owned by dropdown_list_menu_runner_.
MenuItemView* menu_;
// Is the drop down list showing
bool dropdown_open_;
// Like MenuButton, we use a time object in order to keep track of when the
// combobox was closed. The time is used for simulating menu behavior; 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::Time closed_time_;
// The maximum dimensions of the content in the dropdown
mutable gfx::Size content_size_;
// The painters or images that are used when |style_| is STYLE_BUTTONS. The
// first index means the state of unfocused or focused.
// The images are owned by ResourceBundle.
scoped_ptr<Painter> body_button_painters_[2][Button::STATE_COUNT];
std::vector<const gfx::ImageSkia*>
menu_button_images_[2][Button::STATE_COUNT];
// The transparent buttons to handle events and render buttons. These are
// placed on top of this combobox as child views, accept event and manage the
// button states. These are not rendered but when |style_| is
// STYLE_NOTIFY_ON_CLICK, a Combobox renders the button images according to
// these button states.
// The base View takes the ownerships of these as child views.
CustomButton* text_button_;
CustomButton* arrow_button_;
// Used for making calbacks.
base::WeakPtrFactory<Combobox> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(Combobox);
};
} // namespace views
#endif // UI_VIEWS_CONTROLS_COMBOBOX_COMBOBOX_H_
|