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