electron/shell/browser/ui/autofill_popup.cc

222 lines
6.3 KiB
C++
Raw Normal View History

2017-05-19 19:35:13 +00:00
// 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.
2017-05-19 19:52:18 +00:00
#include <algorithm>
#include <memory>
2017-05-19 19:52:18 +00:00
#include <utility>
#include <vector>
#include "base/i18n/rtl.h"
#include "chrome/browser/ui/autofill/popup_view_common.h"
#include "electron/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "shell/browser/native_window_views.h"
#include "shell/browser/ui/autofill_popup.h"
#include "shell/common/api/api.mojom.h"
2019-06-12 22:08:22 +00:00
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
2017-05-19 19:35:13 +00:00
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_conversions.h"
2017-05-19 19:35:13 +00:00
#include "ui/gfx/geometry/vector2d.h"
2017-05-19 19:52:18 +00:00
#include "ui/gfx/text_utils.h"
2017-05-19 19:35:13 +00:00
#if BUILDFLAG(ENABLE_OSR)
#include "shell/browser/osr/osr_render_widget_host_view.h"
#include "shell/browser/osr/osr_view_proxy.h"
#endif
namespace electron {
2017-05-19 19:35:13 +00:00
class PopupViewCommon : public autofill::PopupViewCommon {
public:
explicit PopupViewCommon(const gfx::Rect& window_bounds)
: window_bounds_(window_bounds) {}
2017-05-19 19:35:13 +00:00
gfx::Rect GetWindowBounds(gfx::NativeView container_view) override {
return window_bounds_;
2017-05-19 19:35:13 +00:00
}
private:
gfx::Rect window_bounds_;
};
2017-05-19 19:35:13 +00:00
AutofillPopup::AutofillPopup() {
2018-04-18 01:55:30 +00:00
bold_font_list_ = gfx::FontList().DeriveWithWeight(gfx::Font::Weight::BOLD);
2017-05-19 19:52:18 +00:00
smaller_font_list_ =
gfx::FontList().DeriveWithSizeDelta(kSmallerFontSizeDelta);
2017-05-19 19:35:13 +00:00
}
AutofillPopup::~AutofillPopup() {
Hide();
}
2018-04-18 01:55:30 +00:00
void AutofillPopup::CreateView(content::RenderFrameHost* frame_host,
content::RenderFrameHost* embedder_frame_host,
2018-04-18 01:55:30 +00:00
bool offscreen,
views::View* parent,
const gfx::RectF& r) {
Hide();
frame_host_ = frame_host;
element_bounds_ = gfx::ToEnclosedRect(r);
2017-05-19 19:52:18 +00:00
gfx::Vector2d height_offset(0, element_bounds_.height());
gfx::Point menu_position(element_bounds_.origin() + height_offset);
views::View::ConvertPointToScreen(parent, &menu_position);
popup_bounds_ = gfx::Rect(menu_position, element_bounds_.size());
parent_ = parent;
parent_->AddObserver(this);
view_ = new AutofillPopupView(this, parent->GetWidget());
2017-05-19 19:52:18 +00:00
#if BUILDFLAG(ENABLE_OSR)
if (offscreen) {
auto* rwhv = frame_host->GetView();
if (embedder_frame_host != nullptr) {
rwhv = embedder_frame_host->GetView();
}
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(rwhv);
view_->view_proxy_ = std::make_unique<OffscreenViewProxy>(view_);
osr_rwhv->AddViewProxy(view_->view_proxy_.get());
}
2017-06-26 09:13:05 +00:00
#endif
// Do this after OSR setup, we check for view_proxy_ when showing
view_->Show();
2017-05-19 19:35:13 +00:00
}
void AutofillPopup::Hide() {
if (parent_) {
parent_->RemoveObserver(this);
parent_ = nullptr;
}
if (view_) {
2017-05-19 19:35:13 +00:00
view_->Hide();
view_ = nullptr;
2017-05-19 19:35:13 +00:00
}
}
void AutofillPopup::SetItems(const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
DCHECK(view_);
2017-05-19 19:35:13 +00:00
values_ = values;
labels_ = labels;
UpdatePopupBounds();
view_->OnSuggestionsChanged();
if (view_) // could be hidden after the change
view_->DoUpdateBoundsAndRedrawPopup();
2017-05-19 19:35:13 +00:00
}
void AutofillPopup::AcceptSuggestion(int index) {
mojo::AssociatedRemote<mojom::ElectronAutofillAgent> autofill_agent;
frame_host_->GetRemoteAssociatedInterfaces()->GetInterface(&autofill_agent);
2019-06-12 22:08:22 +00:00
autofill_agent->AcceptDataListSuggestion(GetValueAt(index));
2017-05-19 19:35:13 +00:00
}
void AutofillPopup::UpdatePopupBounds() {
DCHECK(parent_);
gfx::Point origin(element_bounds_.origin());
views::View::ConvertPointToScreen(parent_, &origin);
gfx::Rect bounds(origin, element_bounds_.size());
gfx::Rect window_bounds = parent_->GetBoundsInScreen();
2018-04-18 01:55:30 +00:00
PopupViewCommon popup_view_common(window_bounds);
popup_bounds_ = popup_view_common.CalculatePopupBounds(
GetDesiredPopupWidth(), GetDesiredPopupHeight(), bounds,
gfx::NativeView(), base::i18n::IsRTL());
2018-05-15 01:59:22 +00:00
}
gfx::Rect AutofillPopup::popup_bounds_in_view() {
gfx::Point origin(popup_bounds_.origin());
views::View::ConvertPointFromScreen(parent_, &origin);
return gfx::Rect(origin, popup_bounds_.size());
}
void AutofillPopup::OnViewBoundsChanged(views::View* view) {
UpdatePopupBounds();
view_->DoUpdateBoundsAndRedrawPopup();
}
void AutofillPopup::OnViewIsDeleting(views::View* view) {
Hide();
2017-05-19 19:35:13 +00:00
}
int AutofillPopup::GetDesiredPopupHeight() {
return 2 * kPopupBorderThickness + values_.size() * kRowHeight;
}
int AutofillPopup::GetDesiredPopupWidth() {
int popup_width = element_bounds_.width();
2017-05-23 09:41:59 +00:00
for (size_t i = 0; i < values_.size(); ++i) {
2018-04-18 01:55:30 +00:00
int row_size =
kEndPadding + 2 * kPopupBorderThickness +
gfx::GetStringWidth(GetValueAt(i), GetValueFontListForRow(i)) +
gfx::GetStringWidth(GetLabelAt(i), GetLabelFontListForRow(i));
2017-05-19 19:52:18 +00:00
if (GetLabelAt(i).length() > 0)
2017-05-19 19:35:13 +00:00
row_size += kNamePadding + kEndPadding;
popup_width = std::max(popup_width, row_size);
}
return popup_width;
}
gfx::Rect AutofillPopup::GetRowBounds(int index) {
int top = kPopupBorderThickness + index * kRowHeight;
return gfx::Rect(kPopupBorderThickness, top,
popup_bounds_.width() - 2 * kPopupBorderThickness,
kRowHeight);
}
const gfx::FontList& AutofillPopup::GetValueFontListForRow(int index) const {
return bold_font_list_;
}
const gfx::FontList& AutofillPopup::GetLabelFontListForRow(int index) const {
return smaller_font_list_;
}
ui::NativeTheme::ColorId AutofillPopup::GetBackgroundColorIDForRow(
int index) const {
return (view_ && index == view_->GetSelectedLine())
2018-04-18 01:55:30 +00:00
? ui::NativeTheme::kColorId_ResultsTableHoveredBackground
: ui::NativeTheme::kColorId_ResultsTableNormalBackground;
2017-05-19 19:35:13 +00:00
}
int AutofillPopup::GetLineCount() {
return values_.size();
}
base::string16 AutofillPopup::GetValueAt(int i) {
return values_.at(i);
}
base::string16 AutofillPopup::GetLabelAt(int i) {
return labels_.at(i);
}
int AutofillPopup::LineFromY(int y) const {
int current_height = kPopupBorderThickness;
2017-05-23 09:41:59 +00:00
for (size_t i = 0; i < values_.size(); ++i) {
2017-05-19 19:35:13 +00:00
current_height += kRowHeight;
if (y <= current_height)
return i;
}
2017-05-19 19:52:18 +00:00
2017-05-19 19:35:13 +00:00
return values_.size() - 1;
}
} // namespace electron