autocomplete_popup_view_gtk.h revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1// Copyright (c) 2010 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_GTK_H_
6#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_GTK_H_
7#pragma once
8
9#include <gtk/gtk.h>
10#include <map>
11#include <string>
12
13#include "base/basictypes.h"
14#include "base/scoped_ptr.h"
15#include "chrome/browser/autocomplete/autocomplete_match.h"
16#include "chrome/browser/autocomplete/autocomplete_popup_view.h"
17#include "chrome/common/notification_observer.h"
18#include "chrome/common/notification_registrar.h"
19#include "webkit/glue/window_open_disposition.h"
20
21class AutocompleteEditModel;
22class AutocompleteEditView;
23class AutocompletePopupModel;
24class GtkThemeProvider;
25class Profile;
26class SkBitmap;
27
28class AutocompletePopupViewGtk : public AutocompletePopupView,
29                                 public NotificationObserver {
30 public:
31  AutocompletePopupViewGtk(AutocompleteEditView* edit_view,
32                           AutocompleteEditModel* edit_model,
33                           Profile* profile,
34                           GtkWidget* location_bar);
35  ~AutocompletePopupViewGtk();
36
37  // Overridden from AutocompletePopupView:
38  virtual bool IsOpen() const;
39  virtual void InvalidateLine(size_t line);
40  virtual void UpdatePopupAppearance();
41  virtual gfx::Rect GetTargetBounds();
42  virtual void PaintUpdatesNow();
43  virtual void OnDragCanceled();
44  virtual AutocompletePopupModel* GetModel();
45
46  // Overridden from NotificationObserver:
47  virtual void Observe(NotificationType type,
48                       const NotificationSource& source,
49                       const NotificationDetails& details);
50
51 private:
52  // Be friendly for unit tests.
53  friend class AutocompletePopupViewGtkTest;
54  static void SetupLayoutForMatch(
55      PangoLayout* layout,
56      const std::wstring& text,
57      const AutocompleteMatch::ACMatchClassifications& classifications,
58      const GdkColor* base_color,
59      const GdkColor* dim_color,
60      const GdkColor* url_color,
61      const std::string& prefix_text);
62
63  void Show(size_t num_results);
64  void Hide();
65
66  // Restack the popup window directly above the browser's toplevel window.
67  void StackWindow();
68
69  // Convert a y-coordinate to the closest line / result.
70  size_t LineFromY(int y);
71
72  // Accept a line of the results, for example, when the user clicks a line.
73  void AcceptLine(size_t line, WindowOpenDisposition disposition);
74
75  GdkPixbuf* IconForMatch(const AutocompleteMatch& match, bool selected);
76
77  static gboolean HandleExposeThunk(GtkWidget* widget, GdkEventExpose* event,
78                                    gpointer userdata) {
79    return reinterpret_cast<AutocompletePopupViewGtk*>(userdata)->
80        HandleExpose(widget, event);
81  }
82  gboolean HandleExpose(GtkWidget* widget, GdkEventExpose* event);
83
84  static gboolean HandleMotionThunk(GtkWidget* widget, GdkEventMotion* event,
85                                    gpointer userdata) {
86    return reinterpret_cast<AutocompletePopupViewGtk*>(userdata)->
87        HandleMotion(widget, event);
88  }
89  gboolean HandleMotion(GtkWidget* widget, GdkEventMotion* event);
90
91  static gboolean HandleButtonPressThunk(GtkWidget* widget,
92                                         GdkEventButton* event,
93                                         gpointer userdata) {
94    return reinterpret_cast<AutocompletePopupViewGtk*>(userdata)->
95        HandleButtonPress(widget, event);
96  }
97  gboolean HandleButtonPress(GtkWidget* widget, GdkEventButton* event);
98
99  static gboolean HandleButtonReleaseThunk(GtkWidget* widget,
100                                           GdkEventButton* event,
101                                           gpointer userdata) {
102    return reinterpret_cast<AutocompletePopupViewGtk*>(userdata)->
103        HandleButtonRelease(widget, event);
104  }
105  gboolean HandleButtonRelease(GtkWidget* widget, GdkEventButton* event);
106
107  scoped_ptr<AutocompletePopupModel> model_;
108  AutocompleteEditView* edit_view_;
109  GtkWidget* location_bar_;
110
111  // Our popup window, which is the only widget used, and we paint it on our
112  // own.  This widget shouldn't be exposed outside of this class.
113  GtkWidget* window_;
114  // The pango layout object created from the window, cached across exposes.
115  PangoLayout* layout_;
116
117  GtkThemeProvider* theme_provider_;
118  NotificationRegistrar registrar_;
119
120  // Used to cache GdkPixbufs and map them from the SkBitmaps they were created
121  // from.
122  typedef std::map<const SkBitmap*, GdkPixbuf*> PixbufMap;
123  PixbufMap pixbufs_;
124
125  // A list of colors which we should use for drawing the popup. These change
126  // between gtk and normal mode.
127  GdkColor border_color_;
128  GdkColor background_color_;
129  GdkColor selected_background_color_;
130  GdkColor hovered_background_color_;
131  GdkColor content_text_color_;
132  GdkColor selected_content_text_color_;
133  GdkColor content_dim_text_color_;
134  GdkColor selected_content_dim_text_color_;
135  GdkColor url_text_color_;
136  GdkColor url_selected_text_color_;
137
138  // If the user cancels a dragging action (i.e. by pressing ESC), we don't have
139  // a convenient way to release mouse capture. Instead we use this flag to
140  // simply ignore all remaining drag events, and the eventual mouse release
141  // event. Since OnDragCanceled() can be called when we're not dragging, this
142  // flag is reset to false on a mouse pressed event, to make sure we don't
143  // erroneously ignore the next drag.
144  bool ignore_mouse_drag_;
145
146  // Whether our popup is currently open / shown, or closed / hidden.
147  bool opened_;
148
149  DISALLOW_COPY_AND_ASSIGN(AutocompletePopupViewGtk);
150};
151
152#endif  // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_GTK_H_
153