Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(612)

Side by Side Diff: chrome/browser/gtk/go_button_gtk.cc

Issue 62154: Implement stop/go button for Linux (Closed)
Patch Set: Add a small DCHECK => DCHECK_NE change. Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/gtk/go_button_gtk.h ('k') | chrome/browser/gtk/go_button_gtk_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 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 #include "chrome/browser/gtk/go_button_gtk.h"
6 #include "base/logging.h"
7 #include "base/message_loop.h"
8 #include "chrome/app/chrome_dll_resource.h"
9 #include "chrome/browser/browser.h"
10 #include "grit/theme_resources.h"
11
12 GoButtonGtk::GoButtonGtk(Browser* browser)
13 : browser_(browser),
14 button_delay_(0),
15 stop_timer_(this),
16 intended_mode_(MODE_GO),
17 visible_mode_(MODE_GO),
18 state_(BS_NORMAL),
19 go_(IDR_GO, IDR_GO_P, IDR_GO_H, 0),
20 stop_(IDR_STOP, IDR_STOP_P, IDR_STOP_H, 0),
21 widget_(gtk_button_new()) {
22 gtk_widget_set_size_request(widget_.get(),
23 gdk_pixbuf_get_width(go_.pixbufs(0)),
24 gdk_pixbuf_get_height(go_.pixbufs(0)));
25
26 gtk_widget_set_app_paintable(widget_.get(), TRUE);
27 // We effectively double-buffer by virtue of having only one image...
28 gtk_widget_set_double_buffered(widget_.get(), FALSE);
29
30 g_signal_connect(G_OBJECT(widget_.get()), "expose-event",
31 G_CALLBACK(OnExpose), this);
32 g_signal_connect(G_OBJECT(widget_.get()), "enter",
33 G_CALLBACK(OnEnter), this);
34 g_signal_connect(G_OBJECT(widget_.get()), "leave",
35 G_CALLBACK(OnLeave), this);
36 g_signal_connect(G_OBJECT(widget_.get()), "clicked",
37 G_CALLBACK(OnClicked), this);
38 GTK_WIDGET_UNSET_FLAGS(widget_.get(), GTK_CAN_FOCUS);
39
40 // TODO(willchan): Implement tooltips.
41 gtk_widget_set_tooltip_text(widget_.get(), "Implement toggleable tooltips");
42 }
43
44 GoButtonGtk::~GoButtonGtk() {
45 widget_.Destroy();
46 }
47
48 void GoButtonGtk::ChangeMode(Mode mode) {
49 if (mode != visible_mode_) {
50 gtk_widget_queue_draw(widget_.get());
51 }
52 stop_timer_.RevokeAll();
53 intended_mode_ = mode;
54 visible_mode_ = mode;
55 }
56
57 void GoButtonGtk::ScheduleChangeMode(Mode mode) {
58 if (mode == MODE_STOP) {
59 // If we still have a timer running, we can't yet change to a stop sign,
60 // so we'll queue up the change for when the timer expires or for when
61 // the mouse exits the button.
62 if (!stop_timer_.empty() && state() == BS_HOT) {
63 intended_mode_ = MODE_STOP;
64 } else {
65 ChangeMode(MODE_STOP);
66 }
67 } else {
68 // If we want to change the button to a go button, but the user's mouse
69 // is hovering, don't change the mode just yet - this prevents the
70 // stop button changing to a go under the user's mouse cursor.
71 if (visible_mode_ == MODE_STOP && state() == BS_HOT) {
72 intended_mode_ = MODE_GO;
73 } else {
74 ChangeMode(MODE_GO);
75 }
76 }
77 }
78
79 Task* GoButtonGtk::CreateButtonTimerTask() {
80 return stop_timer_.NewRunnableMethod(&GoButtonGtk::OnButtonTimer);
81 }
82
83 void GoButtonGtk::OnButtonTimer() {
84 if (intended_mode_ != visible_mode_) {
85 ChangeMode(intended_mode_);
86 }
87
88 stop_timer_.RevokeAll();
89 }
90
91 // static
92 gboolean GoButtonGtk::OnExpose(GtkWidget* widget,
93 GdkEventExpose* e,
94 GoButtonGtk* button) {
95 if (button->visible_mode_ == MODE_GO) {
96 return button->go_.OnExpose(widget, e);
97 } else {
98 return button->stop_.OnExpose(widget, e);
99 }
100 }
101
102 // static
103 gboolean GoButtonGtk::OnEnter(GtkButton* widget, GoButtonGtk* button) {
104 DCHECK_EQ(BS_NORMAL, button->state());
105 button->state_ = BS_HOT;
106 return TRUE;
107 }
108
109 // static
110 gboolean GoButtonGtk::OnLeave(GtkButton* widget, GoButtonGtk* button) {
111 DCHECK_EQ(BS_HOT, button->state());
112 button->state_ = BS_NORMAL;
113 if (button->visible_mode_ != button->intended_mode_) {
114 button->ChangeMode(button->intended_mode_);
115 }
116 return TRUE;
117 }
118
119 // static
120 gboolean GoButtonGtk::OnClicked(GtkButton* widget, GoButtonGtk* button) {
121 if (button->visible_mode_ == MODE_STOP) {
122 if (button->browser_)
123 button->browser_->Stop();
124
125 // The user has clicked, so we can feel free to update the button,
126 // even if the mouse is still hovering.
127 button->ChangeMode(MODE_GO);
128 } else if (button->visible_mode_ == MODE_GO && button->stop_timer_.empty()) {
129 // If the go button is visible and not within the double click timer, go.
130 if (button->browser_)
131 button->browser_->ExecuteCommand(IDC_GO);
132
133 // Figure out the system double-click time.
134 if (button->button_delay_ == 0) {
135 GtkSettings* settings = gtk_settings_get_default();
136 g_object_get(G_OBJECT(settings),
137 "gtk-double-click-time",
138 &button->button_delay_,
139 NULL);
140 }
141
142 // Stop any existing timers.
143 button->stop_timer_.RevokeAll();
144
145 // Start a timer - while this timer is running, the go button
146 // cannot be changed to a stop button. We do not set intended_mode_
147 // to MODE_STOP here as we want to wait for the browser to tell
148 // us that it has started loading (and this may occur only after
149 // some delay).
150 MessageLoop::current()->PostDelayedTask(FROM_HERE,
151 button->CreateButtonTimerTask(),
152 button->button_delay_);
153 }
154
155 return TRUE;
156 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/go_button_gtk.h ('k') | chrome/browser/gtk/go_button_gtk_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698