diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0032699..02e655cd 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2952,6 +2952,8 @@ "views/location_bar/bubble_icon_view.h", "views/location_bar/content_setting_image_view.cc", "views/location_bar/content_setting_image_view.h", + "views/location_bar/find_bar_icon.cc", + "views/location_bar/find_bar_icon.h", "views/location_bar/icon_label_bubble_view.cc", "views/location_bar/icon_label_bubble_view.h", "views/location_bar/keyword_hint_view.cc",
diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm index ee582f8..ae49cad 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm
@@ -502,6 +502,10 @@ // If the find bar is not visible, make it actually hidden, so it'll no longer // respond to key events. [[self view] setHidden:![self isFindBarVisible]]; + // Notify the FindBarController that the visibility animation has completed in + // order to show or hide a decoration in the location bar. + if (findBarBridge_) + findBarBridge_->GetFindBarController()->FindBarVisibilityChanged(); } - (gfx::Point)findBarWindowPosition {
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h index 326f4a32..2c69f1fa 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
@@ -75,6 +75,7 @@ void UpdateContentSettingsIcons() override; void UpdateManagePasswordsIconAndBubble() override; void UpdateSaveCreditCardIcon() override; + void UpdateFindBarIconVisibility() override; void UpdateBookmarkStarVisibility() override; void UpdateZoomViewVisibility() override; void UpdateLocationBarVisibility(bool visible, bool animate) override;
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm index 08e9f15..43564a6 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
@@ -198,6 +198,11 @@ OnDecorationsChanged(); } +void LocationBarViewMac::UpdateFindBarIconVisibility() { + // TODO(crbug/651643): Implement for mac. + NOTIMPLEMENTED(); +} + void LocationBarViewMac::UpdateBookmarkStarVisibility() { star_decoration_->SetVisible(IsStarEnabled()); }
diff --git a/chrome/browser/ui/find_bar/find_bar_controller.cc b/chrome/browser/ui/find_bar/find_bar_controller.cc index cfacd76..4a48552 100644 --- a/chrome/browser/ui/find_bar/find_bar_controller.cc +++ b/chrome/browser/ui/find_bar/find_bar_controller.cc
@@ -12,10 +12,14 @@ #include "build/build_config.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/find_bar/find_bar_state.h" #include "chrome/browser/ui/find_bar/find_bar_state_factory.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" +#include "chrome/browser/ui/location_bar/location_bar.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_details.h" @@ -81,6 +85,15 @@ } } +void FindBarController::FindBarVisibilityChanged() { + if (web_contents_) { + chrome::FindBrowserWithWebContents(web_contents_) + ->window() + ->GetLocationBar() + ->UpdateFindBarIconVisibility(); + } +} + void FindBarController::ChangeWebContents(WebContents* contents) { if (web_contents_) { registrar_.RemoveAll();
diff --git a/chrome/browser/ui/find_bar/find_bar_controller.h b/chrome/browser/ui/find_bar/find_bar_controller.h index e912a06..ed909f5 100644 --- a/chrome/browser/ui/find_bar/find_bar_controller.h +++ b/chrome/browser/ui/find_bar/find_bar_controller.h
@@ -54,6 +54,9 @@ void EndFindSession(SelectionAction selection_action, ResultAction results_action); + // The visibility of the find bar view changed. + void FindBarVisibilityChanged(); + // Accessor for the attached WebContents. content::WebContents* web_contents() const { return web_contents_; }
diff --git a/chrome/browser/ui/location_bar/location_bar.h b/chrome/browser/ui/location_bar/location_bar.h index 24cd148..6527807 100644 --- a/chrome/browser/ui/location_bar/location_bar.h +++ b/chrome/browser/ui/location_bar/location_bar.h
@@ -52,6 +52,9 @@ // Updates the visibility and toggled state of the save credit card icon. virtual void UpdateSaveCreditCardIcon() = 0; + // Updates the visibility of the find bar image icon. + virtual void UpdateFindBarIconVisibility() = 0; + // Updates the visibility of the bookmark star. virtual void UpdateBookmarkStarVisibility() = 0;
diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc index 311921d..0951d5ed 100644 --- a/chrome/browser/ui/views/find_bar_host.cc +++ b/chrome/browser/ui/views/find_bar_host.cc
@@ -12,11 +12,14 @@ #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/find_bar_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" +#include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/web_contents.h" #include "ui/events/event.h" #include "ui/events/keycodes/keyboard_codes.h" +#include "ui/views/border.h" #include "ui/views/focus/external_focus_tracker.h" #include "ui/views/widget/root_view.h" #include "ui/views/widget/widget.h" @@ -262,6 +265,10 @@ if (widget_bounds.IsEmpty()) return gfx::Rect(); + gfx::Insets insets = + view()->border()->GetInsets() - + gfx::Insets(0, BackgroundWith1PxBorder::kLocationBarBorderThicknessDip); + // Ask the view how large an area it needs to draw on. gfx::Size prefsize = view()->GetPreferredSize(); @@ -274,12 +281,13 @@ return gfx::Rect(); // Place the view in the top right corner of the widget boundaries (top left - // for RTL languages). + // for RTL languages). Adjust for the view insets to ensure the border lines + // up with the location bar. gfx::Rect view_location; - int x = widget_bounds.x(); + int x = widget_bounds.x() - insets.left(); if (!base::i18n::IsRTL()) - x += widget_bounds.width() - prefsize.width(); - int y = widget_bounds.y(); + x += widget_bounds.width() - prefsize.width() + insets.width(); + int y = widget_bounds.y() - insets.top(); view_location.SetRect(x, y, prefsize.width(), prefsize.height()); // When we get Find results back, we specify a selection rect, which we @@ -344,6 +352,8 @@ visible_bounds = host()->GetWindowBoundsInScreen(); browser_view()->immersive_mode_controller()->OnFindBarVisibleBoundsChanged( visible_bounds); + + find_bar_controller_->FindBarVisibilityChanged(); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc index 2236892..482af60 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.cc +++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -15,12 +15,15 @@ #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" #include "chrome/browser/ui/views/download/download_shelf_view.h" #include "chrome/browser/ui/views/exclusive_access_bubble_views.h" +#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h" #include "chrome/browser/ui/views/frame/contents_layout_manager.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" #include "chrome/browser/ui/views/frame/top_container_view.h" #include "chrome/browser/ui/views/infobars/infobar_container_view.h" +#include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" +#include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "components/web_modal/web_contents_modal_dialog_host.h" #include "ui/base/hit_test.h" #include "ui/base/material_design/material_design_controller.h" @@ -201,48 +204,55 @@ } gfx::Rect BrowserViewLayout::GetFindBarBoundingBox() const { - // This function returns the area the Find Bar can be laid out within. This - // basically implies the "user-perceived content area" of the browser - // window excluding the vertical scrollbar. The "user-perceived content area" - // excludes the detached bookmark bar (in the New Tab case) and any infobars - // since they are not _visually_ connected to the Toolbar. + // This function returns the area the Find Bar can be laid out within. When + // the location bar/OmniBox is visible, the bounding box is the area extending + // from the bottom edge of the location bar/OmniBox to the bottom of the + // "user-perceived content area" of the browser window. The width matches the + // width of the location bar/OmniBox. If the location bar/OmniBox is not + // visible, the returned area is the full "user-perceived content area", + // excluding any vertical scrollbar. + // The "user-perceived content area" excludes the detached bookmark bar (in + // the New Tab case) and any infobars since they are not _visually_ connected + // to the Toolbar. - // First determine the bounding box of the content area in Widget - // coordinates. - gfx::Rect bounding_box = contents_container_->ConvertRectToWidget( - contents_container_->GetLocalBounds()); + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_); + LocationBarView* location_bar_view = browser_view->GetLocationBarView(); - gfx::Rect top_container_bounds = top_container_->ConvertRectToWidget( - top_container_->GetLocalBounds()); + // Check for the presence of a visible OmniBox/location bar. + const bool has_location_bar = + browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR) && + location_bar_view && location_bar_view->visible() && + (!immersive_mode_controller_->IsEnabled() || + immersive_mode_controller_->IsRevealed()); - int find_bar_y = 0; - if (immersive_mode_controller_->IsEnabled() && - !immersive_mode_controller_->IsRevealed()) { - // Position the find bar exactly below the top container. In immersive - // fullscreen, when the top-of-window views are not revealed, only the - // miniature immersive style tab strip is visible. Do not overlap the - // find bar and the tab strip. - find_bar_y = top_container_bounds.bottom(); - } else { - // Overlap the find bar atop |top_container_|. - const int kTopOverlap = 6; - find_bar_y = top_container_bounds.bottom() - kTopOverlap; + gfx::Rect bounding_box; + // If the OmniBox/location bar is visible, anchor the find bar bounding box + // to its bottom edge. + if (has_location_bar) { + // The bounding box should be the area right below the OmniBox/location bar. + bounding_box = location_bar_view->ConvertRectToWidget( + location_bar_view->GetLocalBounds()); + bounding_box.Inset(0, location_bar_view->height(), 0, + -contents_container_->height()); + return bounding_box; } - // Grow the height of |bounding_box| by the height of any elements between - // the top container and |contents_container_| such as the detached bookmark - // bar and any infobars. - int height_delta = bounding_box.y() - find_bar_y; - bounding_box.set_y(find_bar_y); - bounding_box.set_height(std::max(0, bounding_box.height() + height_delta)); - - // Finally decrease the width of the bounding box by the width of - // the vertical scroll bar. - int scrollbar_width = gfx::scrollbar_size(); - bounding_box.set_width(std::max(0, bounding_box.width() - scrollbar_width)); + // Otherwise, use the contents container minus any infobars and detached + // bookmark bar from the top and a scrollbar width from the appropriate edge. + bounding_box = contents_container_->ConvertRectToWidget( + contents_container_->GetLocalBounds()); + // Under ChromeOS, the top_container_ may include the title bar for hosted + // apps. Just make sure something of consequence is visible before it's height + // is used. + const int top_container_height = (browser_view->tabstrip()->visible() || + browser_view->toolbar()->visible() || + browser_view->IsBookmarkBarVisible()) + ? top_container_->height() + : 0; if (base::i18n::IsRTL()) - bounding_box.set_x(bounding_box.x() + scrollbar_width); - + bounding_box.Inset(gfx::scrollbar_size(), top_container_height, 0, 0); + else + bounding_box.Inset(0, top_container_height, gfx::scrollbar_size(), 0); return bounding_box; }
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc index 10918a9..c7f8bf1 100644 --- a/chrome/browser/ui/views/frame/browser_view_unittest.cc +++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -242,8 +242,8 @@ // The web contents should be flush with the bottom of the header. EXPECT_EQ(bottom_of_header, contents_container->y()); - // The find bar should overlap the 1px header/web-contents separator at the - // bottom of the header. - EXPECT_LT(browser_view()->GetFindBarBoundingBox().y(), + // The find bar should butt against the 1px header/web-contents separator at + // the bottom of the header. + EXPECT_EQ(browser_view()->GetFindBarBoundingBox().y(), browser_view()->frame()->GetTopInset(false)); }
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.cc b/chrome/browser/ui/views/location_bar/find_bar_icon.cc new file mode 100644 index 0000000..f678839b --- /dev/null +++ b/chrome/browser/ui/views/location_bar/find_bar_icon.cc
@@ -0,0 +1,21 @@ +// Copyright 2017 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 "chrome/browser/ui/views/location_bar/find_bar_icon.h" + +#include "components/toolbar/vector_icons.h" + +FindBarIcon::FindBarIcon() : BubbleIconView(nullptr, 0) {} + +FindBarIcon::~FindBarIcon() {} + +void FindBarIcon::OnExecuting(ExecuteSource execute_source) {} + +views::BubbleDialogDelegateView* FindBarIcon::GetBubble() const { + return nullptr; +} + +const gfx::VectorIcon& FindBarIcon::GetVectorIcon() const { + return toolbar::kFindInPageIcon; +}
diff --git a/chrome/browser/ui/views/location_bar/find_bar_icon.h b/chrome/browser/ui/views/location_bar/find_bar_icon.h new file mode 100644 index 0000000..3380ae2 --- /dev/null +++ b/chrome/browser/ui/views/location_bar/find_bar_icon.h
@@ -0,0 +1,27 @@ +// Copyright 2017 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 CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_FIND_BAR_ICON_H_ +#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_FIND_BAR_ICON_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/views/location_bar/bubble_icon_view.h" + +// The find icon to show when the find bar is visible. +class FindBarIcon : public BubbleIconView { + public: + FindBarIcon(); + ~FindBarIcon() override; + + protected: + // BubbleIconView: + void OnExecuting(ExecuteSource execute_source) override; + views::BubbleDialogDelegateView* GetBubble() const override; + const gfx::VectorIcon& GetVectorIcon() const override; + + private: + DISALLOW_COPY_AND_ASSIGN(FindBarIcon); +}; + +#endif // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_FIND_BAR_ICON_H_
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 3b54c95..24a0034 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -29,6 +29,8 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" +#include "chrome/browser/ui/find_bar/find_bar.h" +#include "chrome/browser/ui/find_bar/find_bar_controller.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/omnibox/chrome_omnibox_client.h" #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" @@ -37,6 +39,7 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h" +#include "chrome/browser/ui/views/location_bar/find_bar_icon.h" #include "chrome/browser/ui/views/location_bar/keyword_hint_view.h" #include "chrome/browser/ui/views/location_bar/location_bar_layout.h" #include "chrome/browser/ui/views/location_bar/location_icon_view.h" @@ -59,6 +62,7 @@ #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_service.h" #include "components/toolbar/toolbar_model.h" +#include "components/toolbar/vector_icons.h" #include "components/translate/core/browser/language_state.h" #include "components/variations/variations_associated_data.h" #include "components/zoom/zoom_controller.h" @@ -112,7 +116,6 @@ using content::WebContents; using views::View; - // LocationBarView ----------------------------------------------------------- // static @@ -224,36 +227,23 @@ AddChildView(image_view); } - zoom_view_ = new ZoomView(delegate_); - zoom_view_->Init(); - AddChildView(zoom_view_); + auto add_icon = [this](BubbleIconView* icon_view) -> void { + icon_view->Init(); + icon_view->SetVisible(false); + AddChildView(icon_view); + }; - manage_passwords_icon_view_ = new ManagePasswordsIconViews(command_updater()); - manage_passwords_icon_view_->Init(); - AddChildView(manage_passwords_icon_view_); - - save_credit_card_icon_view_ = - new autofill::SaveCardIconView(command_updater(), browser_); - save_credit_card_icon_view_->Init(); - save_credit_card_icon_view_->SetVisible(false); - AddChildView(save_credit_card_icon_view_); - - translate_icon_view_ = new TranslateIconView(command_updater()); - translate_icon_view_->Init(); - translate_icon_view_->SetVisible(false); - AddChildView(translate_icon_view_); - + add_icon(zoom_view_ = new ZoomView(delegate_)); + add_icon(manage_passwords_icon_view_ = + new ManagePasswordsIconViews(command_updater())); + add_icon(save_credit_card_icon_view_ = + new autofill::SaveCardIconView(command_updater(), browser_)); + add_icon(translate_icon_view_ = new TranslateIconView(command_updater())); #if defined(OS_CHROMEOS) - intent_picker_view_ = new IntentPickerView(browser_); - intent_picker_view_->Init(); - intent_picker_view_->SetVisible(false); - AddChildView(intent_picker_view_); -#endif // defined(OS_CHROMEOS) - - star_view_ = new StarView(command_updater(), browser_); - star_view_->Init(); - star_view_->SetVisible(false); - AddChildView(star_view_); + add_icon(intent_picker_view_ = new IntentPickerView(browser_)); +#endif + add_icon(find_bar_icon_ = new FindBarIcon()); + add_icon(star_view_ = new StarView(command_updater(), browser_)); clear_all_button_ = views::CreateVectorImageButton(this); clear_all_button_->SetTooltipText( @@ -532,40 +522,28 @@ location_icon_view_); } -#if defined(OS_CHROMEOS) - if (intent_picker_view_->visible()) { - trailing_decorations.AddDecoration(vertical_padding, location_height, - intent_picker_view_); - } -#endif // defined(OS_CHROMEOS) - if (star_view_->visible()) { - trailing_decorations.AddDecoration(vertical_padding, location_height, - star_view_); - } - if (translate_icon_view_->visible()) { - trailing_decorations.AddDecoration(vertical_padding, location_height, - translate_icon_view_); - } - if (save_credit_card_icon_view_->visible()) { - trailing_decorations.AddDecoration(vertical_padding, location_height, - save_credit_card_icon_view_); - } - if (manage_passwords_icon_view_->visible()) { - trailing_decorations.AddDecoration(vertical_padding, location_height, - manage_passwords_icon_view_); - } - if (zoom_view_->visible()) { - trailing_decorations.AddDecoration(vertical_padding, location_height, - zoom_view_); - } - for (ContentSettingViews::const_reverse_iterator i( - content_setting_views_.rbegin()); i != content_setting_views_.rend(); - ++i) { - if ((*i)->visible()) { + auto add_trailing_decoration = [&trailing_decorations, vertical_padding, + location_height, item_padding](View* view) { + if (view->visible()) { trailing_decorations.AddDecoration(vertical_padding, location_height, false, 0, item_padding, item_padding, - *i); + view); } + }; + +#if defined(OS_CHROMEOS) + add_trailing_decoration(intent_picker_view_); +#endif + add_trailing_decoration(star_view_); + add_trailing_decoration(find_bar_icon_); + add_trailing_decoration(translate_icon_view_); + add_trailing_decoration(save_credit_card_icon_view_); + add_trailing_decoration(manage_passwords_icon_view_); + add_trailing_decoration(zoom_view_); + for (ContentSettingViews::const_reverse_iterator i( + content_setting_views_.rbegin()); + i != content_setting_views_.rend(); ++i) { + add_trailing_decoration(*i); } // Because IMEs may eat the tab key, we don't show "press tab to search" while // IME composition is in progress. @@ -578,10 +556,7 @@ keyword_hint_view_->SetKeyword(keyword); } - if (clear_all_button_->visible()) { - trailing_decorations.AddDecoration(vertical_padding, location_height, - clear_all_button_); - } + add_trailing_decoration(clear_all_button_); const int edge_thickness = GetHorizontalEdgeThickness(); @@ -787,6 +762,15 @@ return was_visible != save_credit_card_icon_view_->visible(); } +bool LocationBarView::RefreshFindBarIcon() { + if (!find_bar_icon_) + return false; + const bool was_visible = find_bar_icon_->visible(); + find_bar_icon_->SetVisible( + browser_->GetFindBarController()->find_bar()->IsFindBarVisible()); + return was_visible != find_bar_icon_->visible(); +} + void LocationBarView::RefreshTranslateIcon() { WebContents* web_contents = GetWebContents(); if (!web_contents) @@ -908,6 +892,17 @@ } } +void LocationBarView::UpdateFindBarIconVisibility() { + if (RefreshFindBarIcon()) { + Layout(); + find_bar_icon_->AnimateInkDrop(find_bar_icon_->visible() + ? views::InkDropState::ACTIVATED + : views::InkDropState::HIDDEN, + nullptr); + SchedulePaint(); + } +} + void LocationBarView::UpdateBookmarkStarVisibility() { if (star_view_) { star_view_->SetVisible(
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index cb6aa95..99c28b2 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -32,6 +32,7 @@ class CommandUpdater; class ContentSettingBubbleModelDelegate; class ContentSettingImageView; +class FindBarIcon; class GURL; class IntentPickerView; class KeywordHintView; @@ -277,6 +278,9 @@ // Updates |save_credit_card_icon_view_|. Returns true if visibility changed. bool RefreshSaveCreditCardIconView(); + // Updates |find_bar_icon_|. Returns true if visibility changed. + bool RefreshFindBarIcon(); + // Updates the Translate icon based on the current tab's Translate status. void RefreshTranslateIcon(); @@ -312,6 +316,7 @@ void UpdateContentSettingsIcons() override; void UpdateManagePasswordsIconAndBubble() override; void UpdateSaveCreditCardIcon() override; + void UpdateFindBarIconVisibility() override; void UpdateBookmarkStarVisibility() override; void UpdateZoomViewVisibility() override; void UpdateLocationBarVisibility(bool visible, bool animation) override; @@ -402,6 +407,9 @@ IntentPickerView* intent_picker_view_ = nullptr; #endif // defined(OS_CHROMEOS) + // The icon displayed when the find bar is visible. + FindBarIcon* find_bar_icon_ = nullptr; + // The star for bookmarking. StarView* star_view_ = nullptr;
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index b2f1ab9..62e8428 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -167,6 +167,7 @@ void UpdateContentSettingsIcons() override {} void UpdateManagePasswordsIconAndBubble() override {} void UpdateSaveCreditCardIcon() override {} + void UpdateFindBarIconVisibility() override {} void UpdateBookmarkStarVisibility() override {} void UpdateZoomViewVisibility() override {} void UpdateLocationBarVisibility(bool visible, bool animate) override {}
diff --git a/components/toolbar/BUILD.gn b/components/toolbar/BUILD.gn index 3a9f304a..bbcadbd5 100644 --- a/components/toolbar/BUILD.gn +++ b/components/toolbar/BUILD.gn
@@ -16,6 +16,7 @@ icon_directory = "vector_icons" icons = [ + "find_in_page.icon", "http.1x.icon", "http.icon", "https_invalid.1x.icon",
diff --git a/components/toolbar/vector_icons/find_in_page.icon b/components/toolbar/vector_icons/find_in_page.icon new file mode 100644 index 0000000..15ecfda --- /dev/null +++ b/components/toolbar/vector_icons/find_in_page.icon
@@ -0,0 +1,30 @@ +// Copyright 2017 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. + +CANVAS_DIMENSIONS, 24, +FLIPS_IN_RTL, +MOVE_TO, 20, 19.59f, +V_LINE_TO, 8, +R_LINE_TO, -6, -6, +H_LINE_TO, 6, +R_CUBIC_TO, -1.1f, 0, -1.99f, 0.9f, -1.99f, 2, +LINE_TO, 4, 20, +R_CUBIC_TO, 0, 1.1f, 0.89f, 2, 1.99f, 2, +H_LINE_TO, 18, +R_CUBIC_TO, 0.45f, 0, 0.85f, -0.15f, 1.19f, -0.4f, +R_LINE_TO, -4.43f, -4.43f, +R_CUBIC_TO, -0.8f, 0.52f, -1.74f, 0.83f, -2.76f, 0.83f, +R_CUBIC_TO, -2.76f, 0, -5, -2.24f, -5, -5, +R_CUBIC_TO, 0, -2.76f, 2.24f, -5, 5, -5, +R_CUBIC_TO, 2.76f, 0, 5, 2.24f, 5, 5, +R_CUBIC_TO, 0, 1.02f, -0.31f, 1.96f, -0.83f, 2.75f, +LINE_TO, 20, 19.59f, +CLOSE, +MOVE_TO, 9, 13, +R_CUBIC_TO, 0, 1.66f, 1.34f, 3, 3, 3, +R_CUBIC_TO, 1.66f, 0, 3, -1.34f, 3, -3, +R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3, +R_CUBIC_TO, -1.66f, 0, -3, 1.34f, -3, 3, +CLOSE, +END
diff --git a/content/browser/background_fetch/background_fetch_context.cc b/content/browser/background_fetch/background_fetch_context.cc index 2013efc..2930b8e 100644 --- a/content/browser/background_fetch/background_fetch_context.cc +++ b/content/browser/background_fetch/background_fetch_context.cc
@@ -13,9 +13,9 @@ #include "content/browser/background_fetch/background_fetch_registration_notifier.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/public/browser/background_fetch_delegate.h" -#include "content/public/browser/blob_handle.h" #include "content/public/browser/browser_context.h" #include "net/url_request/url_request_context_getter.h" +#include "storage/browser/blob/blob_data_handle.h" namespace content { @@ -172,7 +172,7 @@ blink::mojom::BackgroundFetchError error, bool background_fetch_succeeded, std::vector<BackgroundFetchSettledFetch> settled_fetches, - std::vector<std::unique_ptr<BlobHandle>> blob_handles) { + std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (error != blink::mojom::BackgroundFetchError::NONE) { @@ -189,24 +189,24 @@ base::Bind(&BackgroundFetchContext::CleanupRegistration, weak_factory_.GetWeakPtr(), registration_id, // The blob uuid is sent as part of |settled_fetches|. Bind - // |blob_handles| to the callback to keep them alive until - // the waitUntil event is resolved. - std::move(blob_handles))); + // |blob_data_handles| to the callback to keep them alive + // until the waitUntil event is resolved. + std::move(blob_data_handles))); } else { event_dispatcher_.DispatchBackgroundFetchFailEvent( registration_id, std::move(settled_fetches), base::Bind(&BackgroundFetchContext::CleanupRegistration, weak_factory_.GetWeakPtr(), registration_id, // The blob uuid is sent as part of |settled_fetches|. Bind - // |blob_handles| to the callback to keep them alive until - // the waitUntil event is resolved. - std::move(blob_handles))); + // |blob_data_handles| to the callback to keep them alive + // until the waitUntil event is resolved. + std::move(blob_data_handles))); } } void BackgroundFetchContext::CleanupRegistration( const BackgroundFetchRegistrationId& registration_id, - const std::vector<std::unique_ptr<BlobHandle>>& blob_handles) { + const std::vector<std::unique_ptr<storage::BlobDataHandle>>& blob_handles) { DCHECK_CURRENTLY_ON(BrowserThread::IO); // If we had an active JobController, it is no longer necessary, as the
diff --git a/content/browser/background_fetch/background_fetch_context.h b/content/browser/background_fetch/background_fetch_context.h index b6ccbd6..ba8bea397 100644 --- a/content/browser/background_fetch/background_fetch_context.h +++ b/content/browser/background_fetch/background_fetch_context.h
@@ -20,13 +20,16 @@ #include "content/public/browser/browser_thread.h" #include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h" +namespace storage { +class BlobDataHandle; +} + namespace content { class BackgroundFetchJobController; struct BackgroundFetchOptions; class BackgroundFetchRegistrationId; class BackgroundFetchRegistrationNotifier; -class BlobHandle; class BrowserContext; class ServiceWorkerContextWrapper; struct ServiceWorkerFetchRequest; @@ -111,14 +114,15 @@ blink::mojom::BackgroundFetchError error, bool background_fetch_succeeded, std::vector<BackgroundFetchSettledFetch> settled_fetches, - std::vector<std::unique_ptr<BlobHandle>> blob_handles); + std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles); // Called when all processing for the |registration_id| has been finished and // the job is ready to be deleted. |blob_handles| are unused, but some callers // use it to keep blobs alive for the right duration. void CleanupRegistration( const BackgroundFetchRegistrationId& registration_id, - const std::vector<std::unique_ptr<BlobHandle>>& blob_handles); + const std::vector<std::unique_ptr<storage::BlobDataHandle>>& + blob_data_handles); // Called when the last JavaScript BackgroundFetchRegistration object has been // garbage collected for a registration marked for deletion, and so it is now
diff --git a/content/browser/background_fetch/background_fetch_data_manager.cc b/content/browser/background_fetch/background_fetch_data_manager.cc index 9d6ac2ee..32eed21c8 100644 --- a/content/browser/background_fetch/background_fetch_data_manager.cc +++ b/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/containers/flat_set.h" #include "base/containers/queue.h" +#include "base/guid.h" #include "base/memory/ptr_util.h" #include "base/numerics/checked_math.h" #include "base/strings/string_number_conversions.h" @@ -21,13 +22,17 @@ #include "content/browser/background_fetch/background_fetch_request_info.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" -#include "content/public/browser/blob_handle.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_interrupt_reasons.h" #include "content/public/browser/download_item.h" +#include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "services/network/public/interfaces/fetch_api.mojom.h" +#include "storage/browser/blob/blob_data_builder.h" +#include "storage/browser/blob/blob_impl.h" +#include "storage/browser/blob/blob_storage_context.h" +#include "third_party/WebKit/common/blob/blob.mojom.h" // Service Worker DB UserData schema // ================================= @@ -1039,7 +1044,7 @@ std::vector<BackgroundFetchSettledFetch> settled_fetches; settled_fetches.reserve(requests.size()); - std::vector<std::unique_ptr<BlobHandle>> blob_handles; + std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles; for (const auto& request : requests) { BackgroundFetchSettledFetch settled_fetch; @@ -1063,17 +1068,32 @@ if (request->GetFileSize() > 0) { DCHECK(!request->GetFilePath().empty()); - std::unique_ptr<BlobHandle> blob_handle = - blob_storage_context_->CreateFileBackedBlob( - request->GetFilePath(), 0 /* offset */, request->GetFileSize(), - base::Time() /* expected_modification_time */); + DCHECK(blob_storage_context_); - // TODO(peter): Appropriately handle !blob_handle - if (blob_handle) { - settled_fetch.response.blob_uuid = blob_handle->GetUUID(); - settled_fetch.response.blob_size = request->GetFileSize(); + storage::BlobDataBuilder blob_builder(base::GenerateGUID()); + blob_builder.AppendFile(request->GetFilePath(), 0 /* offset */, + request->GetFileSize(), + base::Time() /* expected_modification_time */); - blob_handles.push_back(std::move(blob_handle)); + auto blob_data_handle = + GetBlobStorageContext(blob_storage_context_.get()) + ->AddFinishedBlob(&blob_builder); + + // TODO(peter): Appropriately handle !blob_data_handle + if (blob_data_handle) { + settled_fetch.response.blob_uuid = blob_data_handle->uuid(); + settled_fetch.response.blob_size = blob_data_handle->size(); + if (features::IsMojoBlobsEnabled()) { + blink::mojom::BlobPtr blob_ptr; + storage::BlobImpl::Create( + std::make_unique<storage::BlobDataHandle>(*blob_data_handle), + MakeRequest(&blob_ptr)); + + settled_fetch.response.blob = + base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr)); + } + + blob_data_handles.push_back(std::move(blob_data_handle)); } } } else { @@ -1091,9 +1111,9 @@ settled_fetches.push_back(settled_fetch); } - std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE, - background_fetch_succeeded, - std::move(settled_fetches), std::move(blob_handles)); + std::move(callback).Run( + blink::mojom::BackgroundFetchError::NONE, background_fetch_succeeded, + std::move(settled_fetches), std::move(blob_data_handles)); } void BackgroundFetchDataManager::MarkRegistrationForDeletion(
diff --git a/content/browser/background_fetch/background_fetch_data_manager.h b/content/browser/background_fetch/background_fetch_data_manager.h index 57b8949..2ac4954 100644 --- a/content/browser/background_fetch/background_fetch_data_manager.h +++ b/content/browser/background_fetch/background_fetch_data_manager.h
@@ -22,11 +22,14 @@ #include "third_party/WebKit/public/platform/modules/background_fetch/background_fetch.mojom.h" #include "url/origin.h" +namespace storage { +class BlobDataHandle; +} + namespace content { class BackgroundFetchRequestInfo; struct BackgroundFetchSettledFetch; -class BlobHandle; class BrowserContext; class ChromeBlobStorageContext; class ServiceWorkerContextWrapper; @@ -48,11 +51,11 @@ base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>; using MarkedCompleteCallback = base::OnceCallback<void(bool /* has_pending_or_active_requests */)>; - using SettledFetchesCallback = - base::OnceCallback<void(blink::mojom::BackgroundFetchError, - bool /* background_fetch_succeeded */, - std::vector<BackgroundFetchSettledFetch>, - std::vector<std::unique_ptr<BlobHandle>>)>; + using SettledFetchesCallback = base::OnceCallback<void( + blink::mojom::BackgroundFetchError, + bool /* background_fetch_succeeded */, + std::vector<BackgroundFetchSettledFetch>, + std::vector<std::unique_ptr<storage::BlobDataHandle>>)>; // Note that this also handles non-error cases where the NONE is NONE. using HandleBackgroundFetchErrorCallback = base::OnceCallback<void(blink::mojom::BackgroundFetchError)>;
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.cc b/content/renderer/service_worker/web_service_worker_registration_impl.cc index e1f3688..8b036df 100644 --- a/content/renderer/service_worker/web_service_worker_registration_impl.cc +++ b/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -418,6 +418,10 @@ std::move(active))); return; } + + if (state_ == LifecycleState::kDetached) + return; + DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); ServiceWorkerDispatcher* dispatcher = ServiceWorkerDispatcher::GetThreadSpecificInstance(); DCHECK(dispatcher);
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.h b/third_party/WebKit/Source/platform/WebTaskRunner.h index 0982c5a..027cd82 100644 --- a/third_party/WebKit/Source/platform/WebTaskRunner.h +++ b/third_party/WebKit/Source/platform/WebTaskRunner.h
@@ -59,19 +59,6 @@ // with this call. virtual bool RunsTasksInCurrentSequence() = 0; - // --- - - // Headless Chrome virtualises time for determinism and performance (fast - // forwarding of timers). To make this work some parts of blink (e.g. Timers) - // need to use virtual time, however by default new code should use the normal - // non-virtual time APIs. - - // Returns a double which is the number of seconds since epoch (Jan 1, 1970). - // This may represent either the real time, or a virtual time depending on - // whether or not the WebTaskRunner is associated with a virtual time domain - // or a real time domain. - virtual double VirtualTimeSeconds() const = 0; - // Returns a microsecond resolution platform dependant time source. // This may represent either the real time, or a virtual time depending on // whether or not the WebTaskRunner is associated with a virtual time domain
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc index d918f88..07a8af9 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.cc
@@ -26,10 +26,6 @@ return task_queue_->RunsTasksInCurrentSequence(); } -double WebTaskRunnerImpl::VirtualTimeSeconds() const { - return (Now() - base::TimeTicks::UnixEpoch()).InSecondsF(); -} - double WebTaskRunnerImpl::MonotonicallyIncreasingVirtualTimeSeconds() const { return Now().ToInternalValue() / static_cast<double>(base::Time::kMicrosecondsPerSecond);
diff --git a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h index 0fac5c3..50b23fc 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/child/web_task_runner_impl.h
@@ -28,7 +28,6 @@ // WebTaskRunner implementation: bool RunsTasksInCurrentSequence() override; - double VirtualTimeSeconds() const override; double MonotonicallyIncreasingVirtualTimeSeconds() const override; scoped_refptr<base::SingleThreadTaskRunner> ToSingleThreadTaskRunner() override;
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc index fb6510d..e10eb67c 100644 --- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc +++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.cc
@@ -88,10 +88,6 @@ return true; } -double FakeWebTaskRunner::VirtualTimeSeconds() const { - return data_->time_; -} - double FakeWebTaskRunner::MonotonicallyIncreasingVirtualTimeSeconds() const { return data_->time_; }
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h index 6dabdc6a..43cb11b 100644 --- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h +++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_task_runner.h
@@ -25,7 +25,6 @@ // WebTaskRunner implementation: bool RunsTasksInCurrentSequence() override; - double VirtualTimeSeconds() const override; double MonotonicallyIncreasingVirtualTimeSeconds() const override; SingleThreadTaskRunnerRefPtr ToSingleThreadTaskRunner() override;
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py index 8bab466a..1dede1d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -470,15 +470,8 @@ description += 'Build: %s\n\n' % build_link description += ( - 'Note to sheriffs: This CL imports external tests and adds\n' - 'expectations for those tests; if this CL is large and causes\n' - 'a few new failures, please fix the failures by adding new\n' - 'lines to TestExpectations rather than reverting. See:\n' - 'https://chromium.googlesource.com' - '/chromium/src/+/master/docs/testing/web_platform_tests.md\n\n') - - if directory_owners: - description += self._format_directory_owners(directory_owners) + '\n\n' + 'Note to sheriffs: This is an automatically-generated CL. Please\n' + 'contact ecosystem-infra@chromium.org in case of problems.\n\n') # Move any No-Export tag to the end of the description. description = description.replace('No-Export: true', '')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py index 0015fc6..44d891c 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
@@ -4,6 +4,7 @@ import datetime import json +import unittest from webkitpy.common.checkout.git_mock import MockGit from webkitpy.common.host_mock import MockHost @@ -267,12 +268,8 @@ self.assertEqual( description, 'Last commit message\n\n' - 'Note to sheriffs: This CL imports external tests and adds\n' - 'expectations for those tests; if this CL is large and causes\n' - 'a few new failures, please fix the failures by adding new\n' - 'lines to TestExpectations rather than reverting. See:\n' - 'https://chromium.googlesource.com' - '/chromium/src/+/master/docs/testing/web_platform_tests.md\n\n' + 'Note to sheriffs: This is an automatically-generated CL. Please\n' + 'contact ecosystem-infra@chromium.org in case of problems.\n\n' 'No-Export: true') self.assertEqual(host.executive.calls, [['git', 'log', '-1', '--format=%B']]) @@ -298,6 +295,7 @@ 'No-Export: true', description) + @unittest.skip("http://crbug.com/780055") def test_cl_description_with_directory_owners(self): host = MockHost() host.executive = MockExecutive(output='Last commit message\n\n')
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 25da3e5..d0f94bcb 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -583,7 +583,7 @@ Source of the autoplay attempt: 0 for attribute; 1 for play(). </summary> </metric> - <metric name="UserGestureRequirement"> + <metric name="UserGestureRequired"> <summary> Whether a user gesture was required per autoplay rules at the time of attempt. By definition there is no user gesture on the stack when the
diff --git a/ui/views/controls/tree/tree_view.cc b/ui/views/controls/tree/tree_view.cc index 48bcccf..017273bf 100644 --- a/ui/views/controls/tree/tree_view.cc +++ b/ui/views/controls/tree/tree_view.cc
@@ -711,9 +711,10 @@ if (!model_) return; - preferred_size_.SetSize(root_.GetMaxWidth(text_offset_, root_shown_ ? 1 : 0) + - kTextHorizontalPadding * 2, - row_height_ * GetRowCount()); + preferred_size_.SetSize( + root_.GetMaxWidth(this, text_offset_, root_shown_ ? 1 : 0) + + kTextHorizontalPadding * 2, + row_height_ * GetRowCount()); } void TreeView::LayoutEditor() { @@ -780,24 +781,8 @@ if (model_->GetChildCount(node->model_node())) PaintExpandControl(canvas, bounds, node->is_expanded()); - // Paint the icon. - gfx::ImageSkia icon; - int icon_index = model_->GetIconIndex(node->model_node()); - if (icon_index != -1) - icon = icons_[icon_index]; - else if (node == selected_node_) - icon = open_icon_; - else - icon = closed_icon_; - int icon_x = kArrowRegionSize + kImagePadding + - (open_icon_.width() - icon.width()) / 2; - if (base::i18n::IsRTL()) - icon_x = bounds.right() - icon_x - open_icon_.width(); - else - icon_x += bounds.x(); - canvas->DrawImageInt( - icon, icon_x, - bounds.y() + (bounds.height() - icon.height()) / 2); + if (drawing_provider()->ShouldDrawIconForNode(this, node->model_node())) + PaintNodeIcon(canvas, node, bounds); // Paint the text background and text. In edit mode, the selected node is a // separate editing control, so it does not need to be painted here. @@ -863,6 +848,27 @@ arrow_bounds.y()); } +void TreeView::PaintNodeIcon(gfx::Canvas* canvas, + InternalNode* node, + const gfx::Rect& bounds) { + gfx::ImageSkia icon; + int icon_index = model_->GetIconIndex(node->model_node()); + if (icon_index != -1) + icon = icons_[icon_index]; + else if (node == selected_node_) + icon = open_icon_; + else + icon = closed_icon_; + int icon_x = kArrowRegionSize + kImagePadding + + (open_icon_.width() - icon.width()) / 2; + if (base::i18n::IsRTL()) + icon_x = bounds.right() - icon_x - open_icon_.width(); + else + icon_x += bounds.x(); + canvas->DrawImageInt(icon, icon_x, + bounds.y() + (bounds.height() - icon.height()) / 2); +} + TreeView::InternalNode* TreeView::GetInternalNodeForModelNode( ui::TreeModelNode* model_node, GetInternalNodeCreateType create_type) { @@ -902,7 +908,10 @@ gfx::Rect TreeView::GetTextBoundsForNode(InternalNode* node) { gfx::Rect bounds(GetForegroundBoundsForNode(node)); - bounds.Inset(text_offset_, 0, 0, 0); + if (drawing_provider()->ShouldDrawIconForNode(this, node->model_node())) + bounds.Inset(text_offset_, 0, 0, 0); + else + bounds.Inset(kArrowRegionSize, 0, 0, 0); return bounds; } @@ -1129,13 +1138,14 @@ return result; } -int TreeView::InternalNode::GetMaxWidth(int indent, int depth) { - int max_width = text_width_ + indent * depth; +int TreeView::InternalNode::GetMaxWidth(TreeView* tree, int indent, int depth) { + bool has_icon = tree->drawing_provider()->ShouldDrawIconForNode(tree, this); + int max_width = (has_icon ? text_width_ : kArrowRegionSize) + indent * depth; if (!is_expanded_) return max_width; for (int i = 0; i < child_count(); ++i) { - max_width = std::max(max_width, - GetChild(i)->GetMaxWidth(indent, depth + 1)); + max_width = + std::max(max_width, GetChild(i)->GetMaxWidth(tree, indent, depth + 1)); } return max_width; }
diff --git a/ui/views/controls/tree/tree_view.h b/ui/views/controls/tree/tree_view.h index 11cb38f..2ab62a6b 100644 --- a/ui/views/controls/tree/tree_view.h +++ b/ui/views/controls/tree/tree_view.h
@@ -212,8 +212,9 @@ // Returns the max width of all descendants (including this node). |indent| // is how many pixels each child is indented and |depth| is the depth of - // this node from its parent. - int GetMaxWidth(int indent, int depth); + // this node from its parent. The tree this node is being placed inside is + // |tree|. + int GetMaxWidth(TreeView* tree, int indent, int depth); private: // The node from the model. @@ -297,6 +298,11 @@ const gfx::Rect& node_bounds, bool expanded); + // Paints the icon for the specified |node| in |bounds| to |canvas|. + void PaintNodeIcon(gfx::Canvas* canvas, + InternalNode* node, + const gfx::Rect& bounds); + // Returns the InternalNode for a model node. |create_type| indicates wheter // this should load InternalNode or not. InternalNode* GetInternalNodeForModelNode(
diff --git a/ui/views/controls/tree/tree_view_drawing_provider.cc b/ui/views/controls/tree/tree_view_drawing_provider.cc index cde3a4bd..a1f6249 100644 --- a/ui/views/controls/tree/tree_view_drawing_provider.cc +++ b/ui/views/controls/tree/tree_view_drawing_provider.cc
@@ -40,4 +40,9 @@ return base::string16(); } +bool TreeViewDrawingProvider::ShouldDrawIconForNode(TreeView* tree_view, + ui::TreeModelNode* node) { + return true; +} + } // namespace views
diff --git a/ui/views/controls/tree/tree_view_drawing_provider.h b/ui/views/controls/tree/tree_view_drawing_provider.h index 49a8a5e..a463581 100644 --- a/ui/views/controls/tree/tree_view_drawing_provider.h +++ b/ui/views/controls/tree/tree_view_drawing_provider.h
@@ -36,6 +36,10 @@ // of the node's row in the treeview. virtual base::string16 GetAuxiliaryTextForNode(TreeView* tree_view, ui::TreeModelNode* node); + + // This method returns whether the icon for |node| should be drawn. + virtual bool ShouldDrawIconForNode(TreeView* tree_view, + ui::TreeModelNode* node); }; } // namespace views
diff --git a/ui/views/examples/tree_view_example.cc b/ui/views/examples/tree_view_example.cc index b8eff39..061cbef 100644 --- a/ui/views/examples/tree_view_example.cc +++ b/ui/views/examples/tree_view_example.cc
@@ -29,6 +29,11 @@ return views::TreeViewDrawingProvider::GetAuxiliaryTextForNode(tree_view, node); } + + bool ShouldDrawIconForNode(views::TreeView* tree_view, + ui::TreeModelNode* node) override { + return tree_view->GetSelectedNode() != node; + } }; } // namespace