blob: 13886544882b97ba44307cf72891526d762c9446 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/basictypes.h"
#include "base/observer_list.h"
#include "chrome/browser/autocomplete/autocomplete_controller.h"
#include "chrome/browser/autocomplete/autocomplete_result.h"
#include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
class OmniboxPopupModelObserver;
class OmniboxPopupView;
namespace gfx {
class Image;
class OmniboxPopupModel {
// See selected_line_state_ for details.
enum LineState {
OmniboxPopupModel(OmniboxPopupView* popup_view, OmniboxEditModel* edit_model);
// Computes the maximum width, in pixels, that can be allocated for the two
// parts of an autocomplete result, i.e. the contents and the description.
static void ComputeMatchMaxWidths(int contents_width,
int separator_width,
int description_width,
int available_width,
bool allow_shrinking_contents,
int* contents_max_width,
int* description_max_width);
// Returns true if the popup is currently open.
bool IsOpen() const;
OmniboxPopupView* view() const { return view_; }
// Returns the AutocompleteController used by this popup.
AutocompleteController* autocomplete_controller() const {
return edit_model_->autocomplete_controller();
const AutocompleteResult& result() const {
return autocomplete_controller()->result();
size_t hovered_line() const { return hovered_line_; }
// Call to change the hovered line. |line| should be within the range of
// valid lines (to enable hover) or kNoMatch (to disable hover).
void SetHoveredLine(size_t line);
size_t selected_line() const { return selected_line_; }
LineState selected_line_state() const { return selected_line_state_; }
// Call to change the selected line. This will update all state and repaint
// the necessary parts of the window, as well as updating the edit with the
// new temporary text. |line| will be clamped to the range of valid lines.
// |reset_to_default| is true when the selection is being reset back to the
// default match, and thus there is no temporary text (and no
// |manually_selected_match_|). If |force| is true then the selected line will
// be updated forcibly even if the |line| is same as the current selected
// line.
// NOTE: This assumes the popup is open, and thus both old and new values for
// the selected line should not be kNoMatch.
void SetSelectedLine(size_t line, bool reset_to_default, bool force);
// Called when the user hits escape after arrowing around the popup. This
// will change the selected line back to the default match and redraw.
void ResetToDefaultMatch();
// Immediately updates and opens the popup if necessary, then moves the
// current selection down (|count| > 0) or up (|count| < 0), clamping to the
// first or last result if necessary. If |count| == 0, the selection will be
// unchanged, but the popup will still redraw and modify the text in the
// OmniboxEditModel.
void Move(int count);
// If the selected line has both a normal match and a keyword match, this can
// be used to choose which to select. It is an error to call this when the
// selected line does not have both matches (or there is no selection).
void SetSelectedLineState(LineState state);
// Called when the user hits shift-delete. This should determine if the item
// can be removed from history, and if so, remove it and update the popup.
void TryDeletingCurrentItem();
// If |match| is from an extension, returns the extension icon; otherwise
// returns an empty Image.
gfx::Image GetIconIfExtensionMatch(const AutocompleteMatch& match) const;
// The match the user has manually chosen, if any.
const AutocompleteResult::Selection& manually_selected_match() const {
return manually_selected_match_;
// Invoked from the edit model any time the result set of the controller
// changes.
void OnResultChanged();
// Add and remove observers.
void AddObserver(OmniboxPopupModelObserver* observer);
void RemoveObserver(OmniboxPopupModelObserver* observer);
// The token value for selected_line_, hover_line_ and functions dealing with
// a "line number" that indicates "no line".
static const size_t kNoMatch;
OmniboxPopupView* view_;
OmniboxEditModel* edit_model_;
// The line that's currently hovered. If we're not drawing a hover rect,
// this will be kNoMatch, even if the cursor is over the popup contents.
size_t hovered_line_;
// The currently selected line. This is kNoMatch when nothing is selected,
// which should only be true when the popup is closed.
size_t selected_line_;
// If the selected line has both a normal match and a keyword match, this
// determines whether the normal match (if NORMAL) or the keyword match
// (if KEYWORD) is selected.
LineState selected_line_state_;
// The match the user has manually chosen, if any.
AutocompleteResult::Selection manually_selected_match_;
// Observers.
ObserverList<OmniboxPopupModelObserver> observers_;