diff options
author | gbillock@chromium.org <gbillock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-28 19:11:33 +0000 |
---|---|---|
committer | gbillock@chromium.org <gbillock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-28 19:11:33 +0000 |
commit | 3cfe937422ac6bb8f8be1a8d95d15ddb3469736f (patch) | |
tree | 06a78afd287f644fecf861922e058a49fdf9f842 | |
parent | beb9510bf34133c1a053bee977dc283353f9a86e (diff) | |
download | chromium_src-3cfe937422ac6bb8f8be1a8d95d15ddb3469736f.zip chromium_src-3cfe937422ac6bb8f8be1a8d95d15ddb3469736f.tar.gz chromium_src-3cfe937422ac6bb8f8be1a8d95d15ddb3469736f.tar.bz2 |
[OriginChip] Add animations for the hiding and showing of the chip.
Also moves some logic into the platform-independent OmniboxEditController. Future work may be able to move more code into this class for sharing across platforms.
BUG=338563
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=259639
R=pkasting@chromium.org
Review URL: https://codereview.chromium.org/200783003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260228 0039d316-1c4b-4281-b951-d872f2087c98
24 files changed, 345 insertions, 44 deletions
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 f50b1bf..6130583 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 @@ -150,6 +150,7 @@ class LocationBarViewMac : public LocationBar, virtual void Update(const content::WebContents* contents) OVERRIDE; virtual void OnChanged() OVERRIDE; virtual void OnSetFocus() OVERRIDE; + virtual void ShowURL() OVERRIDE; virtual InstantController* GetInstant() OVERRIDE; virtual content::WebContents* GetWebContents() OVERRIDE; virtual ToolbarModel* GetToolbarModel() OVERRIDE; @@ -174,6 +175,10 @@ class LocationBarViewMac : public LocationBar, // Activates the page action for the extension that has the given id. void ActivatePageAction(const std::string& extension_id); + protected: + // OmniboxEditController: + virtual void HideURL() OVERRIDE; + private: friend ZoomDecorationTest; 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 cb26752..ba5ad5f 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 @@ -570,6 +570,14 @@ void LocationBarViewMac::OnSetFocus() { OnChanged(); } +void LocationBarViewMac::ShowURL() { + omnibox_view_->ShowURL(); +} + +void LocationBarViewMac::HideURL() { + omnibox_view_->HideURL(); +} + InstantController* LocationBarViewMac::GetInstant() { return browser_->instant_controller() ? browser_->instant_controller()->instant() : NULL; diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm index 3a3b8d7..6b1416f 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac_unittest.mm @@ -89,10 +89,13 @@ class TestingOmniboxEditController : public OmniboxEditController { } virtual ~TestingOmniboxEditController() {} + protected: // Overridden from OmniboxEditController: virtual void Update(const content::WebContents* contents) OVERRIDE {} virtual void OnChanged() OVERRIDE {} virtual void OnSetFocus() OVERRIDE {} + virtual void ShowURL() OVERRIDE {} + virtual void HideURL() OVERRIDE {} virtual InstantController* GetInstant() OVERRIDE { return NULL; } virtual content::WebContents* GetWebContents() OVERRIDE { return NULL; } virtual ToolbarModel* GetToolbarModel() OVERRIDE { return toolbar_model_; } diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.cc b/chrome/browser/ui/gtk/location_bar_view_gtk.cc index dde1ff7..e8fa487 100644 --- a/chrome/browser/ui/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/ui/gtk/location_bar_view_gtk.cc @@ -635,6 +635,10 @@ void LocationBarViewGtk::OnSetFocus() { OnChanged(); } +void LocationBarViewGtk::ShowURL() { + omnibox_view_->ShowURL(); +} + InstantController* LocationBarViewGtk::GetInstant() { return browser_->instant_controller() ? browser_->instant_controller()->instant() : NULL; @@ -1571,6 +1575,10 @@ bool LocationBarViewGtk::ShouldOnlyShowLocation() { return !browser_->is_type_tabbed(); } +void LocationBarViewGtk::HideURL() { + omnibox_view_->HideURL(); +} + //////////////////////////////////////////////////////////////////////////////// // LocationBarViewGtk::PageToolViewGtk diff --git a/chrome/browser/ui/gtk/location_bar_view_gtk.h b/chrome/browser/ui/gtk/location_bar_view_gtk.h index 6150409..0de4e02 100644 --- a/chrome/browser/ui/gtk/location_bar_view_gtk.h +++ b/chrome/browser/ui/gtk/location_bar_view_gtk.h @@ -112,6 +112,7 @@ class LocationBarViewGtk : public OmniboxEditController, virtual void Update(const content::WebContents* contents) OVERRIDE; virtual void OnChanged() OVERRIDE; virtual void OnSetFocus() OVERRIDE; + virtual void ShowURL() OVERRIDE; virtual InstantController* GetInstant() OVERRIDE; virtual content::WebContents* GetWebContents() OVERRIDE; virtual ToolbarModel* GetToolbarModel() OVERRIDE; @@ -211,6 +212,9 @@ class LocationBarViewGtk : public OmniboxEditController, }; private: + // OmniboxEditController: + virtual void HideURL() OVERRIDE; + class PageActionViewGtk : public ExtensionActionIconFactory::Observer, public content::NotificationObserver, diff --git a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk_unittest.cc b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk_unittest.cc index 11a2a25..1b2bd5e 100644 --- a/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk_unittest.cc +++ b/chrome/browser/ui/gtk/omnibox/omnibox_view_gtk_unittest.cc @@ -26,10 +26,12 @@ class OmniboxEditControllerMock : public OmniboxEditController { MOCK_METHOD1(Update, void(const content::WebContents* contents)); MOCK_METHOD0(OnChanged, void()); MOCK_METHOD0(OnSetFocus, void()); + MOCK_METHOD0(ShowURL, void()); MOCK_METHOD0(GetInstant, InstantController*()); MOCK_METHOD0(GetWebContents, content::WebContents*()); MOCK_METHOD0(GetToolbarModel, ToolbarModel*()); MOCK_CONST_METHOD0(GetToolbarModel, ToolbarModel*()); + MOCK_METHOD0(HideURL, void()); }; } // namespace diff --git a/chrome/browser/ui/omnibox/omnibox_edit_controller.cc b/chrome/browser/ui/omnibox/omnibox_edit_controller.cc index 43987fc..05d01bb 100644 --- a/chrome/browser/ui/omnibox/omnibox_edit_controller.cc +++ b/chrome/browser/ui/omnibox/omnibox_edit_controller.cc @@ -6,6 +6,7 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/command_updater.h" +#include "chrome/browser/ui/toolbar/toolbar_model.h" void OmniboxEditController::OnAutocompleteAccept( const GURL& destination_url, @@ -26,5 +27,21 @@ OmniboxEditController::OmniboxEditController(CommandUpdater* command_updater) content::PAGE_TRANSITION_FROM_ADDRESS_BAR)) { } +void OmniboxEditController::HideOriginChip() { + GetToolbarModel()->set_origin_chip_enabled(false); + OnChanged(); +} + +void OmniboxEditController::ShowOriginChip() { + // If URL replacement is still enabled, we can simply show the chip. If it + // was disabled by an action to show the URL then the URL needs to be hidden. + if (GetToolbarModel()->url_replacement_enabled()) { + GetToolbarModel()->set_origin_chip_enabled(true); + OnChanged(); + } else { + HideURL(); + } +} + OmniboxEditController::~OmniboxEditController() { } diff --git a/chrome/browser/ui/omnibox/omnibox_edit_controller.h b/chrome/browser/ui/omnibox/omnibox_edit_controller.h index 2757210..9b9f08e 100644 --- a/chrome/browser/ui/omnibox/omnibox_edit_controller.h +++ b/chrome/browser/ui/omnibox/omnibox_edit_controller.h @@ -44,6 +44,16 @@ class OmniboxEditController { // Called whenever the autocomplete edit gets focused. virtual void OnSetFocus() = 0; + // Hides the origin chip and shows the URL. + virtual void ShowURL() = 0; + + // Hides the origin chip while leaving the Omnibox empty. + void HideOriginChip(); + + // Shows the origin chip. Hides the URL if it was previously shown by a call + // to ShowURL(). + void ShowOriginChip(); + // Returns the InstantController, or NULL if instant is not enabled. virtual InstantController* GetInstant() = 0; @@ -57,6 +67,9 @@ class OmniboxEditController { explicit OmniboxEditController(CommandUpdater* command_updater); virtual ~OmniboxEditController(); + // Hides the URL and shows the origin chip. + virtual void HideURL() = 0; + CommandUpdater* command_updater() { return command_updater_; } GURL destination_url() const { return destination_url_; } WindowOpenDisposition disposition() const { return disposition_; } diff --git a/chrome/browser/ui/omnibox/omnibox_edit_unittest.cc b/chrome/browser/ui/omnibox/omnibox_edit_unittest.cc index 6115ad7..7d27472 100644 --- a/chrome/browser/ui/omnibox/omnibox_edit_unittest.cc +++ b/chrome/browser/ui/omnibox/omnibox_edit_unittest.cc @@ -105,10 +105,13 @@ class TestingOmniboxEditController : public OmniboxEditController { toolbar_model_(toolbar_model) { } + protected: // OmniboxEditController: virtual void Update(const content::WebContents* contents) OVERRIDE {} virtual void OnChanged() OVERRIDE {} virtual void OnSetFocus() OVERRIDE {} + virtual void ShowURL() OVERRIDE {} + virtual void HideURL() OVERRIDE {} virtual InstantController* GetInstant() OVERRIDE { return NULL; } virtual WebContents* GetWebContents() OVERRIDE { return NULL; } virtual ToolbarModel* GetToolbarModel() OVERRIDE { return toolbar_model_; } diff --git a/chrome/browser/ui/omnibox/omnibox_view.cc b/chrome/browser/ui/omnibox/omnibox_view.cc index b39fe9f..ecd98b3 100644 --- a/chrome/browser/ui/omnibox/omnibox_view.cc +++ b/chrome/browser/ui/omnibox/omnibox_view.cc @@ -93,23 +93,14 @@ void OmniboxView::HandleOriginChipMouseRelease() { if ((chrome::GetOriginChipV2HideTrigger() == chrome::ORIGIN_CHIP_V2_HIDE_ON_MOUSE_RELEASE) && controller()->GetToolbarModel()->GetText().empty()) { - controller()->GetToolbarModel()->set_origin_chip_enabled(false); - controller()->OnChanged(); + controller()->HideOriginChip(); } } void OmniboxView::OnDidKillFocus() { - // If user input is not in progress, re-enable the origin chip and URL - // replacement. This addresses the case where the URL was shown by a call - // to ShowURL(). If the Omnibox achieved focus by other means, the calls to - // set_url_replacement_enabled, UpdatePermanentText and RevertAll are not - // required (a call to OnChanged would be sufficient) but do no harm. if (chrome::ShouldDisplayOriginChipV2() && !model()->user_input_in_progress()) { - controller()->GetToolbarModel()->set_origin_chip_enabled(true); - controller()->GetToolbarModel()->set_url_replacement_enabled(true); - model()->UpdatePermanentText(); - RevertAll(); + controller()->ShowOriginChip(); } } @@ -179,6 +170,13 @@ void OmniboxView::ShowURL() { SelectAll(true); } +void OmniboxView::HideURL() { + controller_->GetToolbarModel()->set_origin_chip_enabled(true); + controller_->GetToolbarModel()->set_url_replacement_enabled(true); + model_->UpdatePermanentText(); + RevertWithoutResettingSearchTermReplacement(); +} + void OmniboxView::RevertAll() { controller_->GetToolbarModel()->set_url_replacement_enabled(true); RevertWithoutResettingSearchTermReplacement(); diff --git a/chrome/browser/ui/omnibox/omnibox_view.h b/chrome/browser/ui/omnibox/omnibox_view.h index 6e538a7..3463440 100644 --- a/chrome/browser/ui/omnibox/omnibox_view.h +++ b/chrome/browser/ui/omnibox/omnibox_view.h @@ -137,6 +137,9 @@ class OmniboxView { // selects all. void ShowURL(); + // Enables search term replacement and reverts the omnibox. + void HideURL(); + // Re-enables search term replacement on the ToolbarModel, and reverts the // edit and popup back to their unedited state (permanent text showing, popup // closed, no user input in progress). diff --git a/chrome/browser/ui/toolbar/test_toolbar_model.cc b/chrome/browser/ui/toolbar/test_toolbar_model.cc index 1d11263..f086bcb 100644 --- a/chrome/browser/ui/toolbar/test_toolbar_model.cc +++ b/chrome/browser/ui/toolbar/test_toolbar_model.cc @@ -20,6 +20,10 @@ base::string16 TestToolbarModel::GetText() const { return text_; } +base::string16 TestToolbarModel::GetFormattedURL() const { + return text_; +} + base::string16 TestToolbarModel::GetCorpusNameForMobile() const { return base::string16(); } diff --git a/chrome/browser/ui/toolbar/test_toolbar_model.h b/chrome/browser/ui/toolbar/test_toolbar_model.h index dd3a539..f426056 100644 --- a/chrome/browser/ui/toolbar/test_toolbar_model.h +++ b/chrome/browser/ui/toolbar/test_toolbar_model.h @@ -17,6 +17,7 @@ class TestToolbarModel : public ToolbarModel { TestToolbarModel(); virtual ~TestToolbarModel(); virtual base::string16 GetText() const OVERRIDE; + virtual base::string16 GetFormattedURL() const OVERRIDE; virtual base::string16 GetCorpusNameForMobile() const OVERRIDE; virtual GURL GetURL() const OVERRIDE; virtual bool WouldPerformSearchTermReplacement( diff --git a/chrome/browser/ui/toolbar/toolbar_model.h b/chrome/browser/ui/toolbar/toolbar_model.h index 4f1abc6..f4ecb74 100644 --- a/chrome/browser/ui/toolbar/toolbar_model.h +++ b/chrome/browser/ui/toolbar/toolbar_model.h @@ -31,15 +31,21 @@ class ToolbarModel { virtual ~ToolbarModel(); - // Returns the text for the current page's URL. This will have been formatted - // for display to the user: - // - Some characters may be unescaped. - // - The scheme and/or trailing slash may be dropped. + // Returns the text to be displayed in the toolbar for the current page. + // The text is formatted in various ways: // - If the current page's URL is a search URL for the user's default search // engine, the query will be extracted and returned for display instead // of the URL. + // - If the origin chip is enabled and visible, the text will be empty. + // - Otherwise, the text will contain the URL returned by GetFormattedURL(). virtual base::string16 GetText() const = 0; + // Returns a formatted URL for display in the toolbar. The formatting + // includes: + // - Some characters may be unescaped. + // - The scheme and/or trailing slash may be dropped. + virtual base::string16 GetFormattedURL() const = 0; + // Some search URLs bundle a special "corpus" param that we can extract and // display next to users' search terms in cases where we'd show the search // terms instead of the URL anyway. For example, a Google image search might diff --git a/chrome/browser/ui/toolbar/toolbar_model_impl.cc b/chrome/browser/ui/toolbar/toolbar_model_impl.cc index eac4909..1a36ba2 100644 --- a/chrome/browser/ui/toolbar/toolbar_model_impl.cc +++ b/chrome/browser/ui/toolbar/toolbar_model_impl.cc @@ -103,6 +103,10 @@ base::string16 ToolbarModelImpl::GetText() const { if (WouldOmitURLDueToOriginChip()) return base::string16(); + return GetFormattedURL(); +} + +base::string16 ToolbarModelImpl::GetFormattedURL() const { std::string languages; // Empty if we don't have a |navigation_controller|. Profile* profile = GetProfile(); if (profile) diff --git a/chrome/browser/ui/toolbar/toolbar_model_impl.h b/chrome/browser/ui/toolbar/toolbar_model_impl.h index 35e1434..7cec706 100644 --- a/chrome/browser/ui/toolbar/toolbar_model_impl.h +++ b/chrome/browser/ui/toolbar/toolbar_model_impl.h @@ -42,6 +42,7 @@ class ToolbarModelImpl : public ToolbarModel { private: // ToolbarModel: virtual base::string16 GetText() const OVERRIDE; + virtual base::string16 GetFormattedURL() const OVERRIDE; virtual base::string16 GetCorpusNameForMobile() const OVERRIDE; virtual GURL GetURL() const OVERRIDE; virtual bool WouldOmitURLDueToOriginChip() const OVERRIDE; diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 86eb599..75ee610 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -1057,7 +1057,7 @@ void BrowserView::SetFocusToLocationBar(bool select_all) { // origin chip is enabled, show it now to support the same functionality. if (select_all && location_bar->GetToolbarModel()->WouldOmitURLDueToOriginChip()) - location_bar->omnibox_view()->ShowURL(); + location_bar->ShowURL(); else location_bar->FocusLocation(select_all); } else { 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 f8252ed..9e6a0fb 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc @@ -11,6 +11,7 @@ #include "base/i18n/rtl.h" #include "base/prefs/pref_service.h" #include "base/stl_util.h" +#include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/chrome_notification_types.h" @@ -39,6 +40,7 @@ #include "chrome/browser/ui/omnibox/omnibox_popup_view.h" #include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/toolbar/origin_chip_info.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/bookmarks/bookmark_prompt_view.h" #include "chrome/browser/ui/views/browser_dialogs.h" @@ -78,6 +80,7 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/base/theme_provider.h" #include "ui/events/event.h" +#include "ui/gfx/animation/slide_animation.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/image/image.h" @@ -219,7 +222,8 @@ LocationBarView::LocationBarView(Browser* browser, is_popup_mode_(is_popup_mode), show_focus_rect_(false), template_url_service_(NULL), - animation_offset_(0), + dropdown_animation_offset_(0), + animated_host_label_(NULL), weak_ptr_factory_(this) { edit_bookmarks_enabled_.Init( prefs::kEditBookmarksEnabled, profile->GetPrefs(), @@ -317,8 +321,11 @@ void LocationBarView::Init() { ime_inline_autocomplete_view_->SetVisible(false); AddChildView(ime_inline_autocomplete_view_); + animated_host_label_ = new views::Label(base::string16(), font_list); + animated_host_label_->SetVisible(false); + AddChildView(animated_host_label_); + origin_chip_view_ = new OriginChipView(this, profile(), font_list); - origin_chip_view_->Init(); origin_chip_view_->SetFocusable(false); origin_chip_view_->set_drag_controller(this); AddChildView(origin_chip_view_); @@ -423,6 +430,14 @@ void LocationBarView::Init() { search_button_->SetVisible(false); AddChildView(search_button_); + show_url_animation_.reset(new gfx::SlideAnimation(this)); + show_url_animation_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); + show_url_animation_->SetSlideDuration(200); + + hide_url_animation_.reset(new gfx::SlideAnimation(this)); + hide_url_animation_->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN); + hide_url_animation_->SetSlideDuration(200); + content::Source<Profile> profile_source = content::Source<Profile>(profile()); registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOCATION_BAR_UPDATED, @@ -532,7 +547,7 @@ void LocationBarView::SetFocusAndSelection(bool select_all) { } void LocationBarView::SetAnimationOffset(int offset) { - animation_offset_ = offset; + dropdown_animation_offset_ = offset; } void LocationBarView::UpdateContentSettingsIcons() { @@ -708,6 +723,7 @@ void LocationBarView::Layout() { if (!IsInitialized()) return; + animated_host_label_->SetVisible(false); origin_chip_view_->SetVisible(origin_chip_view_->ShouldShow()); selected_keyword_view_->SetVisible(false); location_icon_view_->SetVisible(false); @@ -723,6 +739,46 @@ void LocationBarView::Layout() { LocationBarLayout trailing_decorations(LocationBarLayout::RIGHT_EDGE, item_padding); + // Show and position the animated host label used in the show and hide URL + // animations. + if (show_url_animation_->is_animating() || + hide_url_animation_->is_animating()) { + const GURL url = GetWebContents()->GetURL(); + const base::string16 host = + OriginChip::LabelFromURLForProfile(url, profile()); + animated_host_label_->SetText(host); + + const base::string16 formatted_url = GetToolbarModel()->GetFormattedURL(); + + // Split the formatted URL on the host name in order to determine the size + // of the text leading up to it. + std::vector<base::string16> substrings; + base::SplitStringUsingSubstr(formatted_url, host, &substrings); + const base::string16 text_leading_host = substrings[0]; + const int leading_text_width = + gfx::Canvas::GetStringWidth(text_leading_host, + origin_chip_view_->GetFontList()); + + const int position_of_host_name_in_chip = origin_chip_view_->host_label_x(); + const int position_of_host_name_in_url = + position_of_host_name_in_chip + leading_text_width; + + int host_label_x = position_of_host_name_in_chip; + if (show_url_animation_->is_animating()) { + host_label_x = show_url_animation_-> + CurrentValueBetween(position_of_host_name_in_chip, + position_of_host_name_in_url); + } else if (hide_url_animation_->is_animating()) { + host_label_x = hide_url_animation_-> + CurrentValueBetween(position_of_host_name_in_url, + position_of_host_name_in_chip); + } + animated_host_label_->SetBounds( + host_label_x, 0, + animated_host_label_->GetPreferredSize().width(), height()); + animated_host_label_->SetVisible(true); + } + const int origin_chip_width = origin_chip_view_->visible() ? origin_chip_view_->GetPreferredSize().width() : 0; origin_chip_view_->SetBounds(0, 0, origin_chip_width, height()); @@ -1101,6 +1157,59 @@ void LocationBarView::OnSetFocus() { GetFocusManager()->SetFocusedView(this); } +void LocationBarView::ShowURL() { + if (chrome::ShouldDisplayOriginChipV2()) { + omnibox_view_->SetVisible(false); + omnibox_view_->ShowURL(); + show_url_animation_->Show(); + } else { + omnibox_view_->ShowURL(); + } +} + +void LocationBarView::OnShowURLAnimationEnded() { + animated_host_label_->SetVisible(false); + omnibox_view_->SetVisible(true); + omnibox_view_->FadeIn(); + omnibox_view_->SetFocus(); + + // Sometimes the selection established by OmniboxView::ShowURL() is lost at + // the call to SetFocus() above. Select all again to be sure. + // TODO(jdonnelly): Figure out why the selection is sometimes lost and + // implement a more principled fix. + omnibox_view_->SelectAll(true); +} + +void LocationBarView::HideURL() { + omnibox_view_->SetVisible(false); + hide_url_animation_->Show(); +} + +void LocationBarView::OnHideURLAnimationEnded() { + animated_host_label_->SetVisible(false); + omnibox_view_->HideURL(); + omnibox_view_->SetVisible(true); + origin_chip_view_->FadeIn(); +} + +void LocationBarView::AnimationProgressed(const gfx::Animation* animation) { + if (animation == show_url_animation_.get() || + animation == hide_url_animation_.get()) { + Layout(); + SchedulePaint(); + } +} + +void LocationBarView::AnimationEnded(const gfx::Animation* animation) { + if (animation == show_url_animation_.get()) { + show_url_animation_->Reset(); + OnShowURLAnimationEnded(); + } else if (animation == hide_url_animation_.get()) { + hide_url_animation_->Reset(); + OnHideURLAnimationEnded(); + } +} + InstantController* LocationBarView::GetInstant() { return delegate_->GetInstant(); } 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 51489ba..cd7d8e7 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h @@ -23,6 +23,7 @@ #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" +#include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/font.h" #include "ui/gfx/rect.h" #include "ui/views/controls/button/button.h" @@ -56,6 +57,10 @@ namespace content { struct SSLStatus; } +namespace gfx { +class SlideAnimation; +} + namespace views { class BubbleDelegateView; class ImageButton; @@ -80,6 +85,7 @@ class LocationBarView : public LocationBar, public views::DragController, public OmniboxEditController, public DropdownBarHostDelegate, + public gfx::AnimationDelegate, public TemplateURLServiceObserver, public content::NotificationObserver, public SearchModelObserver { @@ -91,8 +97,8 @@ class LocationBarView : public LocationBar, virtual void SetFocusAndSelection(bool select_all) OVERRIDE; virtual void SetAnimationOffset(int offset) OVERRIDE; - // Returns the offset used while animating. - int animation_offset() const { return animation_offset_; } + // Returns the offset used during dropdown animation. + int dropdown_animation_offset() const { return dropdown_animation_offset_; } class Delegate { public: @@ -255,6 +261,7 @@ class LocationBarView : public LocationBar, virtual void Update(const content::WebContents* contents) OVERRIDE; virtual void OnChanged() OVERRIDE; virtual void OnSetFocus() OVERRIDE; + virtual void ShowURL() OVERRIDE; virtual InstantController* GetInstant() OVERRIDE; virtual content::WebContents* GetWebContents() OVERRIDE; virtual ToolbarModel* GetToolbarModel() OVERRIDE; @@ -352,10 +359,17 @@ class LocationBarView : public LocationBar, // Space between the edge and a bubble. static const int kBubblePadding; - protected: + private: + // views::View: virtual void OnFocus() OVERRIDE; - private: + // OmniboxEditController: + virtual void HideURL() OVERRIDE; + + // gfx::AnimationDelegate: + virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; + virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; + typedef std::vector<ContentSettingImageView*> ContentSettingViews; friend class PageActionImageView; @@ -416,6 +430,10 @@ class LocationBarView : public LocationBar, // don't normally use this). Sets the value and clears the selection. void AccessibilitySetValue(const base::string16& new_value); + // Origin chip animation control methods. + void OnShowURLAnimationEnded(); + void OnHideURLAnimationEnded(); + // The Browser this LocationBarView is in. Note that at least // chromeos::SimpleWebViewDialog uses a LocationBarView outside any browser // window, so this may be NULL. @@ -511,11 +529,18 @@ class LocationBarView : public LocationBar, // Tracks this preference to determine whether bookmark editing is allowed. BooleanPrefMember edit_bookmarks_enabled_; - // While animating, the host clips the widget and draws only the bottom - // part of it. The view needs to know the pixel offset at which we are drawing - // the widget so that we can draw the curved edges that attach to the toolbar - // in the right location. - int animation_offset_; + // During dropdown animation, the host clips the widget and draws only the + // bottom part of it. The view needs to know the pixel offset at which we are + // drawing the widget so that we can draw the curved edges that attach to the + // toolbar in the right location. + int dropdown_animation_offset_; + + // Origin chip animations. + scoped_ptr<gfx::SlideAnimation> show_url_animation_; + scoped_ptr<gfx::SlideAnimation> hide_url_animation_; + + // Text label shown only during origin chip animations. + views::Label* animated_host_label_; // Used to register for notifications received by NotificationObserver. content::NotificationRegistrar registrar_; diff --git a/chrome/browser/ui/views/location_bar/origin_chip_view.cc b/chrome/browser/ui/views/location_bar/origin_chip_view.cc index 09e3853..1da7a95 100644 --- a/chrome/browser/ui/views/location_bar/origin_chip_view.cc +++ b/chrome/browser/ui/views/location_bar/origin_chip_view.cc @@ -25,8 +25,6 @@ #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/manifest_handlers/icons_handler.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_entry.h" #include "content/public/browser/user_metrics.h" #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" @@ -37,6 +35,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/theme_provider.h" +#include "ui/gfx/animation/slide_animation.h" +#include "ui/gfx/canvas.h" #include "ui/gfx/font_list.h" #include "ui/views/background.h" #include "ui/views/controls/button/label_button.h" @@ -143,16 +143,7 @@ OriginChipView::OriginChipView(LocationBarView* location_bar_view, sb_service->ui_manager()->AddObserver(this); SetFontList(font_list); -} -OriginChipView::~OriginChipView() { - scoped_refptr<SafeBrowsingService> sb_service = - g_browser_process->safe_browsing_service(); - if (sb_service.get() && sb_service->ui_manager()) - sb_service->ui_manager()->RemoveObserver(this); -} - -void OriginChipView::Init() { image()->EnableCanvasFlippingForRTLUI(false); // TODO(gbillock): Would be nice to just use stock LabelButton stuff here. @@ -164,6 +155,17 @@ void OriginChipView::Init() { host_label_ = new views::Label(base::string16(), GetFontList()); AddChildView(host_label_); + + fade_in_animation_.reset(new gfx::SlideAnimation(this)); + fade_in_animation_->SetTweenType(gfx::Tween::LINEAR); + fade_in_animation_->SetSlideDuration(300); +} + +OriginChipView::~OriginChipView() { + scoped_refptr<SafeBrowsingService> sb_service = + g_browser_process->safe_browsing_service(); + if (sb_service.get() && sb_service->ui_manager()) + sb_service->ui_manager()->RemoveObserver(this); } bool OriginChipView::ShouldShow() { @@ -280,6 +282,24 @@ void OriginChipView::OnChanged() { // arrows are pointing to the right spot. Only needed for some edge cases. } +void OriginChipView::FadeIn() { + fade_in_animation_->Show(); +} + +void OriginChipView::AnimationProgressed(const gfx::Animation* animation) { + if (animation == fade_in_animation_.get()) + SchedulePaint(); + else + views::LabelButton::AnimationProgressed(animation); +} + +void OriginChipView::AnimationEnded(const gfx::Animation* animation) { + if (animation == fade_in_animation_.get()) + fade_in_animation_->Reset(); + else + views::LabelButton::AnimationEnded(animation); +} + gfx::Size OriginChipView::GetPreferredSize() { gfx::Size label_size = host_label_->GetPreferredSize(); gfx::Size icon_size = location_icon_view_->GetPreferredSize(); @@ -312,6 +332,17 @@ void OriginChipView::Layout() { height() - 2 * LocationBarView::kNormalEdgeThickness); } +void OriginChipView::OnPaintBorder(gfx::Canvas* canvas) { + if (fade_in_animation_->is_animating()) { + canvas->SaveLayerAlpha(static_cast<uint8>( + fade_in_animation_->CurrentValueBetween(0, 255))); + views::LabelButton::OnPaintBorder(canvas); + canvas->Restore(); + } else { + views::LabelButton::OnPaintBorder(canvas); + } +} + int OriginChipView::ElideDomainTarget(int target_max_width) { base::string16 host = OriginChip::LabelFromURLForProfile(url_displayed_, profile_); @@ -350,7 +381,7 @@ void OriginChipView::ButtonPressed(views::Button* sender, UMA_HISTOGRAM_COUNTS("OriginChip.Pressed", 1); content::RecordAction(base::UserMetricsAction("OriginChipPress")); - location_bar_view_->GetOmniboxView()->ShowURL(); + location_bar_view_->ShowURL(); } // Note: When OnSafeBrowsingHit would be called, OnSafeBrowsingMatch will diff --git a/chrome/browser/ui/views/location_bar/origin_chip_view.h b/chrome/browser/ui/views/location_bar/origin_chip_view.h index bb2d19d..644283e 100644 --- a/chrome/browser/ui/views/location_bar/origin_chip_view.h +++ b/chrome/browser/ui/views/location_bar/origin_chip_view.h @@ -22,6 +22,7 @@ class WebContents; namespace gfx { class Canvas; class FontList; +class SlideAnimation; } namespace views { @@ -38,8 +39,6 @@ class OriginChipView : public views::LabelButton, const gfx::FontList& font_list); virtual ~OriginChipView(); - void Init(); - // Returns true if the origin chip should be visible. This will always be // true if the original origin chip experiment is enabled. If the V2 // experiment is enabled this is true if the chip hasn't been hidden by @@ -65,9 +64,18 @@ class OriginChipView : public views::LabelButton, // width, since the hostname will not be elided past the TLD+1. int ElideDomainTarget(int target_max_width); + // Starts an animation that fades in the border. + void FadeIn(); + + // Returns the current X position of the host label. + int host_label_x() const { return host_label_->x(); } + // views::LabelButton: + virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; + virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; virtual gfx::Size GetPreferredSize() OVERRIDE; virtual void Layout() OVERRIDE; + virtual void OnPaintBorder(gfx::Canvas* canvas) OVERRIDE; // views::ButtonListener: virtual void ButtonPressed(views::Button* sender, @@ -92,6 +100,7 @@ class OriginChipView : public views::LabelButton, GURL url_displayed_; ToolbarModel::SecurityLevel security_level_; bool url_malware_; + scoped_ptr<gfx::SlideAnimation> fade_in_animation_; DISALLOW_COPY_AND_ASSIGN(OriginChipView); }; diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index 02c2d7a..aa42419 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc @@ -41,6 +41,7 @@ #include "ui/base/models/simple_menu_model.h" #include "ui/base/resource/resource_bundle.h" #include "ui/events/event.h" +#include "ui/gfx/animation/slide_animation.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font_list.h" #include "ui/gfx/selection_model.h" @@ -180,6 +181,14 @@ void OmniboxViewViews::Init() { chromeos::input_method::InputMethodManager::Get()-> AddCandidateWindowObserver(this); #endif + + fade_in_animation_.reset(new gfx::SlideAnimation(this)); + fade_in_animation_->SetTweenType(gfx::Tween::LINEAR); + fade_in_animation_->SetSlideDuration(300); +} + +void OmniboxViewViews::FadeIn() { + fade_in_animation_->Show(); } //////////////////////////////////////////////////////////////////////////////// @@ -189,6 +198,17 @@ const char* OmniboxViewViews::GetClassName() const { return kViewClassName; } +void OmniboxViewViews::OnPaint(gfx::Canvas* canvas) { + if (fade_in_animation_->is_animating()) { + canvas->SaveLayerAlpha(static_cast<uint8>( + fade_in_animation_->CurrentValueBetween(0, 255))); + views::Textfield::OnPaint(canvas); + canvas->Restore(); + } else { + views::Textfield::OnPaint(canvas); + } +} + bool OmniboxViewViews::OnMousePressed(const ui::MouseEvent& event) { select_all_on_mouse_release_ = (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) && @@ -757,7 +777,7 @@ void OmniboxViewViews::ExecuteCommand(int command_id, int event_flags) { model()->PasteAndGo(GetClipboardText()); break; case IDS_SHOW_URL: - ShowURL(); + controller()->ShowURL(); break; case IDC_EDIT_SEARCH_ENGINES: command_updater()->ExecuteCommand(command_id); @@ -777,6 +797,17 @@ void OmniboxViewViews::ExecuteCommand(int command_id, int event_flags) { } //////////////////////////////////////////////////////////////////////////////// +// OmniboxViewViews, gfx::AnimationDelegate implementation: + +void OmniboxViewViews::AnimationProgressed(const gfx::Animation* animation) { + SchedulePaint(); +} + +void OmniboxViewViews::AnimationEnded(const gfx::Animation* animation) { + fade_in_animation_->Reset(); +} + +//////////////////////////////////////////////////////////////////////////////// // OmniboxViewViews, views::TextfieldController implementation: void OmniboxViewViews::ContentsChanged(views::Textfield* sender, diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index 311a5aa..c7e19df 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h @@ -12,6 +12,7 @@ #include "chrome/browser/ui/omnibox/omnibox_view.h" #include "chrome/browser/ui/toolbar/toolbar_model.h" #include "ui/base/window_open_disposition.h" +#include "ui/gfx/animation/animation_delegate.h" #include "ui/gfx/range/range.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/controls/textfield/textfield_controller.h" @@ -24,6 +25,10 @@ class LocationBarView; class OmniboxPopupView; class Profile; +namespace gfx { +class SlideAnimation; +} + namespace ui { class OSExchangeData; } // namespace ui @@ -32,6 +37,7 @@ class OSExchangeData; class OmniboxViewViews : public views::Textfield, public OmniboxView, + public gfx::AnimationDelegate, #if defined(OS_CHROMEOS) public chromeos::input_method::InputMethodManager::CandidateWindowObserver, @@ -52,8 +58,12 @@ class OmniboxViewViews // Initialize, create the underlying views, etc; void Init(); + // Starts an animation that fades in the entire OmniboxView. + void FadeIn(); + // views::Textfield: virtual const char* GetClassName() const OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; @@ -118,6 +128,10 @@ class OmniboxViewViews virtual base::string16 GetLabelForCommandId(int command_id) const OVERRIDE; virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; + // gfx::AnimationDelegate: + virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; + virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; + // views::TextfieldController: virtual void ContentsChanged(views::Textfield* sender, const base::string16& new_contents) OVERRIDE; @@ -207,6 +221,8 @@ class OmniboxViewViews // and gets a tap. So we use this variable to remember focus state before tap. bool select_all_on_gesture_tap_; + scoped_ptr<gfx::SlideAnimation> fade_in_animation_; + DISALLOW_COPY_AND_ASSIGN(OmniboxViewViews); }; diff --git a/chrome/browser/ui/views/toolbar/toolbar_origin_chip_view.cc b/chrome/browser/ui/views/toolbar/toolbar_origin_chip_view.cc index 136807a..7fb18d0 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_origin_chip_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_origin_chip_view.cc @@ -341,7 +341,7 @@ void ToolbarOriginChipView::ButtonPressed(views::Button* sender, UMA_HISTOGRAM_COUNTS("OriginChip.Pressed", 1); content::RecordAction(base::UserMetricsAction("OriginChipPress")); - toolbar_view_->location_bar()->GetOmniboxView()->ShowURL(); + toolbar_view_->location_bar()->ShowURL(); } void ToolbarOriginChipView::WriteDragDataForView(View* sender, |