1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_GTK_H_
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_GTK_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gtk/gtk.h>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
11513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include <string>
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
15513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/autocomplete/autocomplete_match.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autocomplete/autocomplete_popup_view.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_observer.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h"
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/font.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/window_open_disposition.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AutocompleteEditModel;
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AutocompleteEditView;
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AutocompletePopupModel;
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass GtkThemeService;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass Profile;
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SkBitmap;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass AutocompletePopupViewGtk : public AutocompletePopupView,
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 public NotificationObserver {
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AutocompletePopupViewGtk(const gfx::Font& font,
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                           AutocompleteEditView* edit_view,
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           AutocompleteEditModel* edit_model,
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           Profile* profile,
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           GtkWidget* location_bar);
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~AutocompletePopupViewGtk();
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Overridden from AutocompletePopupView:
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual bool IsOpen() const;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void InvalidateLine(size_t line);
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void UpdatePopupAppearance();
43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  virtual gfx::Rect GetTargetBounds();
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void PaintUpdatesNow();
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void OnDragCanceled();
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Overridden from NotificationObserver:
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Observe(NotificationType type,
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationSource& source,
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationDetails& details);
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
53513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Be friendly for unit tests.
54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  friend class AutocompletePopupViewGtkTest;
55513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  static void SetupLayoutForMatch(
56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      PangoLayout* layout,
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      const string16& text,
58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      const AutocompleteMatch::ACMatchClassifications& classifications,
59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      const GdkColor* base_color,
60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      const GdkColor* dim_color,
61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      const GdkColor* url_color,
62513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      const std::string& prefix_text);
63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Show(size_t num_results);
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Hide();
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Restack the popup window directly above the browser's toplevel window.
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void StackWindow();
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Convert a y-coordinate to the closest line / result.
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t LineFromY(int y);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Accept a line of the results, for example, when the user clicks a line.
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AcceptLine(size_t line, WindowOpenDisposition disposition);
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkPixbuf* IconForMatch(const AutocompleteMatch& match, bool selected);
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static gboolean HandleExposeThunk(GtkWidget* widget, GdkEventExpose* event,
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    gpointer userdata) {
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return reinterpret_cast<AutocompletePopupViewGtk*>(userdata)->
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        HandleExpose(widget, event);
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gboolean HandleExpose(GtkWidget* widget, GdkEventExpose* event);
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static gboolean HandleMotionThunk(GtkWidget* widget, GdkEventMotion* event,
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    gpointer userdata) {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return reinterpret_cast<AutocompletePopupViewGtk*>(userdata)->
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        HandleMotion(widget, event);
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gboolean HandleMotion(GtkWidget* widget, GdkEventMotion* event);
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static gboolean HandleButtonPressThunk(GtkWidget* widget,
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         GdkEventButton* event,
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         gpointer userdata) {
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return reinterpret_cast<AutocompletePopupViewGtk*>(userdata)->
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        HandleButtonPress(widget, event);
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gboolean HandleButtonPress(GtkWidget* widget, GdkEventButton* event);
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static gboolean HandleButtonReleaseThunk(GtkWidget* widget,
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           GdkEventButton* event,
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           gpointer userdata) {
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return reinterpret_cast<AutocompletePopupViewGtk*>(userdata)->
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        HandleButtonRelease(widget, event);
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gboolean HandleButtonRelease(GtkWidget* widget, GdkEventButton* event);
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<AutocompletePopupModel> model_;
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AutocompleteEditView* edit_view_;
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* location_bar_;
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Our popup window, which is the only widget used, and we paint it on our
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // own.  This widget shouldn't be exposed outside of this class.
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* window_;
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The pango layout object created from the window, cached across exposes.
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PangoLayout* layout_;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GtkThemeService* theme_service_;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationRegistrar registrar_;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Font used for suggestions after being derived from the constructor's
12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // |font|.
12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  gfx::Font font_;
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Used to cache GdkPixbufs and map them from the SkBitmaps they were created
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // from.
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::map<const SkBitmap*, GdkPixbuf*> PixbufMap;
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PixbufMap pixbufs_;
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A list of colors which we should use for drawing the popup. These change
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // between gtk and normal mode.
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkColor border_color_;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkColor background_color_;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkColor selected_background_color_;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkColor hovered_background_color_;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkColor content_text_color_;
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkColor selected_content_text_color_;
138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  GdkColor content_dim_text_color_;
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  GdkColor selected_content_dim_text_color_;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkColor url_text_color_;
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkColor url_selected_text_color_;
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the user cancels a dragging action (i.e. by pressing ESC), we don't have
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // a convenient way to release mouse capture. Instead we use this flag to
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // simply ignore all remaining drag events, and the eventual mouse release
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // event. Since OnDragCanceled() can be called when we're not dragging, this
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // flag is reset to false on a mouse pressed event, to make sure we don't
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // erroneously ignore the next drag.
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ignore_mouse_drag_;
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Whether our popup is currently open / shown, or closed / hidden.
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool opened_;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(AutocompletePopupViewGtk);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_GTK_H_
158