summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/gtk/find_bar_gtk.h
blob: 69aef6f3c03961c79b4690ae11715a84b9334774 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_GTK_FIND_BAR_GTK_H_
#define CHROME_BROWSER_UI_GTK_FIND_BAR_GTK_H_

#include <gtk/gtk.h>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/ui/find_bar/find_bar.h"
#include "chrome/browser/ui/gtk/slide_animator_gtk.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/base/gtk/focus_store_gtk.h"
#include "ui/base/gtk/gtk_signal.h"
#include "ui/base/gtk/owned_widget_gtk.h"
#include "ui/gfx/point.h"

class Browser;
class BrowserWindowGtk;
class CustomDrawButton;
class FindBarController;
class GtkThemeService;
class NineBox;

typedef struct _GtkFloatingContainer GtkFloatingContainer;

// Currently this class contains both a model and a view.  We may want to
// eventually pull out the model specific bits and share with Windows.
class FindBarGtk : public FindBar,
                   public FindBarTesting,
                   public content::NotificationObserver {
 public:
  explicit FindBarGtk(BrowserWindowGtk* window);
  virtual ~FindBarGtk();

  GtkWidget* widget() const { return slide_widget_->widget(); }

  // Methods from FindBar.
  virtual FindBarController* GetFindBarController() const OVERRIDE;
  virtual void SetFindBarController(
      FindBarController* find_bar_controller) OVERRIDE;
  virtual void Show(bool animate) OVERRIDE;
  virtual void Hide(bool animate) OVERRIDE;
  virtual void SetFocusAndSelection() OVERRIDE;
  virtual void ClearResults(const FindNotificationDetails& results) OVERRIDE;
  virtual void StopAnimation() OVERRIDE;
  virtual void MoveWindowIfNecessary(const gfx::Rect& selection_rect,
                                     bool no_redraw) OVERRIDE;
  virtual void SetFindText(const string16& find_text) OVERRIDE;
  virtual void UpdateUIForFindResult(const FindNotificationDetails& result,
                                     const string16& find_text) OVERRIDE;
  virtual void AudibleAlert() OVERRIDE;
  virtual bool IsFindBarVisible() OVERRIDE;
  virtual void RestoreSavedFocus() OVERRIDE;
  virtual bool HasGlobalFindPasteboard() OVERRIDE;
  virtual void UpdateFindBarForChangedWebContents() OVERRIDE;
  virtual FindBarTesting* GetFindBarTesting() OVERRIDE;

  // Methods from FindBarTesting.
  virtual bool GetFindBarWindowInfo(gfx::Point* position,
                                    bool* fully_visible) OVERRIDE;
  virtual string16 GetFindText() OVERRIDE;
  virtual string16 GetFindSelectedText() OVERRIDE;
  virtual string16 GetMatchCountText() OVERRIDE;
  virtual int GetWidth() OVERRIDE;

  // Overridden from content::NotificationObserver:
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

 private:
  void InitWidgets();

  // Store the currently focused widget if it is not in the find bar.
  // This should always be called before we claim focus.
  void StoreOutsideFocus();

  // For certain keystrokes, such as up or down, we want to forward the event
  // to the renderer rather than handling it ourselves. Returns true if the
  // key event was forwarded.
  // See similar function in FindBarWin.
  bool MaybeForwardKeyEventToRenderer(GdkEventKey* event);

  // Searches for another occurrence of the entry text, moving forward if
  // |forward_search| is true.
  void FindEntryTextInContents(bool forward_search);

  void UpdateMatchLabelAppearance(bool failure);

  // Asynchronously repositions the dialog.
  void Reposition();

  // Returns the rectangle representing where to position the find bar. If
  // |avoid_overlapping_rect| is specified, the return value will be a rectangle
  // located immediately to the left of |avoid_overlapping_rect|, as long as
  // there is enough room for the dialog to draw within the bounds. If not, the
  // dialog position returned will overlap |avoid_overlapping_rect|.
  // Note: |avoid_overlapping_rect| is expected to use coordinates relative to
  // the top of the page area, (it will be converted to coordinates relative to
  // the top of the browser window, when comparing against the dialog
  // coordinates). The returned value is relative to the browser window.
  gfx::Rect GetDialogPosition(const gfx::Rect& avoid_overlapping_rect);

  // Adjust the text alignment according to the text direction of the widget
  // and |text_entry_|'s content, to make sure the real text alignment is
  // always in sync with the UI language direction.
  void AdjustTextAlignment();

  // Get the position of the findbar within the floating container.
  gfx::Point GetPosition();

  static void OnParentSet(GtkWidget* widget, GtkObject* old_parent,
                          FindBarGtk* find_bar);

  static void OnSetFloatingPosition(GtkFloatingContainer* floating_container,
                                    GtkAllocation* allocation,
                                    FindBarGtk* find_bar);

  // Callback when the entry text changes.
  static gboolean OnChanged(GtkWindow* window, FindBarGtk* find_bar);

  static gboolean OnKeyPressEvent(GtkWidget* widget, GdkEventKey* event,
                                  FindBarGtk* find_bar);
  static gboolean OnKeyReleaseEvent(GtkWidget* widget, GdkEventKey* event,
                                    FindBarGtk* find_bar);

  // Callback for previous, next, and close button.
  CHROMEGTK_CALLBACK_0(FindBarGtk, void, OnClicked);

  // Handles shapping and drawing the find bar background.
  static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* event,
                           FindBarGtk* bar);

  // Expose that draws the text entry background in GTK mode.
  static gboolean OnContentEventBoxExpose(GtkWidget* widget,
                                          GdkEventExpose* event,
                                          FindBarGtk* bar);

  // These are both used for focus management.
  static gboolean OnFocus(GtkWidget* text_entry, GtkDirectionType focus,
                          FindBarGtk* find_bar);
  static gboolean OnButtonPress(GtkWidget* text_entry, GdkEventButton* e,
                                FindBarGtk* find_bar);

  // Forwards ctrl-Home/End key bindings to the renderer.
  static void OnMoveCursor(GtkEntry* entry, GtkMovementStep step, gint count,
                           gboolean selection, FindBarGtk* bar);

  // Handles Enter key.
  CHROMEGTK_CALLBACK_0(FindBarGtk, void, OnActivate);

  // After Copy and cut handlers.
  CHROMEGTK_CALLBACK_0(FindBarGtk, void, HandleAfterCopyOrCutClipboard);

  static void OnWidgetDirectionChanged(GtkWidget* widget,
                                       GtkTextDirection previous_direction,
                                       FindBarGtk* find_bar) {
    find_bar->AdjustTextAlignment();
  }

  static void OnKeymapDirectionChanged(GdkKeymap* keymap,
                                       FindBarGtk* find_bar) {
    find_bar->AdjustTextAlignment();
  }

  CHROMEGTK_CALLBACK_1(FindBarGtk, gboolean, OnFocusIn, GdkEventFocus*);
  CHROMEGTK_CALLBACK_1(FindBarGtk, gboolean, OnFocusOut, GdkEventFocus*);

  Browser* browser_;
  BrowserWindowGtk* window_;

  // Provides colors and information about GTK.
  GtkThemeService* theme_service_;

  // The widget that animates the slide-in and -out of the findbar.
  scoped_ptr<SlideAnimatorGtk> slide_widget_;

  // A GtkAlignment that is the child of |slide_widget_|.
  GtkWidget* container_;

  // Cached allocation of |container_|. We keep this on hand so that we can
  // reset the widget's shape when the width/height change.
  int container_width_;
  int container_height_;

  // The widget where text is entered.
  GtkWidget* text_entry_;

  // An event box and alignment that wrap the entry area and the count label.
  GtkWidget* content_event_box_;
  GtkWidget* content_alignment_;

  // The border around the text entry area.
  GtkWidget* border_bin_;
  GtkWidget* border_bin_alignment_;

  // The next and previous match buttons.
  scoped_ptr<CustomDrawButton> find_previous_button_;
  scoped_ptr<CustomDrawButton> find_next_button_;

  // The GtkLabel listing how many results were found.
  GtkWidget* match_count_label_;
  GtkWidget* match_count_event_box_;
  // Cache whether the match count label is showing failure or not so that
  // we can update its appearance without changing its semantics.
  bool match_label_failure_;

  // The X to close the find bar.
  scoped_ptr<CustomDrawButton> close_button_;

  // The last matchcount number we reported to the user.
  int last_reported_matchcount_;

  // Pointer back to the owning controller.
  FindBarController* find_bar_controller_;

  // Saves where the focus used to be whenever we get it.
  ui::FocusStoreGtk focus_store_;

  // If true, the change signal for the text entry is ignored.
  bool ignore_changed_signal_;

  // This is the width of widget(). We cache it so we can recognize whether
  // allocate signals have changed it, and if so take appropriate actions.
  int current_fixed_width_;

  scoped_ptr<NineBox> dialog_background_;

  // The selection rect we are currently showing. We cache it to avoid covering
  // it up.
  gfx::Rect selection_rect_;

  content::NotificationRegistrar registrar_;

  DISALLOW_COPY_AND_ASSIGN(FindBarGtk);
};

#endif  // CHROME_BROWSER_UI_GTK_FIND_BAR_GTK_H_