Home | History | Annotate | Download | only in gtk
      1 // Copyright (c) 2012 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_RELOAD_BUTTON_GTK_H_
      6 #define CHROME_BROWSER_UI_GTK_RELOAD_BUTTON_GTK_H_
      7 
      8 #include <gtk/gtk.h>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/compiler_specific.h"
     12 #include "base/timer/timer.h"
     13 #include "chrome/browser/ui/gtk/custom_button.h"
     14 #include "chrome/browser/ui/gtk/menu_gtk.h"
     15 #include "content/public/browser/notification_observer.h"
     16 #include "content/public/browser/notification_registrar.h"
     17 #include "ui/base/gtk/gtk_signal.h"
     18 #include "ui/base/gtk/owned_widget_gtk.h"
     19 #include "ui/base/models/simple_menu_model.h"
     20 
     21 class Browser;
     22 class GtkThemeService;
     23 class LocationBarViewGtk;
     24 
     25 class ReloadButtonGtk : public content::NotificationObserver,
     26                         MenuGtk::Delegate,
     27                         public ui::SimpleMenuModel::Delegate {
     28  public:
     29   enum Mode { MODE_RELOAD = 0, MODE_STOP };
     30 
     31   ReloadButtonGtk(LocationBarViewGtk* location_bar, Browser* browser);
     32   virtual ~ReloadButtonGtk();
     33 
     34   GtkWidget* widget() const { return widget_.get(); }
     35 
     36   // Ask for a specified button state.  If |force| is true this will be applied
     37   // immediately.
     38   void ChangeMode(Mode mode, bool force);
     39 
     40   // Provide content::NotificationObserver implementation.
     41   virtual void Observe(int type,
     42                        const content::NotificationSource& source,
     43                        const content::NotificationDetails& details) OVERRIDE;
     44 
     45   // Provide MenuGtk::Delegate implementation.
     46   virtual void StoppedShowing() OVERRIDE;
     47 
     48   // Provide SimpleMenuModel::Delegate implementation.
     49   virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
     50   virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
     51   virtual bool IsCommandIdVisible(int command_id) const OVERRIDE;
     52   virtual bool GetAcceleratorForCommandId(
     53      int command_id,
     54      ui::Accelerator* accelerator) OVERRIDE;
     55   virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
     56 
     57  private:
     58   friend class ReloadButtonGtkTest;
     59 
     60   CHROMEGTK_CALLBACK_0(ReloadButtonGtk, void, OnClicked);
     61   CHROMEGTK_CALLBACK_1(ReloadButtonGtk, gboolean, OnExpose, GdkEventExpose*);
     62   CHROMEGTK_CALLBACK_1(ReloadButtonGtk,
     63                        gboolean,
     64                        OnLeaveNotify,
     65                        GdkEventCrossing*);
     66   CHROMEGTK_CALLBACK_4(ReloadButtonGtk,
     67                        gboolean,
     68                        OnQueryTooltip,
     69                        gint,
     70                        gint,
     71                        gboolean,
     72                        GtkTooltip*);
     73 
     74   // Starts a timer to show the dropdown menu.
     75   CHROMEGTK_CALLBACK_1(ReloadButtonGtk,
     76                        gboolean,
     77                        OnButtonPress,
     78                        GdkEventButton*);
     79 
     80   // If there is a timer to show the dropdown menu, and the mouse has moved
     81   // sufficiently down the screen, cancel the timer and immediately show the
     82   // menu.
     83   CHROMEGTK_CALLBACK_1(ReloadButtonGtk,
     84                        gboolean,
     85                        OnMouseMove,
     86                        GdkEventMotion*);
     87 
     88   void UpdateThemeButtons();
     89 
     90   void OnDoubleClickTimer();
     91   void OnStopToReloadTimer();
     92 
     93   // Shows the dropdown menu.
     94   void ShowReloadMenu(int button, guint32 event_time);
     95 
     96   // Do actual reload. command == 0, indicates default dehaviour.
     97   void DoReload(int command);
     98 
     99   // Indicates if reload menu is currently enabled.
    100   bool ReloadMenuEnabled();
    101   void ClearCache();
    102 
    103   base::OneShotTimer<ReloadButtonGtk> double_click_timer_;
    104   base::OneShotTimer<ReloadButtonGtk> stop_to_reload_timer_;
    105 
    106   // These may be NULL when testing.
    107   LocationBarViewGtk* const location_bar_;
    108   Browser* const browser_;
    109 
    110   // The mode we should be in assuming no timers are running.
    111   Mode intended_mode_;
    112 
    113   // The currently-visible mode - this may differ from the intended mode.
    114   Mode visible_mode_;
    115 
    116   // Used to listen for theme change notifications.
    117   content::NotificationRegistrar registrar_;
    118 
    119   GtkThemeService* theme_service_;
    120 
    121   CustomDrawButtonBase reload_;
    122   CustomDrawButtonBase stop_;
    123   CustomDrawHoverController hover_controller_;
    124 
    125   ui::OwnedWidgetGtk widget_;
    126 
    127   // The delay times for the timers.  These are members so that tests can modify
    128   // them.
    129   base::TimeDelta double_click_timer_delay_;
    130   base::TimeDelta stop_to_reload_timer_delay_;
    131 
    132   // The y position of the last mouse down event.
    133   int y_position_of_last_press_;
    134   base::WeakPtrFactory<ReloadButtonGtk> weak_factory_;
    135   // The menu gets reset every time it is shown.
    136   scoped_ptr<MenuGtk> menu_;
    137   // The dropdown menu model.
    138   scoped_ptr<ui::SimpleMenuModel> menu_model_;
    139   // Indicates if menu is currently shown.
    140   bool menu_visible_;
    141 
    142   // TESTING ONLY
    143   // True if we should pretend the button is hovered.
    144   bool testing_mouse_hovered_;
    145   // Increments when we would tell the browser to "reload", so
    146   // test code can tell whether we did so (as there may be no |browser_|).
    147   int testing_reload_count_;
    148 
    149   DISALLOW_IMPLICIT_CONSTRUCTORS(ReloadButtonGtk);
    150 };
    151 
    152 #endif  // CHROME_BROWSER_UI_GTK_RELOAD_BUTTON_GTK_H_
    153