1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
6 #define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
11 #include "base/compiler_specific.h"
12 #include "base/prefs/pref_member.h"
13 #include "chrome/browser/extensions/extension_context_menu_model.h"
14 #include "chrome/browser/ui/location_bar/location_bar.h"
15 #include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
16 #include "chrome/browser/ui/search/search_model_observer.h"
17 #include "chrome/browser/ui/toolbar/toolbar_model.h"
18 #include "chrome/browser/ui/views/dropdown_bar_host.h"
19 #include "chrome/browser/ui/views/dropdown_bar_host_delegate.h"
20 #include "chrome/browser/ui/views/extensions/extension_popup.h"
21 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h"
22 #include "components/search_engines/template_url_service_observer.h"
23 #include "ui/gfx/animation/animation_delegate.h"
24 #include "ui/gfx/font.h"
25 #include "ui/gfx/rect.h"
26 #include "ui/views/controls/button/button.h"
27 #include "ui/views/drag_controller.h"
29 class ActionBoxButtonView;
31 class ContentSettingBubbleModelDelegate;
32 class ContentSettingImageView;
34 class ExtensionAction;
36 class GeneratedCreditCardView;
37 class InstantController;
38 class KeywordHintView;
39 class LocationIconView;
40 class OpenPDFInReaderView;
41 class ManagePasswordsIconView;
43 class PageActionWithBadgeView;
44 class PageActionImageView;
47 class SelectedKeywordView;
49 class TemplateURLService;
50 class TranslateIconView;
62 class BubbleDelegateView;
69 /////////////////////////////////////////////////////////////////////////////
71 // LocationBarView class
73 // The LocationBarView class is a View subclass that paints the background
74 // of the URL bar strip and contains its content.
76 /////////////////////////////////////////////////////////////////////////////
77 class LocationBarView : public LocationBar,
78 public LocationBarTesting,
80 public views::ButtonListener,
81 public views::DragController,
82 public OmniboxEditController,
83 public DropdownBarHostDelegate,
84 public gfx::AnimationDelegate,
85 public TemplateURLServiceObserver,
86 public SearchModelObserver {
88 // The location bar view's class name.
89 static const char kViewClassName[];
91 // Returns the offset used during dropdown animation.
92 int dropdown_animation_offset() const { return dropdown_animation_offset_; }
96 // Should return the current web contents.
97 virtual content::WebContents* GetWebContents() = 0;
99 // Returns the InstantController, or NULL if there isn't one.
100 virtual InstantController* GetInstant() = 0;
102 virtual ToolbarModel* GetToolbarModel() = 0;
103 virtual const ToolbarModel* GetToolbarModel() const = 0;
105 // Creates Widget for the given delegate.
106 virtual views::Widget* CreateViewsBubble(
107 views::BubbleDelegateView* bubble_delegate) = 0;
109 // Creates PageActionImageView. Caller gets an ownership.
110 virtual PageActionImageView* CreatePageActionImageView(
111 LocationBarView* owner,
112 ExtensionAction* action) = 0;
114 // Returns ContentSettingBubbleModelDelegate.
115 virtual ContentSettingBubbleModelDelegate*
116 GetContentSettingBubbleModelDelegate() = 0;
118 // Shows permissions and settings for the given web contents.
119 virtual void ShowWebsiteSettings(content::WebContents* web_contents,
121 const content::SSLStatus& ssl) = 0;
124 virtual ~Delegate() {}
135 LocationBarView(Browser* browser,
137 CommandUpdater* command_updater,
141 ~LocationBarView() override;
143 // Initializes the LocationBarView.
146 // True if this instance has been initialized by calling Init, which can only
147 // be called when the receiving instance is attached to a view container.
148 bool IsInitialized() const;
150 // Returns the appropriate color for the desired kind, based on the user's
152 SkColor GetColor(ToolbarModel::SecurityLevel security_level,
153 ColorKind kind) const;
155 // Returns the delegate.
156 Delegate* delegate() const { return delegate_; }
158 // See comment in browser_window.h for more info.
159 void ZoomChangedForActiveTab(bool can_show_bubble);
161 // The zoom icon. It may not be visible.
162 ZoomView* zoom_view() { return zoom_view_; }
164 // The passwords icon. It may not be visible.
165 ManagePasswordsIconView* manage_passwords_icon_view() {
166 return manage_passwords_icon_view_;
169 // Sets |preview_enabled| for the PageAction View associated with this
170 // |page_action|. If |preview_enabled| is true, the view will display the
171 // PageActions icon even though it has not been activated by the extension.
172 // This is used by the ExtensionInstalledBubble to preview what the icon
173 // will look like for the user upon installation of the extension.
174 void SetPreviewEnabledPageAction(ExtensionAction* page_action,
175 bool preview_enabled);
177 // Retrieves the PageAction View which is associated with |page_action|.
178 PageActionWithBadgeView* GetPageActionView(ExtensionAction* page_action);
180 // Toggles the star on or off.
181 void SetStarToggled(bool on);
183 // The star. It may not be visible.
184 StarView* star_view() { return star_view_; }
186 // Toggles the translate icon on or off.
187 void SetTranslateIconToggled(bool on);
189 // The translate icon. It may not be visible.
190 TranslateIconView* translate_icon_view() { return translate_icon_view_; }
192 // Returns the screen coordinates of the omnibox (where the URL text appears,
193 // not where the icons are shown).
194 gfx::Point GetOmniboxViewOrigin() const;
196 // Shows |text| as an inline autocompletion. This is useful for IMEs, where
197 // we can't show the autocompletion inside the actual OmniboxView. See
198 // comments on |ime_inline_autocomplete_view_|.
199 void SetImeInlineAutocompletion(const base::string16& text);
201 // Invoked from OmniboxViewWin to show gray text autocompletion.
202 void SetGrayTextAutocompletion(const base::string16& text);
204 // Returns the current gray text autocompletion.
205 base::string16 GetGrayTextAutocompletion() const;
207 // Set if we should show a focus rect while the location entry field is
208 // focused. Used when the toolbar is in full keyboard accessibility mode.
209 // Repaints if necessary.
210 virtual void SetShowFocusRect(bool show);
212 // Select all of the text. Needed when the user tabs through controls
213 // in the toolbar in full keyboard accessibility mode.
214 virtual void SelectAll();
216 LocationIconView* location_icon_view() { return location_icon_view_; }
218 // Return the point suitable for anchoring location-bar-anchored bubbles at.
219 // The point will be returned in the coordinates of the LocationBarView.
220 gfx::Point GetLocationBarAnchorPoint() const;
222 OmniboxViewViews* omnibox_view() { return omnibox_view_; }
223 const OmniboxViewViews* omnibox_view() const { return omnibox_view_; }
225 views::View* generated_credit_card_view();
227 // Returns the height of the control without the top and bottom
228 // edges(i.e. the height of the edit control inside). If
229 // |use_preferred_size| is true this will be the preferred height,
230 // otherwise it will be the current height.
231 int GetInternalHeight(bool use_preferred_size);
233 // Returns the position and width that the popup should be, and also the left
234 // edge that the results should align themselves to (which will leave some
235 // border on the left of the popup).
236 void GetOmniboxPopupPositioningInfo(gfx::Point* top_left_screen_coord,
242 void FocusLocation(bool select_all) override;
243 void Revert() override;
244 OmniboxView* GetOmniboxView() override;
247 bool HasFocus() const override;
248 void GetAccessibleState(ui::AXViewState* state) override;
249 gfx::Size GetPreferredSize() const override;
250 void Layout() override;
252 // OmniboxEditController:
253 void Update(const content::WebContents* contents) override;
254 void ShowURL() override;
255 void EndOriginChipAnimations(bool cancel_fade) override;
256 ToolbarModel* GetToolbarModel() override;
257 content::WebContents* GetWebContents() override;
259 // Thickness of the edges of the omnibox background images, in normal mode.
260 static const int kNormalEdgeThickness;
261 // The same, but for popup mode.
262 static const int kPopupEdgeThickness;
263 // Space between items in the location bar, as well as between items and the
265 static const int kItemPadding;
266 // Amount of padding built into the standard omnibox icons.
267 static const int kIconInternalPadding;
268 // Amount of padding to place between the origin chip and the leading edge of
270 static const int kOriginChipEdgeItemPadding;
271 // Amount of padding built into the origin chip.
272 static const int kOriginChipBuiltinPadding;
273 // Space between the edge and a bubble.
274 static const int kBubblePadding;
277 typedef std::vector<ContentSettingImageView*> ContentSettingViews;
279 friend class PageActionImageView;
280 friend class PageActionWithBadgeView;
281 typedef std::vector<ExtensionAction*> PageActions;
282 typedef std::vector<PageActionWithBadgeView*> PageActionViews;
284 // Helper for GetMinimumWidth(). Calculates the incremental minimum width
285 // |view| should add to the trailing width after the omnibox.
286 static int IncrementalMinimumWidth(views::View* view);
288 // Returns the thickness of any visible left and right edge, in pixels.
289 int GetHorizontalEdgeThickness() const;
291 // The same, but for the top and bottom edges.
292 int vertical_edge_thickness() const {
293 return is_popup_mode_ ? kPopupEdgeThickness : kNormalEdgeThickness;
296 // Updates the visibility state of the Content Blocked icons to reflect what
297 // is actually blocked on the current page. Returns true if the visibility
298 // of at least one of the views in |content_setting_views_| changed.
299 bool RefreshContentSettingViews();
301 // Deletes all page action views that we have created.
302 void DeletePageActionViews();
304 // Updates the views for the Page Actions, to reflect state changes for
305 // PageActions. Returns true if the visibility of a PageActionWithBadgeView
306 // changed, or PageActionWithBadgeView were created/destroyed.
307 bool RefreshPageActionViews();
309 // Updates the view for the zoom icon based on the current tab's zoom. Returns
310 // true if the visibility of the view changed.
311 bool RefreshZoomView();
313 // Updates the Translate icon based on the current tab's Translate status.
314 void RefreshTranslateIcon();
316 // Updates |manage_passwords_icon_view_|. Returns true if visibility changed.
317 bool RefreshManagePasswordsIconView();
319 // Helper to show the first run info bubble.
320 void ShowFirstRunBubbleInternal();
322 // Returns true if the suggest text is valid.
323 bool HasValidSuggestText() const;
325 bool ShouldShowKeywordBubble() const;
326 bool ShouldShowEVBubble() const;
328 // Used to "reverse" the URL showing/hiding animations, since we use separate
329 // animations whose curves are not true inverses of each other. Based on the
330 // current position of the omnibox, calculates what value the desired
331 // animation (|hide_url_animation_| if |hide| is true, |show_url_animation_|
332 // if it's false) should be set to in order to produce the same omnibox
333 // position. This way we can stop the old animation, set the new animation to
334 // this value, and start it running, and the text will appear to reverse
335 // directions from its current location.
336 double GetValueForAnimation(bool hide) const;
338 // Resets |show_url_animation_| and the color changes it causes.
339 void ResetShowAnimationAndColors();
342 void ShowFirstRunBubble() override;
343 GURL GetDestinationURL() const override;
344 WindowOpenDisposition GetWindowOpenDisposition() const override;
345 ui::PageTransition GetPageTransition() const override;
346 void AcceptInput() override;
347 void FocusSearch() override;
348 void UpdateContentSettingsIcons() override;
349 void UpdateManagePasswordsIconAndBubble() override;
350 void UpdatePageActions() override;
351 void InvalidatePageActions() override;
352 void UpdateBookmarkStarVisibility() override;
353 bool ShowPageActionPopup(const extensions::Extension* extension,
354 bool grant_active_tab) override;
355 void UpdateOpenPDFInReaderPrompt() override;
356 void UpdateGeneratedCreditCardView() override;
357 void SaveStateToContents(content::WebContents* contents) override;
358 const OmniboxView* GetOmniboxView() const override;
359 LocationBarTesting* GetLocationBarForTesting() override;
361 // LocationBarTesting:
362 int PageActionCount() override;
363 int PageActionVisibleCount() override;
364 ExtensionAction* GetPageAction(size_t index) override;
365 ExtensionAction* GetVisiblePageAction(size_t index) override;
366 void TestPageActionPressed(size_t index) override;
367 bool GetBookmarkStarVisibility() override;
370 const char* GetClassName() const override;
371 void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
372 void OnFocus() override;
373 void OnPaint(gfx::Canvas* canvas) override;
374 void PaintChildren(gfx::Canvas* canvas,
375 const views::CullSet& cull_set) override;
377 // views::ButtonListener:
378 void ButtonPressed(views::Button* sender, const ui::Event& event) override;
380 // views::DragController:
381 void WriteDragDataForView(View* sender,
382 const gfx::Point& press_pt,
383 OSExchangeData* data) override;
384 int GetDragOperationsForView(View* sender, const gfx::Point& p) override;
385 bool CanStartDragForView(View* sender,
386 const gfx::Point& press_pt,
387 const gfx::Point& p) override;
389 // OmniboxEditController:
390 void OnChanged() override;
391 void OnSetFocus() override;
392 InstantController* GetInstant() override;
393 const ToolbarModel* GetToolbarModel() const override;
394 void HideURL() override;
396 // DropdownBarHostDelegate:
397 void SetFocusAndSelection(bool select_all) override;
398 void SetAnimationOffset(int offset) override;
400 // gfx::AnimationDelegate:
401 void AnimationProgressed(const gfx::Animation* animation) override;
402 void AnimationEnded(const gfx::Animation* animation) override;
404 // TemplateURLServiceObserver:
405 void OnTemplateURLServiceChanged() override;
407 // SearchModelObserver:
408 void ModelChanged(const SearchModel::State& old_state,
409 const SearchModel::State& new_state) override;
411 // The Browser this LocationBarView is in. Note that at least
412 // chromeos::SimpleWebViewDialog uses a LocationBarView outside any browser
413 // window, so this may be NULL.
416 OmniboxViewViews* omnibox_view_;
421 // Object used to paint the border.
422 scoped_ptr<views::Painter> border_painter_;
424 // The origin chip that may appear in the location bar.
425 OriginChipView* origin_chip_view_;
427 // An icon to the left of the edit field.
428 LocationIconView* location_icon_view_;
430 // A bubble displayed for EV HTTPS sites.
431 EVBubbleView* ev_bubble_view_;
433 // A view to show inline autocompletion when an IME is active. In this case,
434 // we shouldn't change the text or selection inside the OmniboxView itself,
435 // since this will conflict with the IME's control over the text. So instead
436 // we show any autocompletion in a separate field after the OmniboxView.
437 views::Label* ime_inline_autocomplete_view_;
439 // The following views are used to provide hints and remind the user as to
440 // what is going in the edit. They are all added a children of the
441 // LocationBarView. At most one is visible at a time. Preference is
442 // given to the keyword_view_, then hint_view_.
443 // These autocollapse when the edit needs the room.
445 // Shown if the user has selected a keyword.
446 SelectedKeywordView* selected_keyword_view_;
448 // View responsible for showing suggested text. This is NULL when there is no
450 views::Label* suggested_text_view_;
452 // Shown if the selected url has a corresponding keyword.
453 KeywordHintView* keyword_hint_view_;
455 // The voice search icon.
456 views::ImageButton* mic_search_view_;
458 // The content setting views.
459 ContentSettingViews content_setting_views_;
462 ZoomView* zoom_view_;
464 // A bubble that shows after successfully generating a new credit card number.
465 GeneratedCreditCardView* generated_credit_card_view_;
467 // The icon to open a PDF in Reader.
468 OpenPDFInReaderView* open_pdf_in_reader_view_;
470 // The manage passwords icon.
471 ManagePasswordsIconView* manage_passwords_icon_view_;
473 // The current page actions.
474 PageActions page_actions_;
476 // The page action icon views.
477 PageActionViews page_action_views_;
479 // The icon for Translate.
480 TranslateIconView* translate_icon_view_;
483 StarView* star_view_;
485 // The search/go button.
486 SearchButton* search_button_;
488 // Whether we're in popup mode. This value also controls whether the location
490 const bool is_popup_mode_;
492 // True if we should show a focus rect while the location entry field is
493 // focused. Used when the toolbar is in full keyboard accessibility mode.
494 bool show_focus_rect_;
496 // This is in case we're destroyed before the model loads. We need to make
497 // Add/RemoveObserver calls.
498 TemplateURLService* template_url_service_;
500 // Tracks this preference to determine whether bookmark editing is allowed.
501 BooleanPrefMember edit_bookmarks_enabled_;
503 // During dropdown animation, the host clips the widget and draws only the
504 // bottom part of it. The view needs to know the pixel offset at which we are
505 // drawing the widget so that we can draw the curved edges that attach to the
506 // toolbar in the right location.
507 int dropdown_animation_offset_;
509 // Origin chip animations.
511 // For the "show URL" animation, we instantly hide the origin chip and show
512 // the |omnibox_view_| in its place, containing the complete URL. However, we
513 // clip that view (using the XXX_leading_inset_ and XXX_width_ members) so
514 // that only the hostname is visible. We also offset the omnibox (using the
515 // XXX_offset_ members) so the hostname is in the same place as it was in the
516 // origin chip. Finally, we set the selection text and background color of
517 // the text to match the pressed origin chip. Then, as the animation runs,
518 // all of these values are animated to their steady-state values (no omnibox
519 // offset, no inset, width equal to the full omnibox text [which is reset to
520 // "no width clamp" after the animation ends], and standard selection colors).
522 // For the hide animation, we run the positioning and clipping parts of the
523 // animation in reverse, but instead of changing the selection color, because
524 // there usually isn't a selection when hiding, we leave the omnibox colors
525 // alone, and when the hide animation has ended, tell the origin chip to
526 // fade-in its background.
527 scoped_ptr<gfx::SlideAnimation> show_url_animation_;
528 scoped_ptr<gfx::SlideAnimation> hide_url_animation_;
529 // The omnibox offset may be positive or negative. The starting offset is the
530 // amount necessary to shift the |omnibox_view_| by such that the hostname
531 // portion of the URL aligns with the hostname in the origin chip. As the
532 // show animation runs, the current offset gradually moves to 0.
533 int starting_omnibox_offset_;
534 int current_omnibox_offset_;
535 // The leading inset is always positive. The starting inset is the width of
536 // the text between the leading edge of the omnibox and the edge of the
537 // hostname, which is clipped off at the start of the show animation. Note
538 // that in RTL mode, this will be the part of the URL that is logically after
539 // the hostname. As the show animation runs, the current inset gradually
541 int starting_omnibox_leading_inset_;
542 int current_omnibox_leading_inset_;
543 // The width is always positive. The ending width is the width of the entire
544 // omnibox URL. As the show animation runs, the current width gradually moves
545 // from the width of the hostname to the ending value.
546 int current_omnibox_width_;
547 int ending_omnibox_width_;
549 DISALLOW_COPY_AND_ASSIGN(LocationBarView);
552 #endif // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_