summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/gtk/reload_button_gtk.h
blob: 7527c379e91c32f3d746c8aae2c08af1af67edd0 (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
// 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_RELOAD_BUTTON_GTK_H_
#define CHROME_BROWSER_UI_GTK_RELOAD_BUTTON_GTK_H_

#include <gtk/gtk.h>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/timer.h"
#include "chrome/browser/ui/gtk/custom_button.h"
#include "chrome/browser/ui/gtk/menu_gtk.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/gtk/gtk_signal.h"
#include "ui/base/gtk/owned_widget_gtk.h"

class Browser;
class GtkThemeService;
class LocationBarViewGtk;

class ReloadButtonGtk : public content::NotificationObserver,
                        MenuGtk::Delegate,
                        public ui::SimpleMenuModel::Delegate {
 public:
  enum Mode { MODE_RELOAD = 0, MODE_STOP };

  ReloadButtonGtk(LocationBarViewGtk* location_bar, Browser* browser);
  virtual ~ReloadButtonGtk();

  GtkWidget* widget() const { return widget_.get(); }

  // Ask for a specified button state.  If |force| is true this will be applied
  // immediately.
  void ChangeMode(Mode mode, bool force);

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

  // Provide MenuGtk::Delegate implementation.
  virtual void StoppedShowing() OVERRIDE;

  // Provide SimpleMenuModel::Delegate implementation.
  virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
  virtual bool IsCommandIdVisible(int command_id) const OVERRIDE;
  virtual bool GetAcceleratorForCommandId(
     int command_id,
     ui::Accelerator* accelerator) OVERRIDE;
  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;

 private:
  friend class ReloadButtonGtkTest;

  CHROMEGTK_CALLBACK_0(ReloadButtonGtk, void, OnClicked);
  CHROMEGTK_CALLBACK_1(ReloadButtonGtk, gboolean, OnExpose, GdkEventExpose*);
  CHROMEGTK_CALLBACK_1(ReloadButtonGtk,
                       gboolean,
                       OnLeaveNotify,
                       GdkEventCrossing*);
  CHROMEGTK_CALLBACK_4(ReloadButtonGtk,
                       gboolean,
                       OnQueryTooltip,
                       gint,
                       gint,
                       gboolean,
                       GtkTooltip*);

  // Starts a timer to show the dropdown menu.
  CHROMEGTK_CALLBACK_1(ReloadButtonGtk,
                       gboolean,
                       OnButtonPress,
                       GdkEventButton*);

  // If there is a timer to show the dropdown menu, and the mouse has moved
  // sufficiently down the screen, cancel the timer and immediately show the
  // menu.
  CHROMEGTK_CALLBACK_1(ReloadButtonGtk,
                       gboolean,
                       OnMouseMove,
                       GdkEventMotion*);

  void UpdateThemeButtons();

  void OnDoubleClickTimer();
  void OnStopToReloadTimer();

  // Shows the dropdown menu.
  void ShowReloadMenu(int button, guint32 event_time);

  // Do actual reload. command == 0, indicates default dehaviour.
  void DoReload(int command);

  // Indicates if reload menu is currently enabled.
  bool ReloadMenuEnabled();
  void ClearCache();

  base::OneShotTimer<ReloadButtonGtk> double_click_timer_;
  base::OneShotTimer<ReloadButtonGtk> stop_to_reload_timer_;

  // These may be NULL when testing.
  LocationBarViewGtk* const location_bar_;
  Browser* const browser_;

  // The mode we should be in assuming no timers are running.
  Mode intended_mode_;

  // The currently-visible mode - this may differ from the intended mode.
  Mode visible_mode_;

  // Used to listen for theme change notifications.
  content::NotificationRegistrar registrar_;

  GtkThemeService* theme_service_;

  CustomDrawButtonBase reload_;
  CustomDrawButtonBase stop_;
  CustomDrawHoverController hover_controller_;

  ui::OwnedWidgetGtk widget_;

  // The delay times for the timers.  These are members so that tests can modify
  // them.
  base::TimeDelta double_click_timer_delay_;
  base::TimeDelta stop_to_reload_timer_delay_;

  // The y position of the last mouse down event.
  int y_position_of_last_press_;
  base::WeakPtrFactory<ReloadButtonGtk> weak_factory_;
  // The menu gets reset every time it is shown.
  scoped_ptr<MenuGtk> menu_;
  // The dropdown menu model.
  scoped_ptr<ui::SimpleMenuModel> menu_model_;
  // Indicates if menu is currently shown.
  bool menu_visible_;

  // TESTING ONLY
  // True if we should pretend the button is hovered.
  bool testing_mouse_hovered_;
  // Increments when we would tell the browser to "reload", so
  // test code can tell whether we did so (as there may be no |browser_|).
  int testing_reload_count_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(ReloadButtonGtk);
};

#endif  // CHROME_BROWSER_UI_GTK_RELOAD_BUTTON_GTK_H_