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