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