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