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_UI_GTK_FIND_BAR_GTK_H_ 6 #define CHROME_BROWSER_UI_GTK_FIND_BAR_GTK_H_ 7 #pragma once 8 9 #include <gtk/gtk.h> 10 11 #include "base/basictypes.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "chrome/browser/ui/find_bar/find_bar.h" 14 #include "chrome/browser/ui/gtk/focus_store_gtk.h" 15 #include "chrome/browser/ui/gtk/owned_widget_gtk.h" 16 #include "chrome/browser/ui/gtk/slide_animator_gtk.h" 17 #include "content/common/notification_observer.h" 18 #include "content/common/notification_registrar.h" 19 #include "ui/gfx/point.h" 20 21 class Browser; 22 class BrowserWindowGtk; 23 class CustomDrawButton; 24 class FindBarController; 25 class GtkThemeService; 26 class NineBox; 27 class SlideAnimatorGtk; 28 class TabContentsContainerGtk; 29 30 typedef struct _GtkFloatingContainer GtkFloatingContainer; 31 32 // Currently this class contains both a model and a view. We may want to 33 // eventually pull out the model specific bits and share with Windows. 34 class FindBarGtk : public FindBar, 35 public FindBarTesting, 36 public NotificationObserver { 37 public: 38 explicit FindBarGtk(Browser* browser); 39 virtual ~FindBarGtk(); 40 widget()41 GtkWidget* widget() const { return slide_widget_->widget(); } 42 43 // Methods from FindBar. 44 virtual FindBarController* GetFindBarController() const; 45 virtual void SetFindBarController(FindBarController* find_bar_controller); 46 virtual void Show(bool animate); 47 virtual void Hide(bool animate); 48 virtual void SetFocusAndSelection(); 49 virtual void ClearResults(const FindNotificationDetails& results); 50 virtual void StopAnimation(); 51 virtual void MoveWindowIfNecessary(const gfx::Rect& selection_rect, 52 bool no_redraw); 53 virtual void SetFindText(const string16& find_text); 54 virtual void UpdateUIForFindResult(const FindNotificationDetails& result, 55 const string16& find_text); 56 virtual void AudibleAlert(); 57 virtual bool IsFindBarVisible(); 58 virtual void RestoreSavedFocus(); 59 virtual FindBarTesting* GetFindBarTesting(); 60 61 // Methods from FindBarTesting. 62 virtual bool GetFindBarWindowInfo(gfx::Point* position, 63 bool* fully_visible); 64 virtual string16 GetFindText(); 65 virtual string16 GetFindSelectedText(); 66 virtual string16 GetMatchCountText(); 67 68 // Overridden from NotificationObserver: 69 virtual void Observe(NotificationType type, 70 const NotificationSource& source, 71 const NotificationDetails& details); 72 73 private: 74 void InitWidgets(); 75 76 // Store the currently focused widget if it is not in the find bar. 77 // This should always be called before we claim focus. 78 void StoreOutsideFocus(); 79 80 // For certain keystrokes, such as up or down, we want to forward the event 81 // to the renderer rather than handling it ourselves. Returns true if the 82 // key event was forwarded. 83 // See similar function in FindBarWin. 84 bool MaybeForwardKeyEventToRenderer(GdkEventKey* event); 85 86 // Searches for another occurrence of the entry text, moving forward if 87 // |forward_search| is true. 88 void FindEntryTextInContents(bool forward_search); 89 90 void UpdateMatchLabelAppearance(bool failure); 91 92 // Asynchronously repositions the dialog. 93 void Reposition(); 94 95 // Returns the rectangle representing where to position the find bar. If 96 // |avoid_overlapping_rect| is specified, the return value will be a rectangle 97 // located immediately to the left of |avoid_overlapping_rect|, as long as 98 // there is enough room for the dialog to draw within the bounds. If not, the 99 // dialog position returned will overlap |avoid_overlapping_rect|. 100 // Note: |avoid_overlapping_rect| is expected to use coordinates relative to 101 // the top of the page area, (it will be converted to coordinates relative to 102 // the top of the browser window, when comparing against the dialog 103 // coordinates). The returned value is relative to the browser window. 104 gfx::Rect GetDialogPosition(gfx::Rect avoid_overlapping_rect); 105 106 // Adjust the text alignment according to the text direction of the widget 107 // and |text_entry_|'s content, to make sure the real text alignment is 108 // always in sync with the UI language direction. 109 void AdjustTextAlignment(); 110 111 // Get the position of the findbar within the floating container. 112 gfx::Point GetPosition(); 113 114 static void OnParentSet(GtkWidget* widget, GtkObject* old_parent, 115 FindBarGtk* find_bar); 116 117 static void OnSetFloatingPosition(GtkFloatingContainer* floating_container, 118 GtkAllocation* allocation, 119 FindBarGtk* find_bar); 120 121 // Callback when the entry text changes. 122 static gboolean OnChanged(GtkWindow* window, FindBarGtk* find_bar); 123 124 static gboolean OnKeyPressEvent(GtkWidget* widget, GdkEventKey* event, 125 FindBarGtk* find_bar); 126 static gboolean OnKeyReleaseEvent(GtkWidget* widget, GdkEventKey* event, 127 FindBarGtk* find_bar); 128 129 // Callback for previous, next, and close button. 130 static void OnClicked(GtkWidget* button, FindBarGtk* find_bar); 131 132 // Handles shapping and drawing the find bar background. 133 static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* event, 134 FindBarGtk* bar); 135 136 // Expose that draws the text entry background in GTK mode. 137 static gboolean OnContentEventBoxExpose(GtkWidget* widget, 138 GdkEventExpose* event, 139 FindBarGtk* bar); 140 141 // These are both used for focus management. 142 static gboolean OnFocus(GtkWidget* text_entry, GtkDirectionType focus, 143 FindBarGtk* find_bar); 144 static gboolean OnButtonPress(GtkWidget* text_entry, GdkEventButton* e, 145 FindBarGtk* find_bar); 146 147 // Forwards ctrl-Home/End key bindings to the renderer. 148 static void OnMoveCursor(GtkEntry* entry, GtkMovementStep step, gint count, 149 gboolean selection, FindBarGtk* bar); 150 151 // Handles Enter key. 152 static void OnActivate(GtkEntry* entry, FindBarGtk* bar); 153 OnWidgetDirectionChanged(GtkWidget * widget,GtkTextDirection previous_direction,FindBarGtk * find_bar)154 static void OnWidgetDirectionChanged(GtkWidget* widget, 155 GtkTextDirection previous_direction, 156 FindBarGtk* find_bar) { 157 find_bar->AdjustTextAlignment(); 158 } 159 OnKeymapDirectionChanged(GdkKeymap * keymap,FindBarGtk * find_bar)160 static void OnKeymapDirectionChanged(GdkKeymap* keymap, 161 FindBarGtk* find_bar) { 162 find_bar->AdjustTextAlignment(); 163 } 164 165 static gboolean OnFocusIn(GtkWidget* entry, GdkEventFocus* event, 166 FindBarGtk* find_bar); 167 168 static gboolean OnFocusOut(GtkWidget* entry, GdkEventFocus* event, 169 FindBarGtk* find_bar); 170 171 Browser* browser_; 172 BrowserWindowGtk* window_; 173 174 // Provides colors and information about GTK. 175 GtkThemeService* theme_service_; 176 177 // The widget that animates the slide-in and -out of the findbar. 178 scoped_ptr<SlideAnimatorGtk> slide_widget_; 179 180 // A GtkAlignment that is the child of |slide_widget_|. 181 GtkWidget* container_; 182 183 // Cached allocation of |container_|. We keep this on hand so that we can 184 // reset the widget's shape when the width/height change. 185 int container_width_; 186 int container_height_; 187 188 // The widget where text is entered. 189 GtkWidget* text_entry_; 190 191 // An event box and alignment that wrap the entry area and the count label. 192 GtkWidget* content_event_box_; 193 GtkWidget* content_alignment_; 194 195 // The border around the text entry area. 196 GtkWidget* border_bin_; 197 GtkWidget* border_bin_alignment_; 198 199 // The next and previous match buttons. 200 scoped_ptr<CustomDrawButton> find_previous_button_; 201 scoped_ptr<CustomDrawButton> find_next_button_; 202 203 // The GtkLabel listing how many results were found. 204 GtkWidget* match_count_label_; 205 GtkWidget* match_count_event_box_; 206 // Cache whether the match count label is showing failure or not so that 207 // we can update its appearance without changing its semantics. 208 bool match_label_failure_; 209 210 // The X to close the find bar. 211 scoped_ptr<CustomDrawButton> close_button_; 212 213 // The last matchcount number we reported to the user. 214 int last_reported_matchcount_; 215 216 // Pointer back to the owning controller. 217 FindBarController* find_bar_controller_; 218 219 // Saves where the focus used to be whenever we get it. 220 FocusStoreGtk focus_store_; 221 222 // If true, the change signal for the text entry is ignored. 223 bool ignore_changed_signal_; 224 225 // This is the width of widget(). We cache it so we can recognize whether 226 // allocate signals have changed it, and if so take appropriate actions. 227 int current_fixed_width_; 228 229 scoped_ptr<NineBox> dialog_background_; 230 231 // The selection rect we are currently showing. We cache it to avoid covering 232 // it up. 233 gfx::Rect selection_rect_; 234 235 NotificationRegistrar registrar_; 236 237 DISALLOW_COPY_AND_ASSIGN(FindBarGtk); 238 }; 239 240 #endif // CHROME_BROWSER_UI_GTK_FIND_BAR_GTK_H_ 241