location_bar_view.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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.
4
5#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
6#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
7
8#include <string>
9#include <vector>
10
11#include "base/compiler_specific.h"
12#include "base/prefs/public/pref_observer.h"
13#include "chrome/browser/api/prefs/pref_member.h"
14#include "chrome/browser/extensions/extension_context_menu_model.h"
15#include "chrome/browser/search_engines/template_url_service_observer.h"
16#include "chrome/browser/ui/omnibox/location_bar.h"
17#include "chrome/browser/ui/omnibox/omnibox_edit_controller.h"
18#include "chrome/browser/ui/search/search_model_observer.h"
19#include "chrome/browser/ui/toolbar/toolbar_model.h"
20#include "chrome/browser/ui/views/dropdown_bar_host.h"
21#include "chrome/browser/ui/views/dropdown_bar_host_delegate.h"
22#include "chrome/browser/ui/views/extensions/extension_popup.h"
23#include "content/public/browser/notification_observer.h"
24#include "content/public/browser/notification_registrar.h"
25#include "ui/gfx/font.h"
26#include "ui/gfx/rect.h"
27#include "ui/views/controls/native/native_view_host.h"
28#include "ui/views/drag_controller.h"
29
30#if defined(USE_AURA)
31#include "ui/compositor/layer_animation_observer.h"
32#endif
33
34class ActionBoxButtonView;
35class CommandUpdater;
36class ContentSettingBubbleModelDelegate;
37class ContentSettingImageView;
38class EVBubbleView;
39class ExtensionAction;
40class GURL;
41class InstantController;
42class KeywordHintView;
43class LocationIconView;
44class OpenPDFInReaderView;
45class PageActionWithBadgeView;
46class PageActionImageView;
47class Profile;
48class SelectedKeywordView;
49class StarView;
50class TabContents;
51class TemplateURLService;
52class WebIntentsButtonView;
53class ZoomView;
54
55namespace chrome {
56namespace search {
57class SearchModel;
58}
59}
60
61namespace views {
62class BubbleDelegateView;
63class Label;
64class Widget;
65}
66
67/////////////////////////////////////////////////////////////////////////////
68//
69// LocationBarView class
70//
71//   The LocationBarView class is a View subclass that paints the background
72//   of the URL bar strip and contains its content.
73//
74/////////////////////////////////////////////////////////////////////////////
75class LocationBarView : public LocationBar,
76                        public LocationBarTesting,
77                        public views::View,
78                        public views::DragController,
79                        public OmniboxEditController,
80                        public DropdownBarHostDelegate,
81                        public chrome::search::SearchModelObserver,
82                        public TemplateURLServiceObserver,
83                        public content::NotificationObserver,
84                        public PrefObserver {
85 public:
86  // The location bar view's class name.
87  static const char kViewClassName[];
88
89  // DropdownBarHostDelegate
90  virtual void SetFocusAndSelection(bool select_all) OVERRIDE;
91  virtual void SetAnimationOffset(int offset) OVERRIDE;
92
93  // chrome::search::SearchModelObserver:
94  virtual void ModeChanged(const chrome::search::Mode& old_mode,
95                           const chrome::search::Mode& new_mode) OVERRIDE;
96
97  // Returns the offset used while animating.
98  int animation_offset() const { return animation_offset_; }
99
100  class Delegate {
101   public:
102    // Should return the current tab contents.
103    virtual TabContents* GetTabContents() const = 0;
104
105    // Returns the InstantController, or NULL if there isn't one.
106    virtual InstantController* GetInstant() = 0;
107
108    // Creates Widget for the given delegate.
109    virtual views::Widget* CreateViewsBubble(
110        views::BubbleDelegateView* bubble_delegate) = 0;
111
112    // Creates PageActionImageView. Caller gets an ownership.
113    virtual PageActionImageView* CreatePageActionImageView(
114        LocationBarView* owner,
115        ExtensionAction* action) = 0;
116
117    // Returns ContentSettingBubbleModelDelegate.
118    virtual ContentSettingBubbleModelDelegate*
119        GetContentSettingBubbleModelDelegate() = 0;
120
121    // Shows page information in the given web contents.
122    virtual void ShowPageInfo(content::WebContents* web_contents,
123                              const GURL& url,
124                              const content::SSLStatus& ssl,
125                              bool show_history) = 0;
126
127    // Called by the location bar view when the user starts typing in the edit.
128    // This forces our security style to be UNKNOWN for the duration of the
129    // editing.
130    virtual void OnInputInProgress(bool in_progress) = 0;
131
132   protected:
133    virtual ~Delegate() {}
134  };
135
136  enum ColorKind {
137    BACKGROUND = 0,
138    TEXT,
139    SELECTED_TEXT,
140    DEEMPHASIZED_TEXT,
141    SECURITY_TEXT,
142  };
143
144  // The modes reflect the different scenarios where a location bar can be used.
145  // The normal mode is the mode used in a regular browser window.
146  // In popup mode, the location bar view is read only and has a slightly
147  // different presentation (font size / color).
148  // In app launcher mode, the location bar is empty and no security states or
149  // page/browser actions are displayed.
150  enum Mode {
151    NORMAL = 0,
152    POPUP,
153    APP_LAUNCHER
154  };
155
156  LocationBarView(Browser* browser,
157                  Profile* profile,
158                  CommandUpdater* command_updater,
159                  ToolbarModel* model,
160                  Delegate* delegate,
161                  chrome::search::SearchModel* search_model,
162                  Mode mode);
163
164  virtual ~LocationBarView();
165
166  // Initializes the LocationBarView.
167  void Init();
168
169  // True if this instance has been initialized by calling Init, which can only
170  // be called when the receiving instance is attached to a view container.
171  bool IsInitialized() const;
172
173  // Returns the appropriate color for the desired kind, based on the user's
174  // system theme.
175  SkColor GetColor(ToolbarModel::SecurityLevel security_level,
176                   ColorKind kind) const;
177
178  // Updates the location bar.  We also reset the bar's permanent text and
179  // security style, and, if |tab_for_state_restoring| is non-NULL, also restore
180  // saved state that the tab holds.
181  void Update(const content::WebContents* tab_for_state_restoring);
182
183  // Returns corresponding profile.
184  Profile* profile() const { return profile_; }
185
186  // Returns the delegate.
187  Delegate* delegate() const { return delegate_; }
188
189  // See comment in browser_window.h for more info.
190  void ZoomChangedForActiveTab(bool can_show_bubble);
191
192  // Sets |preview_enabled| for the PageAction View associated with this
193  // |page_action|. If |preview_enabled| is true, the view will display the
194  // PageActions icon even though it has not been activated by the extension.
195  // This is used by the ExtensionInstalledBubble to preview what the icon
196  // will look like for the user upon installation of the extension.
197  void SetPreviewEnabledPageAction(ExtensionAction* page_action,
198                                   bool preview_enabled);
199
200  // Retrieves the PageAction View which is associated with |page_action|.
201  views::View* GetPageActionView(ExtensionAction* page_action);
202
203  // Toggles the star on or off.
204  void SetStarToggled(bool on);
205
206  // Returns the star view. It may not be visible.
207  StarView* star_view() { return star_view_; }
208
209  // Shows the bookmark prompt.
210  void ShowBookmarkPrompt();
211
212  // Shows the Chrome To Mobile bubble.
213  void ShowChromeToMobileBubble();
214
215  // Returns the screen coordinates of the location entry (where the URL text
216  // appears, not where the icons are shown).
217  gfx::Point GetLocationEntryOrigin() const;
218
219  // Invoked from OmniboxViewWin to show the instant suggestion.
220  void SetInstantSuggestion(const string16& text);
221
222  // Returns the current instant suggestion text.
223  string16 GetInstantSuggestion() const;
224
225  // Sets whether the location entry can accept focus.
226  void SetLocationEntryFocusable(bool focusable);
227
228  // Returns true if the location entry is focusable and visible in
229  // the root view.
230  bool IsLocationEntryFocusableInRootView() const;
231
232  // Sizing functions
233  virtual gfx::Size GetPreferredSize() OVERRIDE;
234
235  // Layout and Painting functions
236  virtual void Layout() OVERRIDE;
237  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
238
239  // No focus border for the location bar, the caret is enough.
240  virtual void OnPaintFocusBorder(gfx::Canvas* canvas) OVERRIDE { }
241
242  // Set if we should show a focus rect while the location entry field is
243  // focused. Used when the toolbar is in full keyboard accessibility mode.
244  // Repaints if necessary.
245  virtual void SetShowFocusRect(bool show);
246
247  // Select all of the text. Needed when the user tabs through controls
248  // in the toolbar in full keyboard accessibility mode.
249  virtual void SelectAll();
250
251  const gfx::Font& font() const { return font_; }
252
253#if defined(OS_WIN) && !defined(USE_AURA)
254  // Event Handlers
255  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
256  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;
257  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE;
258  virtual void OnMouseCaptureLost() OVERRIDE;
259#endif
260
261  LocationIconView* location_icon_view() { return location_icon_view_; }
262  const LocationIconView* location_icon_view() const {
263    return location_icon_view_;
264  }
265
266  views::View* location_entry_view() const { return location_entry_view_; }
267
268  chrome::search::SearchModel* search_model() const {
269    return search_model_;
270  }
271
272  // Overridden from OmniboxEditController:
273  virtual void OnAutocompleteAccept(const GURL& url,
274                                    WindowOpenDisposition disposition,
275                                    content::PageTransition transition,
276                                    const GURL& alternate_nav_url) OVERRIDE;
277  virtual void OnChanged() OVERRIDE;
278  virtual void OnSelectionBoundsChanged() OVERRIDE;
279  virtual void OnInputInProgress(bool in_progress) OVERRIDE;
280  virtual void OnKillFocus() OVERRIDE;
281  virtual void OnSetFocus() OVERRIDE;
282  virtual gfx::Image GetFavicon() const OVERRIDE;
283  virtual string16 GetTitle() const OVERRIDE;
284  virtual InstantController* GetInstant() OVERRIDE;
285  virtual TabContents* GetTabContents() const OVERRIDE;
286
287  // Overridden from views::View:
288  virtual std::string GetClassName() const OVERRIDE;
289  virtual bool SkipDefaultKeyEventProcessing(
290      const ui::KeyEvent& event) OVERRIDE;
291  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
292  virtual bool HasFocus() const OVERRIDE;
293
294  // Overridden from views::DragController:
295  virtual void WriteDragDataForView(View* sender,
296                                    const gfx::Point& press_pt,
297                                    OSExchangeData* data) OVERRIDE;
298  virtual int GetDragOperationsForView(View* sender,
299                                       const gfx::Point& p) OVERRIDE;
300  virtual bool CanStartDragForView(View* sender,
301                                   const gfx::Point& press_pt,
302                                   const gfx::Point& p) OVERRIDE;
303
304  // Overridden from LocationBar:
305  virtual void ShowFirstRunBubble() OVERRIDE;
306  virtual void SetInstantSuggestion(
307      const InstantSuggestion& suggestion) OVERRIDE;
308  virtual string16 GetInputString() const OVERRIDE;
309  virtual WindowOpenDisposition GetWindowOpenDisposition() const OVERRIDE;
310  virtual content::PageTransition GetPageTransition() const OVERRIDE;
311  virtual void AcceptInput() OVERRIDE;
312  virtual void FocusLocation(bool select_all) OVERRIDE;
313  virtual void FocusSearch() OVERRIDE;
314  virtual void UpdateContentSettingsIcons() OVERRIDE;
315  virtual void UpdatePageActions() OVERRIDE;
316  virtual void InvalidatePageActions() OVERRIDE;
317  virtual void UpdateWebIntentsButton() OVERRIDE;
318  virtual void UpdateOpenPDFInReaderPrompt() OVERRIDE;
319  virtual void SaveStateToContents(content::WebContents* contents) OVERRIDE;
320  virtual void Revert() OVERRIDE;
321  virtual const OmniboxView* GetLocationEntry() const OVERRIDE;
322  virtual OmniboxView* GetLocationEntry() OVERRIDE;
323  virtual LocationBarTesting* GetLocationBarForTesting() OVERRIDE;
324
325  // Overridden from LocationBarTesting:
326  virtual int PageActionCount() OVERRIDE;
327  virtual int PageActionVisibleCount() OVERRIDE;
328  virtual ExtensionAction* GetPageAction(size_t index) OVERRIDE;
329  virtual ExtensionAction* GetVisiblePageAction(size_t index) OVERRIDE;
330  virtual void TestPageActionPressed(size_t index) OVERRIDE;
331  virtual void TestActionBoxMenuItemSelected(int command_id) OVERRIDE;
332  virtual bool GetBookmarkStarVisibility() OVERRIDE;
333
334  // Overridden from TemplateURLServiceObserver
335  virtual void OnTemplateURLServiceChanged() OVERRIDE;
336
337  // Overridden from content::NotificationObserver
338  virtual void Observe(int type,
339                       const content::NotificationSource& source,
340                       const content::NotificationDetails& details) OVERRIDE;
341
342  // Overridden from PrefObserver
343  virtual void OnPreferenceChanged(PrefServiceBase* service,
344                                   const std::string& pref_name) OVERRIDE;
345
346  // Returns the height of the control without the top and bottom
347  // edges(i.e.  the height of the edit control inside).  If
348  // |use_preferred_size| is true this will be the preferred height,
349  // otherwise it will be the current height.
350  int GetInternalHeight(bool use_preferred_size);
351
352  // Space between items in the location bar.
353  static int GetItemPadding();
354
355  // Space between the edges and the items next to them.
356  static int GetEdgeItemPadding();
357
358  // Thickness of the left and right edges of the omnibox, in normal mode.
359  static const int kNormalHorizontalEdgeThickness;
360  // Thickness of the top and bottom edges of the omnibox.
361  static const int kVerticalEdgeThickness;
362  // Amount of padding built into the standard omnibox icons.
363  static const int kIconInternalPadding;
364  // Space between the edge and a bubble.
365  static const int kBubbleHorizontalPadding;
366
367 protected:
368  virtual void OnFocus() OVERRIDE;
369
370 private:
371  typedef std::vector<ContentSettingImageView*> ContentSettingViews;
372
373  friend class PageActionImageView;
374  friend class PageActionWithBadgeView;
375  typedef std::vector<PageActionWithBadgeView*> PageActionViews;
376
377#if defined(USE_AURA)
378  // Observer that informs the LocationBarView when the animation is done.
379  class FadeAnimationObserver : public ui::ImplicitAnimationObserver {
380   public:
381    explicit FadeAnimationObserver(LocationBarView* location_bar_view);
382    virtual ~FadeAnimationObserver();
383
384    // ui::ImplicitAnimationObserver overrides:
385    virtual void OnImplicitAnimationsCompleted() OVERRIDE;
386
387   private:
388    // The location bar view being animated.  Not owned.
389    LocationBarView* location_bar_view_;
390
391    DISALLOW_COPY_AND_ASSIGN(FadeAnimationObserver);
392  };
393#endif  // USE_AURA
394
395  // Returns the amount of horizontal space (in pixels) out of
396  // |location_bar_width| that is not taken up by the actual text in
397  // location_entry_.
398  int AvailableWidth(int location_bar_width);
399
400  // If |view| fits in |available_width|, it is made visible and positioned at
401  // the leading or trailing end of |bounds|, which are then shrunk
402  // appropriately.  Otherwise |view| is made invisible.
403  // Note: |view| is expected to have already been positioned and sized
404  // vertically.
405  void LayoutView(views::View* view,
406                  int padding,
407                  int available_width,
408                  bool leading,
409                  gfx::Rect* bounds);
410
411  // Update the visibility state of the Content Blocked icons to reflect what is
412  // actually blocked on the current page.
413  void RefreshContentSettingViews();
414
415  // Delete all page action views that we have created.
416  void DeletePageActionViews();
417
418  // Update the views for the Page Actions, to reflect state changes for
419  // PageActions.
420  void RefreshPageActionViews();
421
422  // Update the view for the zoom icon based on the current tab's zoom.
423  void RefreshZoomView();
424
425  // Sets the visibility of view to new_vis.
426  void ToggleVisibility(bool new_vis, views::View* view);
427
428#if !defined(USE_AURA)
429  // Helper for the Mouse event handlers that does all the real work.
430  void OnMouseEvent(const ui::MouseEvent& event, UINT msg);
431#endif
432
433  // Returns true if the suggest text is valid.
434  bool HasValidSuggestText() const;
435
436  // Helper to show the first run info bubble.
437  void ShowFirstRunBubbleInternal();
438
439  // Draw backgrounds and borders for page actions.  Must be called
440  // after layout, so the |page_action_views_| have their bounds.
441  void PaintPageActionBackgrounds(gfx::Canvas* canvas);
442
443#if defined(USE_AURA)
444  // Fade in the location bar view so the icons come in gradually.
445  void StartFadeAnimation();
446
447  // Stops the fade animation, if it is playing.  Otherwise does nothing.
448  void StopFadeAnimation();
449
450  // Cleans up layers used for the animation.
451  void CleanupFadeAnimation();
452#endif
453
454  // The Browser this LocationBarView is in.  Note that at least
455  // chromeos::SimpleWebViewDialog uses a LocationBarView outside any browser
456  // window, so this may be NULL.
457  Browser* browser_;
458
459  // The Autocomplete Edit field.
460  scoped_ptr<OmniboxView> location_entry_;
461
462  // The profile which corresponds to this View.
463  Profile* profile_;
464
465  // Command updater which corresponds to this View.
466  CommandUpdater* command_updater_;
467
468  // The model.
469  ToolbarModel* model_;
470
471  // Our delegate.
472  Delegate* delegate_;
473
474  // Weak, owned by browser.
475  // This is null if there is no browser instance.
476  chrome::search::SearchModel* search_model_;
477
478  // This is the string of text from the autocompletion session that the user
479  // entered or selected.
480  string16 location_input_;
481
482  // The user's desired disposition for how their input should be opened
483  WindowOpenDisposition disposition_;
484
485  // The transition type to use for the navigation
486  content::PageTransition transition_;
487
488  // Font used by edit and some of the hints.
489  gfx::Font font_;
490
491  // An object used to paint the normal-mode background.
492  scoped_ptr<views::Painter> background_painter_;
493
494  // An object used to paint the focus border when search mode is |NTP|.
495  scoped_ptr<views::Painter> search_focus_painter_;
496
497  // An icon to the left of the edit field.
498  LocationIconView* location_icon_view_;
499
500  // A bubble displayed for EV HTTPS sites.
501  EVBubbleView* ev_bubble_view_;
502
503  // Location_entry view
504  views::View* location_entry_view_;
505
506  // The following views are used to provide hints and remind the user as to
507  // what is going in the edit. They are all added a children of the
508  // LocationBarView. At most one is visible at a time. Preference is
509  // given to the keyword_view_, then hint_view_.
510  // These autocollapse when the edit needs the room.
511
512  // Shown if the user has selected a keyword.
513  SelectedKeywordView* selected_keyword_view_;
514
515  // View responsible for showing suggested text. This is NULL when there is no
516  // suggested text.
517  views::Label* suggested_text_view_;
518
519  // Shown if the selected url has a corresponding keyword.
520  KeywordHintView* keyword_hint_view_;
521
522  // The content setting views.
523  ContentSettingViews content_setting_views_;
524
525  // The zoom icon.
526  ZoomView* zoom_view_;
527
528  // The icon to open a PDF in Reader.
529  OpenPDFInReaderView* open_pdf_in_reader_view_;
530
531  // The current page actions.
532  std::vector<ExtensionAction*> page_actions_;
533
534  // The page action icon views.
535  PageActionViews page_action_views_;
536
537  // The star.
538  StarView* star_view_;
539
540  // The web intents choose-another-service button
541  WebIntentsButtonView* web_intents_button_view_;
542
543  // The action box button (plus).
544  ActionBoxButtonView* action_box_button_view_;
545
546  // The mode that dictates how the bar shows.
547  Mode mode_;
548
549  // True if we should show a focus rect while the location entry field is
550  // focused. Used when the toolbar is in full keyboard accessibility mode.
551  bool show_focus_rect_;
552
553  // True if Instant Extended API is enabled.
554  const bool instant_extended_api_enabled_;
555
556  // This is in case we're destroyed before the model loads. We need to make
557  // Add/RemoveObserver calls.
558  TemplateURLService* template_url_service_;
559
560  // Tracks this preference to determine whether bookmark editing is allowed.
561  BooleanPrefMember edit_bookmarks_enabled_;
562
563  // While animating, the host clips the widget and draws only the bottom
564  // part of it. The view needs to know the pixel offset at which we are drawing
565  // the widget so that we can draw the curved edges that attach to the toolbar
566  // in the right location.
567  int animation_offset_;
568
569  // Used to register for notifications received by NotificationObserver.
570  content::NotificationRegistrar registrar_;
571
572#if defined(USE_AURA)
573  // Observer for a fade-in animation.
574  scoped_ptr<FadeAnimationObserver> fade_animation_observer_;
575#endif
576
577  DISALLOW_IMPLICIT_CONSTRUCTORS(LocationBarView);
578};
579
580#endif  // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
581