Home | History | Annotate | Download | only in gtk
      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 
     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 
    154   static void OnWidgetDirectionChanged(GtkWidget* widget,
    155                                        GtkTextDirection previous_direction,
    156                                        FindBarGtk* find_bar) {
    157     find_bar->AdjustTextAlignment();
    158   }
    159 
    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