15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_UI_GTK_RELOAD_BUTTON_GTK_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_UI_GTK_RELOAD_BUTTON_GTK_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtk/gtk.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/custom_button.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/menu_gtk.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/gtk_signal.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/owned_widget_gtk.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/base/models/simple_menu_model.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Browser;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GtkThemeService;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LocationBarViewGtk;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReloadButtonGtk : public content::NotificationObserver,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        MenuGtk::Delegate,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        public ui::SimpleMenuModel::Delegate {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum Mode { MODE_RELOAD = 0, MODE_STOP };
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReloadButtonGtk(LocationBarViewGtk* location_bar, Browser* browser);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ReloadButtonGtk();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* widget() const { return widget_.get(); }
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ask for a specified button state.  If |force| is true this will be applied
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // immediately.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ChangeMode(Mode mode, bool force);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Provide content::NotificationObserver implementation.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Provide MenuGtk::Delegate implementation.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void StoppedShowing() OVERRIDE;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Provide SimpleMenuModel::Delegate implementation.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsCommandIdVisible(int command_id) const OVERRIDE;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetAcceleratorForCommandId(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     int command_id,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     ui::Accelerator* accelerator) OVERRIDE;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ReloadButtonGtkTest;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROMEGTK_CALLBACK_0(ReloadButtonGtk, void, OnClicked);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROMEGTK_CALLBACK_1(ReloadButtonGtk, gboolean, OnExpose, GdkEventExpose*);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROMEGTK_CALLBACK_1(ReloadButtonGtk,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       gboolean,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       OnLeaveNotify,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       GdkEventCrossing*);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROMEGTK_CALLBACK_4(ReloadButtonGtk,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       gboolean,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       OnQueryTooltip,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       gint,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       gint,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       gboolean,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       GtkTooltip*);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts a timer to show the dropdown menu.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROMEGTK_CALLBACK_1(ReloadButtonGtk,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       gboolean,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       OnButtonPress,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       GdkEventButton*);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is a timer to show the dropdown menu, and the mouse has moved
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sufficiently down the screen, cancel the timer and immediately show the
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // menu.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROMEGTK_CALLBACK_1(ReloadButtonGtk,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       gboolean,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       OnMouseMove,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       GdkEventMotion*);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateThemeButtons();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnDoubleClickTimer();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnStopToReloadTimer();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shows the dropdown menu.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ShowReloadMenu(int button, guint32 event_time);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do actual reload. command == 0, indicates default dehaviour.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoReload(int command);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates if reload menu is currently enabled.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ReloadMenuEnabled();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearCache();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::OneShotTimer<ReloadButtonGtk> double_click_timer_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::OneShotTimer<ReloadButtonGtk> stop_to_reload_timer_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These may be NULL when testing.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LocationBarViewGtk* const location_bar_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* const browser_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mode we should be in assuming no timers are running.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mode intended_mode_;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The currently-visible mode - this may differ from the intended mode.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mode visible_mode_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to listen for theme change notifications.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkThemeService* theme_service_;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CustomDrawButtonBase reload_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CustomDrawButtonBase stop_;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CustomDrawHoverController hover_controller_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::OwnedWidgetGtk widget_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delay times for the timers.  These are members so that tests can modify
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // them.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta double_click_timer_delay_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta stop_to_reload_timer_delay_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The y position of the last mouse down event.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int y_position_of_last_press_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<ReloadButtonGtk> weak_factory_;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The menu gets reset every time it is shown.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MenuGtk> menu_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The dropdown menu model.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ui::SimpleMenuModel> menu_model_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicates if menu is currently shown.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool menu_visible_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TESTING ONLY
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if we should pretend the button is hovered.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool testing_mouse_hovered_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Increments when we would tell the browser to "reload", so
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // test code can tell whether we did so (as there may be no |browser_|).
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int testing_reload_count_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(ReloadButtonGtk);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_UI_GTK_RELOAD_BUTTON_GTK_H_
153