Commit 9c17bce2 authored by Robert Liao's avatar Robert Liao Committed by Commit Bot

Make EditableCombobox Default Constructable

BUG=1108460

Change-Id: Ie5eb700075a15cc1cec52f500831115a161f100c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2364080Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Robert Liao <robliao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799912}
parent 53b382e0
...@@ -334,6 +334,8 @@ component("views") { ...@@ -334,6 +334,8 @@ component("views") {
"controls/button/toggle_button.cc", "controls/button/toggle_button.cc",
"controls/combobox/combobox.cc", "controls/combobox/combobox.cc",
"controls/combobox/combobox_util.cc", "controls/combobox/combobox_util.cc",
"controls/combobox/empty_combobox_model.cc",
"controls/combobox/empty_combobox_model.h",
"controls/editable_combobox/editable_combobox.cc", "controls/editable_combobox/editable_combobox.cc",
"controls/focus_ring.cc", "controls/focus_ring.cc",
"controls/focusable_border.cc", "controls/focusable_border.cc",
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "ui/views/controls/button/button_controller.h" #include "ui/views/controls/button/button_controller.h"
#include "ui/views/controls/combobox/combobox_listener.h" #include "ui/views/controls/combobox/combobox_listener.h"
#include "ui/views/controls/combobox/combobox_util.h" #include "ui/views/controls/combobox/combobox_util.h"
#include "ui/views/controls/combobox/empty_combobox_model.h"
#include "ui/views/controls/focus_ring.h" #include "ui/views/controls/focus_ring.h"
#include "ui/views/controls/focusable_border.h" #include "ui/views/controls/focusable_border.h"
#include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_config.h"
...@@ -51,23 +52,6 @@ namespace { ...@@ -51,23 +52,6 @@ namespace {
// Used to indicate that no item is currently selected by the user. // Used to indicate that no item is currently selected by the user.
constexpr int kNoSelection = -1; constexpr int kNoSelection = -1;
// An empty model for a combo box.
class EmptyComboboxModel final : public ui::ComboboxModel {
public:
EmptyComboboxModel() = default;
EmptyComboboxModel(EmptyComboboxModel&) = delete;
EmptyComboboxModel& operator=(const EmptyComboboxModel&) = delete;
~EmptyComboboxModel() override = default;
// ui::ComboboxModel:
int GetItemCount() const override { return 0; }
base::string16 GetItemAt(int index) const override {
NOTREACHED();
return base::string16();
}
int GetDefaultIndex() const override { return -1; }
};
SkColor GetTextColorForEnableState(const Combobox& combobox, bool enabled) { SkColor GetTextColorForEnableState(const Combobox& combobox, bool enabled) {
const int style = enabled ? style::STYLE_PRIMARY : style::STYLE_DISABLED; const int style = enabled ? style::STYLE_PRIMARY : style::STYLE_DISABLED;
return style::GetColor(combobox, style::CONTEXT_TEXTFIELD, style); return style::GetColor(combobox, style::CONTEXT_TEXTFIELD, style);
...@@ -248,7 +232,7 @@ class Combobox::ComboboxMenuModel : public ui::MenuModel { ...@@ -248,7 +232,7 @@ class Combobox::ComboboxMenuModel : public ui::MenuModel {
// Combobox, public: // Combobox, public:
Combobox::Combobox(int text_context, int text_style) Combobox::Combobox(int text_context, int text_style)
: Combobox(std::make_unique<EmptyComboboxModel>()) {} : Combobox(std::make_unique<internal::EmptyComboboxModel>()) {}
Combobox::Combobox(std::unique_ptr<ui::ComboboxModel> model, Combobox::Combobox(std::unique_ptr<ui::ComboboxModel> model,
int text_context, int text_context,
......
// Copyright 2020 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.
#include "ui/views/controls/combobox/empty_combobox_model.h"
#include "base/notreached.h"
#include "base/strings/string16.h"
namespace views {
namespace internal {
EmptyComboboxModel::EmptyComboboxModel() = default;
EmptyComboboxModel::~EmptyComboboxModel() = default;
int EmptyComboboxModel::GetItemCount() const {
return 0;
}
base::string16 EmptyComboboxModel::GetItemAt(int index) const {
NOTREACHED();
return base::string16();
}
int EmptyComboboxModel::GetDefaultIndex() const {
return -1;
}
} // namespace internal
} // namespace views
// Copyright 2020 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_EMPTY_COMBOBOX_MODEL_H_
#define UI_VIEWS_CONTROLS_COMBOBOX_EMPTY_COMBOBOX_MODEL_H_
#include "ui/base/models/combobox_model.h"
namespace views {
namespace internal {
// An empty model for a combo box.
class EmptyComboboxModel final : public ui::ComboboxModel {
public:
EmptyComboboxModel();
EmptyComboboxModel(EmptyComboboxModel&) = delete;
EmptyComboboxModel& operator=(const EmptyComboboxModel&) = delete;
~EmptyComboboxModel() override;
// ui::ComboboxModel:
int GetItemCount() const override;
base::string16 GetItemAt(int index) const override;
int GetDefaultIndex() const override;
};
} // namespace internal
} // namespace views
#endif // UI_VIEWS_CONTROLS_COMBOBOX_EMPTY_COMBOBOX_MODEL_H_
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "ui/views/controls/button/button.h" #include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/button_controller.h" #include "ui/views/controls/button/button_controller.h"
#include "ui/views/controls/combobox/combobox_util.h" #include "ui/views/controls/combobox/combobox_util.h"
#include "ui/views/controls/combobox/empty_combobox_model.h"
#include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_config.h"
#include "ui/views/controls/menu/menu_runner.h" #include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/menu/menu_types.h" #include "ui/views/controls/menu/menu_types.h"
...@@ -301,6 +302,9 @@ class EditableCombobox::EditableComboboxPreTargetHandler ...@@ -301,6 +302,9 @@ class EditableCombobox::EditableComboboxPreTargetHandler
DISALLOW_COPY_AND_ASSIGN(EditableComboboxPreTargetHandler); DISALLOW_COPY_AND_ASSIGN(EditableComboboxPreTargetHandler);
}; };
EditableCombobox::EditableCombobox()
: EditableCombobox(std::make_unique<internal::EmptyComboboxModel>()) {}
EditableCombobox::EditableCombobox( EditableCombobox::EditableCombobox(
std::unique_ptr<ui::ComboboxModel> combobox_model, std::unique_ptr<ui::ComboboxModel> combobox_model,
const bool filter_on_edit, const bool filter_on_edit,
...@@ -310,16 +314,13 @@ EditableCombobox::EditableCombobox( ...@@ -310,16 +314,13 @@ EditableCombobox::EditableCombobox(
const int text_style, const int text_style,
const bool display_arrow) const bool display_arrow)
: textfield_(new Textfield()), : textfield_(new Textfield()),
combobox_model_(std::move(combobox_model)),
menu_model_(
std::make_unique<EditableComboboxMenuModel>(this,
combobox_model_.get(),
filter_on_edit,
show_on_empty)),
text_context_(text_context), text_context_(text_context),
text_style_(text_style), text_style_(text_style),
type_(type), type_(type),
filter_on_edit_(filter_on_edit),
show_on_empty_(show_on_empty),
showing_password_text_(type != Type::kPassword) { showing_password_text_(type != Type::kPassword) {
SetModel(std::move(combobox_model));
observer_.Add(textfield_); observer_.Add(textfield_);
textfield_->set_controller(this); textfield_->set_controller(this);
textfield_->SetFontList(GetFontList()); textfield_->SetFontList(GetFontList());
...@@ -341,6 +342,13 @@ EditableCombobox::~EditableCombobox() { ...@@ -341,6 +342,13 @@ EditableCombobox::~EditableCombobox() {
textfield_->set_controller(nullptr); textfield_->set_controller(nullptr);
} }
void EditableCombobox::SetModel(std::unique_ptr<ui::ComboboxModel> model) {
CloseMenu();
combobox_model_.swap(model);
menu_model_ = std::make_unique<EditableComboboxMenuModel>(
this, combobox_model_.get(), filter_on_edit_, show_on_empty_);
}
const base::string16& EditableCombobox::GetText() const { const base::string16& EditableCombobox::GetText() const {
return textfield_->GetText(); return textfield_->GetText();
} }
......
...@@ -56,6 +56,8 @@ class VIEWS_EXPORT EditableCombobox ...@@ -56,6 +56,8 @@ class VIEWS_EXPORT EditableCombobox
static constexpr int kDefaultTextContext = style::CONTEXT_BUTTON; static constexpr int kDefaultTextContext = style::CONTEXT_BUTTON;
static constexpr int kDefaultTextStyle = style::STYLE_PRIMARY; static constexpr int kDefaultTextStyle = style::STYLE_PRIMARY;
EditableCombobox();
// |combobox_model|: The ComboboxModel that gives us the items to show in the // |combobox_model|: The ComboboxModel that gives us the items to show in the
// menu. // menu.
// |filter_on_edit|: Whether to only show the items that are case-insensitive // |filter_on_edit|: Whether to only show the items that are case-insensitive
...@@ -66,16 +68,18 @@ class VIEWS_EXPORT EditableCombobox ...@@ -66,16 +68,18 @@ class VIEWS_EXPORT EditableCombobox
// |text_context| and |text_style|: Together these indicate the font to use. // |text_context| and |text_style|: Together these indicate the font to use.
// |display_arrow|: Whether to display an arrow in the combobox to indicate // |display_arrow|: Whether to display an arrow in the combobox to indicate
// that there is a drop-down list. // that there is a drop-down list.
EditableCombobox(std::unique_ptr<ui::ComboboxModel> combobox_model, explicit EditableCombobox(std::unique_ptr<ui::ComboboxModel> combobox_model,
bool filter_on_edit, bool filter_on_edit = false,
bool show_on_empty, bool show_on_empty = true,
Type type = Type::kRegular, Type type = Type::kRegular,
int text_context = kDefaultTextContext, int text_context = kDefaultTextContext,
int text_style = kDefaultTextStyle, int text_style = kDefaultTextStyle,
bool display_arrow = true); bool display_arrow = true);
~EditableCombobox() override; ~EditableCombobox() override;
void SetModel(std::unique_ptr<ui::ComboboxModel> model);
const base::string16& GetText() const; const base::string16& GetText() const;
void SetText(const base::string16& text); void SetText(const base::string16& text);
...@@ -167,6 +171,12 @@ class VIEWS_EXPORT EditableCombobox ...@@ -167,6 +171,12 @@ class VIEWS_EXPORT EditableCombobox
const Type type_; const Type type_;
// Whether to adapt the items shown to the textfield content.
bool filter_on_edit_;
// Whether to show options when the textfield is empty.
bool show_on_empty_;
// Set while the drop-down is showing. // Set while the drop-down is showing.
std::unique_ptr<MenuRunner> menu_runner_; std::unique_ptr<MenuRunner> menu_runner_;
......
...@@ -829,5 +829,67 @@ TEST_F(EditableComboboxTest, NoCrashWithoutWidget) { ...@@ -829,5 +829,67 @@ TEST_F(EditableComboboxTest, NoCrashWithoutWidget) {
combobox->RevealPasswords(true); combobox->RevealPasswords(true);
} }
using EditableComboboxDefaultTest = ViewsTestBase;
class ConfigurableComboboxModel final : public ui::ComboboxModel {
public:
explicit ConfigurableComboboxModel(bool* destroyed = nullptr)
: destroyed_(destroyed) {
if (destroyed_)
*destroyed_ = false;
}
ConfigurableComboboxModel(ConfigurableComboboxModel&) = delete;
ConfigurableComboboxModel& operator=(const ConfigurableComboboxModel&) =
delete;
~ConfigurableComboboxModel() override {
if (destroyed_)
*destroyed_ = true;
}
// ui::ComboboxModel:
int GetItemCount() const override { return item_count_; }
base::string16 GetItemAt(int index) const override {
DCHECK_LT(index, item_count_);
return base::NumberToString16(index);
}
void SetItemCount(int item_count) { item_count_ = item_count; }
private:
bool* const destroyed_;
int item_count_ = 0;
};
} // namespace } // namespace
TEST_F(EditableComboboxDefaultTest, Default) {
auto combobox = std::make_unique<EditableCombobox>();
EXPECT_EQ(0, combobox->GetItemCountForTest());
}
TEST_F(EditableComboboxDefaultTest, SetModel) {
std::unique_ptr<ConfigurableComboboxModel> model =
std::make_unique<ConfigurableComboboxModel>();
model->SetItemCount(42);
auto combobox = std::make_unique<EditableCombobox>();
combobox->SetModel(std::move(model));
EXPECT_EQ(42, combobox->GetItemCountForTest());
}
TEST_F(EditableComboboxDefaultTest, SetModelOverwrite) {
bool destroyed_first = false;
bool destroyed_second = false;
{
auto combobox = std::make_unique<EditableCombobox>();
combobox->SetModel(
std::make_unique<ConfigurableComboboxModel>(&destroyed_first));
ASSERT_FALSE(destroyed_first);
combobox->SetModel(
std::make_unique<ConfigurableComboboxModel>(&destroyed_second));
EXPECT_TRUE(destroyed_first);
ASSERT_FALSE(destroyed_second);
}
EXPECT_TRUE(destroyed_second);
}
} // namespace views } // namespace views
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment