Home | History | Annotate | Download | only in omnibox
      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_OMNIBOX_OMNIBOX_POPUP_MODEL_H_
      6 #define CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MODEL_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/observer_list.h"
     10 #include "chrome/browser/autocomplete/autocomplete_controller.h"
     11 #include "chrome/browser/autocomplete/autocomplete_result.h"
     12 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
     13 
     14 class OmniboxPopupModelObserver;
     15 class OmniboxPopupView;
     16 
     17 namespace gfx {
     18 class Image;
     19 }
     20 
     21 class OmniboxPopupModel {
     22  public:
     23   // See selected_line_state_ for details.
     24   enum LineState {
     25     NORMAL = 0,
     26     KEYWORD
     27   };
     28 
     29   OmniboxPopupModel(OmniboxPopupView* popup_view, OmniboxEditModel* edit_model);
     30   ~OmniboxPopupModel();
     31 
     32   // Computes the maximum width, in pixels, that can be allocated for the two
     33   // parts of an autocomplete result, i.e. the contents and the description.
     34   static void ComputeMatchMaxWidths(int contents_width,
     35                                     int separator_width,
     36                                     int description_width,
     37                                     int available_width,
     38                                     bool allow_shrinking_contents,
     39                                     int* contents_max_width,
     40                                     int* description_max_width);
     41 
     42   // Returns true if the popup is currently open.
     43   bool IsOpen() const;
     44 
     45   OmniboxPopupView* view() const { return view_; }
     46 
     47   // Returns the AutocompleteController used by this popup.
     48   AutocompleteController* autocomplete_controller() const {
     49     return edit_model_->autocomplete_controller();
     50   }
     51 
     52   const AutocompleteResult& result() const {
     53     return autocomplete_controller()->result();
     54   }
     55 
     56   size_t hovered_line() const { return hovered_line_; }
     57 
     58   // Call to change the hovered line.  |line| should be within the range of
     59   // valid lines (to enable hover) or kNoMatch (to disable hover).
     60   void SetHoveredLine(size_t line);
     61 
     62   size_t selected_line() const { return selected_line_; }
     63 
     64   LineState selected_line_state() const { return selected_line_state_; }
     65 
     66   // Call to change the selected line.  This will update all state and repaint
     67   // the necessary parts of the window, as well as updating the edit with the
     68   // new temporary text.  |line| will be clamped to the range of valid lines.
     69   // |reset_to_default| is true when the selection is being reset back to the
     70   // default match, and thus there is no temporary text (and no
     71   // |manually_selected_match_|). If |force| is true then the selected line will
     72   // be updated forcibly even if the |line| is same as the current selected
     73   // line.
     74   // NOTE: This assumes the popup is open, and thus both old and new values for
     75   // the selected line should not be kNoMatch.
     76   void SetSelectedLine(size_t line, bool reset_to_default, bool force);
     77 
     78   // Called when the user hits escape after arrowing around the popup.  This
     79   // will change the selected line back to the default match and redraw.
     80   void ResetToDefaultMatch();
     81 
     82   // Immediately updates and opens the popup if necessary, then moves the
     83   // current selection down (|count| > 0) or up (|count| < 0), clamping to the
     84   // first or last result if necessary.  If |count| == 0, the selection will be
     85   // unchanged, but the popup will still redraw and modify the text in the
     86   // OmniboxEditModel.
     87   void Move(int count);
     88 
     89   // If the selected line has both a normal match and a keyword match, this can
     90   // be used to choose which to select. It is an error to call this when the
     91   // selected line does not have both matches (or there is no selection).
     92   void SetSelectedLineState(LineState state);
     93 
     94   // Called when the user hits shift-delete.  This should determine if the item
     95   // can be removed from history, and if so, remove it and update the popup.
     96   void TryDeletingCurrentItem();
     97 
     98   // If |match| is from an extension, returns the extension icon; otherwise
     99   // returns an empty Image.
    100   gfx::Image GetIconIfExtensionMatch(const AutocompleteMatch& match) const;
    101 
    102   // The match the user has manually chosen, if any.
    103   const AutocompleteResult::Selection& manually_selected_match() const {
    104     return manually_selected_match_;
    105   }
    106 
    107   // Invoked from the edit model any time the result set of the controller
    108   // changes.
    109   void OnResultChanged();
    110 
    111   // Add and remove observers.
    112   void AddObserver(OmniboxPopupModelObserver* observer);
    113   void RemoveObserver(OmniboxPopupModelObserver* observer);
    114 
    115   // The token value for selected_line_, hover_line_ and functions dealing with
    116   // a "line number" that indicates "no line".
    117   static const size_t kNoMatch;
    118 
    119  private:
    120   OmniboxPopupView* view_;
    121 
    122   OmniboxEditModel* edit_model_;
    123 
    124   // The line that's currently hovered.  If we're not drawing a hover rect,
    125   // this will be kNoMatch, even if the cursor is over the popup contents.
    126   size_t hovered_line_;
    127 
    128   // The currently selected line.  This is kNoMatch when nothing is selected,
    129   // which should only be true when the popup is closed.
    130   size_t selected_line_;
    131 
    132   // If the selected line has both a normal match and a keyword match, this
    133   // determines whether the normal match (if NORMAL) or the keyword match
    134   // (if KEYWORD) is selected.
    135   LineState selected_line_state_;
    136 
    137   // The match the user has manually chosen, if any.
    138   AutocompleteResult::Selection manually_selected_match_;
    139 
    140   // Observers.
    141   ObserverList<OmniboxPopupModelObserver> observers_;
    142 
    143   DISALLOW_COPY_AND_ASSIGN(OmniboxPopupModel);
    144 };
    145 
    146 #endif  // CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MODEL_H_
    147