• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
widget()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   // The menu gets reset every time it is shown.
135   scoped_ptr<MenuGtk> menu_;
136   // The dropdown menu model.
137   scoped_ptr<ui::SimpleMenuModel> menu_model_;
138   // Indicates if menu is currently shown.
139   bool menu_visible_;
140 
141   // TESTING ONLY
142   // True if we should pretend the button is hovered.
143   bool testing_mouse_hovered_;
144   // Increments when we would tell the browser to "reload", so
145   // test code can tell whether we did so (as there may be no |browser_|).
146   int testing_reload_count_;
147 
148   base::WeakPtrFactory<ReloadButtonGtk> weak_factory_;
149 
150   DISALLOW_IMPLICIT_CONSTRUCTORS(ReloadButtonGtk);
151 };
152 
153 #endif  // CHROME_BROWSER_UI_GTK_RELOAD_BUTTON_GTK_H_
154