Home | History | Annotate | Download | only in autocomplete
      1 // Copyright (c) 2011 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_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_MAC_H_
      6 #define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_MAC_H_
      7 #pragma once
      8 
      9 #import <Cocoa/Cocoa.h>
     10 
     11 #include <string>
     12 
     13 #include "base/basictypes.h"
     14 #include "base/memory/scoped_nsobject.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "chrome/browser/autocomplete/autocomplete.h"
     17 #include "chrome/browser/autocomplete/autocomplete_match.h"
     18 #include "chrome/browser/autocomplete/autocomplete_popup_view.h"
     19 #import "chrome/browser/ui/cocoa/location_bar/instant_opt_in_controller.h"
     20 #include "ui/gfx/font.h"
     21 #include "webkit/glue/window_open_disposition.h"
     22 
     23 
     24 class AutocompleteEditModel;
     25 class AutocompleteEditViewMac;
     26 @class AutocompleteMatrix;
     27 class AutocompletePopupModel;
     28 @class InstantOptInController;
     29 @class NSImage;
     30 class Profile;
     31 
     32 // Implements AutocompletePopupView using a raw NSWindow containing an
     33 // NSTableView.
     34 //
     35 // TODO(rohitrao): This class is set up in a way that makes testing hard.
     36 // Refactor and write unittests.  http://crbug.com/9977
     37 
     38 class AutocompletePopupViewMac : public AutocompletePopupView,
     39                                  public InstantOptInControllerDelegate {
     40  public:
     41   AutocompletePopupViewMac(AutocompleteEditViewMac* edit_view,
     42                            AutocompleteEditModel* edit_model,
     43                            Profile* profile,
     44                            NSTextField* field);
     45   virtual ~AutocompletePopupViewMac();
     46 
     47   // Implement the InstantOptInControllerDelegate interface.
     48   virtual void UserPressedOptIn(bool opt_in);
     49 
     50   // Implement the AutocompletePopupView interface.
     51   virtual bool IsOpen() const;
     52   virtual void InvalidateLine(size_t line) {
     53     // TODO(shess): Verify that there is no need to implement this.
     54     // This is currently used in two places in the model:
     55     //
     56     // When setting the selected line, the selected line is
     57     // invalidated, then the selected line is changed, then the new
     58     // selected line is invalidated, then PaintUpdatesNow() is called.
     59     // For us PaintUpdatesNow() should be sufficient.
     60     //
     61     // Same thing happens when changing the hovered line, except with
     62     // no call to PaintUpdatesNow().  Since this code does not
     63     // currently support special display of the hovered line, there's
     64     // nothing to do here.
     65     //
     66     // deanm indicates that this is an anti-flicker optimization,
     67     // which we probably cannot utilize (and may not need) so long as
     68     // we're using NSTableView to implement the popup contents.  We
     69     // may need to move away from NSTableView to implement hover,
     70     // though.
     71   }
     72   virtual void UpdatePopupAppearance();
     73 
     74   virtual gfx::Rect GetTargetBounds();
     75 
     76   // Set |line| to be selected.
     77   void SetSelectedLine(size_t line);
     78 
     79   // This is only called by model in SetSelectedLine() after updating
     80   // everything.  Popup should already be visible.
     81   virtual void PaintUpdatesNow();
     82 
     83   virtual void OnDragCanceled() {}
     84 
     85   // Opens the URL corresponding to the given |row|.  If |force_background| is
     86   // true, forces the URL to open in a background tab.  Otherwise, determines
     87   // the proper window open disposition from the modifier flags on |[NSApp
     88   // currentEvent]|.
     89   void OpenURLForRow(int row, bool force_background);
     90 
     91   // Return the text to show for the match, based on the match's
     92   // contents and description.  Result will be in |font|, with the
     93   // boldfaced version used for matches.
     94   static NSAttributedString* MatchText(const AutocompleteMatch& match,
     95                                 gfx::Font& font,
     96                                 float cellWidth);
     97 
     98   // Helper for MatchText() to allow sharing code between the contents
     99   // and description cases.  Returns NSMutableAttributedString as a
    100   // convenience for MatchText().
    101   static NSMutableAttributedString* DecorateMatchedString(
    102       const string16 &matchString,
    103       const AutocompleteMatch::ACMatchClassifications &classifications,
    104       NSColor* textColor, NSColor* dimTextColor, gfx::Font& font);
    105 
    106   // Helper for MatchText() to elide a marked-up string using
    107   // gfx::ElideText() as a model.  Modifies |aString| in place.
    108   // TODO(shess): Consider breaking AutocompleteButtonCell out of this
    109   // code, and modifying it to have something like -setMatch:, so that
    110   // these convolutions to expose internals for testing can be
    111   // cleaner.
    112   static NSMutableAttributedString* ElideString(
    113       NSMutableAttributedString* aString,
    114       const string16 originalString,
    115       const gfx::Font& font,
    116       const float cellWidth);
    117 
    118  private:
    119   // Returns the AutocompleteMatrix for this popup view.
    120   AutocompleteMatrix* GetAutocompleteMatrix();
    121 
    122   // Create the popup_ instance if needed.
    123   void CreatePopupIfNeeded();
    124 
    125   // Calculate the appropriate position for the popup based on the
    126   // field's screen position and the given target for the matrix
    127   // height, and makes the popup visible.  Animates to the new frame
    128   // if the popup shrinks, snaps to the new frame if the popup grows,
    129   // allows existing animations to continue if the size doesn't
    130   // change.
    131   void PositionPopup(const CGFloat matrixHeight);
    132 
    133   // Returns the NSImage that should be used as an icon for the given match.
    134   NSImage* ImageForMatch(const AutocompleteMatch& match);
    135 
    136   // Returns whether or not to show the instant opt-in prompt.
    137   bool ShouldShowInstantOptIn();
    138 
    139   scoped_ptr<AutocompletePopupModel> model_;
    140   AutocompleteEditViewMac* edit_view_;
    141   NSTextField* field_;  // owned by tab controller
    142 
    143   // Child window containing a matrix which implements the popup.
    144   scoped_nsobject<NSWindow> popup_;
    145   scoped_nsobject<InstantOptInController> opt_in_controller_;
    146   NSRect targetPopupFrame_;
    147 
    148   DISALLOW_COPY_AND_ASSIGN(AutocompletePopupViewMac);
    149 };
    150 
    151 #endif  // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_MAC_H_
    152