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

Side by Side Diff: chrome/browser/ui/cocoa/toolbar/reload_button.mm

Issue 657443004: MacViews: Get views based toolbar to compile on the Mac. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@views-findbar
Patch Set: Rebase Created 6 years, 2 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
OLDNEW
(Empty)
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 #import "chrome/browser/ui/cocoa/toolbar/reload_button.h"
6
7 #include "chrome/app/chrome_command_ids.h"
8 #import "chrome/browser/ui/cocoa/accelerators_cocoa.h"
9 #import "chrome/browser/ui/cocoa/view_id_util.h"
10 #include "chrome/browser/command_updater.h"
11 #include "chrome/grit/generated_resources.h"
12 #include "grit/theme_resources.h"
13 #include "ui/base/accelerators/platform_accelerator_cocoa.h"
14 #include "ui/base/l10n/l10n_util.h"
15 #include "ui/base/l10n/l10n_util_mac.h"
16 #import "ui/events/event_utils.h"
17
18 namespace {
19
20 // Constant matches Windows.
21 NSTimeInterval kPendingReloadTimeout = 1.35;
22
23 // Contents of the Reload drop-down menu.
24 const int kReloadMenuItems[] = {
25 IDS_RELOAD_MENU_NORMAL_RELOAD_ITEM,
26 IDS_RELOAD_MENU_HARD_RELOAD_ITEM,
27 IDS_RELOAD_MENU_EMPTY_AND_HARD_RELOAD_ITEM,
28 };
29 // Note: must have the same size as |kReloadMenuItems|.
30 const int kReloadMenuCommands[] = {
31 IDC_RELOAD,
32 IDC_RELOAD_IGNORING_CACHE,
33 IDC_RELOAD_CLEARING_CACHE,
34 };
35
36 } // namespace
37
38 @interface ReloadButton ()
39 - (void)invalidatePendingReloadTimer;
40 - (void)forceReloadState:(NSTimer *)timer;
41 - (void)populateMenu;
42 @end
43
44 @implementation ReloadButton
45
46 + (Class)cellClass {
47 return [ClickHoldButtonCell class];
48 }
49
50 - (id)initWithFrame:(NSRect)frameRect {
51 if ((self = [super initWithFrame:frameRect])) {
52 // Since this is not a custom view, -awakeFromNib won't be called twice.
53 [self awakeFromNib];
54 }
55 return self;
56 }
57
58 - (void)viewWillMoveToWindow:(NSWindow *)newWindow {
59 // If this view is moved to a new window, reset its state.
60 [self setIsLoading:NO force:YES];
61 [super viewWillMoveToWindow:newWindow];
62 }
63
64 - (void)awakeFromNib {
65 // Don't allow multi-clicks, because the user probably wouldn't ever
66 // want to stop+reload or reload+stop.
67 [self setIgnoresMultiClick:YES];
68
69 [self setOpenMenuOnRightClick:YES];
70 [self setOpenMenuOnClick:NO];
71
72 menu_.reset([[NSMenu alloc] initWithTitle:@""]);
73 [self populateMenu];
74 }
75
76 - (void)invalidatePendingReloadTimer {
77 [pendingReloadTimer_ invalidate];
78 pendingReloadTimer_ = nil;
79 }
80
81 - (void)updateTag:(NSInteger)anInt {
82 if ([self tag] == anInt)
83 return;
84
85 // Forcibly remove any stale tooltip which is being displayed.
86 [self removeAllToolTips];
87 id cell = [self cell];
88 [self setTag:anInt];
89 if (anInt == IDC_RELOAD) {
90 [cell setImageID:IDR_RELOAD
91 forButtonState:image_button_cell::kDefaultState];
92 [cell setImageID:IDR_RELOAD_H
93 forButtonState:image_button_cell::kHoverState];
94 [cell setImageID:IDR_RELOAD_P
95 forButtonState:image_button_cell::kPressedState];
96 // The stop button has a disabled image but the reload button doesn't. To
97 // unset it we have to explicilty change the image ID to 0.
98 [cell setImageID:0
99 forButtonState:image_button_cell::kDisabledState];
100 [self setToolTip:l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_RELOAD)];
101 } else if (anInt == IDC_STOP) {
102 [cell setImageID:IDR_STOP
103 forButtonState:image_button_cell::kDefaultState];
104 [cell setImageID:IDR_STOP_H
105 forButtonState:image_button_cell::kHoverState];
106 [cell setImageID:IDR_STOP_P
107 forButtonState:image_button_cell::kPressedState];
108 [cell setImageID:IDR_STOP_D
109 forButtonState:image_button_cell::kDisabledState];
110 [self setToolTip:l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_STOP)];
111 } else {
112 NOTREACHED();
113 }
114 }
115
116 - (id)accessibilityAttributeValue:(NSString *)attribute {
117 if ([attribute isEqualToString:NSAccessibilityEnabledAttribute] &&
118 pendingReloadTimer_) {
119 return [NSNumber numberWithBool:NO];
120 } else {
121 return [super accessibilityAttributeValue:attribute];
122 }
123 }
124
125 - (void)setIsLoading:(BOOL)isLoading force:(BOOL)force {
126 // Can always transition to stop mode. Only transition to reload
127 // mode if forced or if the mouse isn't hovering. Otherwise, note
128 // that reload mode is desired and disable the button.
129 if (isLoading) {
130 [self invalidatePendingReloadTimer];
131 [self updateTag:IDC_STOP];
132 } else if (force) {
133 [self invalidatePendingReloadTimer];
134 [self updateTag:IDC_RELOAD];
135 } else if ([self tag] == IDC_STOP &&
136 !pendingReloadTimer_ &&
137 [[self cell] isMouseInside]) {
138 id cell = [self cell];
139 [cell setImageID:IDR_STOP_D
140 forButtonState:image_button_cell::kDefaultState];
141 [cell setImageID:IDR_STOP_D
142 forButtonState:image_button_cell::kDisabledState];
143 [cell setImageID:IDR_STOP_D
144 forButtonState:image_button_cell::kHoverState];
145 [cell setImageID:IDR_STOP_D
146 forButtonState:image_button_cell::kPressedState];
147 pendingReloadTimer_ =
148 [NSTimer timerWithTimeInterval:kPendingReloadTimeout
149 target:self
150 selector:@selector(forceReloadState:)
151 userInfo:nil
152 repeats:NO];
153 // Must add the timer to |NSRunLoopCommonModes| because
154 // it should run in |NSEventTrackingRunLoopMode| as well as
155 // |NSDefaultRunLoopMode|.
156 [[NSRunLoop currentRunLoop] addTimer:pendingReloadTimer_
157 forMode:NSRunLoopCommonModes];
158 } else {
159 [self invalidatePendingReloadTimer];
160 [self updateTag:IDC_RELOAD];
161 }
162 [self setEnabled:pendingReloadTimer_ == nil];
163 }
164
165 - (void)setMenuEnabled:(BOOL)enabled {
166 [self setAttachedMenu:(enabled ? menu_ : nil)];
167 }
168
169 - (void)setCommandUpdater:(CommandUpdater*)commandUpdater {
170 commandUpdater_ = commandUpdater;
171 }
172
173 - (void)forceReloadState:(NSTimer *)timer {
174 DCHECK_EQ(timer, pendingReloadTimer_);
175 [self setIsLoading:NO force:YES];
176 // Verify that |pendingReloadTimer_| is nil so it is not left dangling.
177 DCHECK(!pendingReloadTimer_);
178 }
179
180 - (BOOL)sendAction:(SEL)theAction to:(id)theTarget {
181 if ([self tag] == IDC_STOP) {
182 if (pendingReloadTimer_) {
183 // If |pendingReloadTimer_| then the control is currently being
184 // drawn in a disabled state, so just return. The control is NOT actually
185 // disabled, otherwise mousetracking (courtesy of the NSButtonCell)
186 // would not work.
187 return YES;
188 } else {
189 // When the stop is processed, immediately change to reload mode,
190 // even though the IPC still has to bounce off the renderer and
191 // back before the regular |-setIsLoaded:force:| will be called.
192 // [This is how views and gtk do it.]
193 BOOL ret = [super sendAction:theAction to:theTarget];
194 if (ret)
195 [self forceReloadState:pendingReloadTimer_];
196 return ret;
197 }
198 }
199
200 return [super sendAction:theAction to:theTarget];
201 }
202
203 - (ViewID)viewID {
204 return VIEW_ID_RELOAD_BUTTON;
205 }
206
207 - (void)mouseInsideStateDidChange:(BOOL)isInside {
208 [pendingReloadTimer_ fire];
209 }
210
211 - (void)populateMenu {
212 [menu_ setAutoenablesItems:NO];
213 // 0-th item must be blank. (This is because we use a pulldown list, for which
214 // Cocoa uses the 0-th item as "title" in the button.)
215 [menu_ addItemWithTitle:@""
216 action:nil
217 keyEquivalent:@""];
218 AcceleratorsCocoa* keymap = AcceleratorsCocoa::GetInstance();
219 for (size_t i = 0; i < arraysize(kReloadMenuItems); ++i) {
220 NSString* title = l10n_util::GetNSStringWithFixup(kReloadMenuItems[i]);
221 base::scoped_nsobject<NSMenuItem> item(
222 [[NSMenuItem alloc] initWithTitle:title
223 action:@selector(executeMenuItem:)
224 keyEquivalent:@""]);
225
226 const ui::Accelerator* accelerator =
227 keymap->GetAcceleratorForCommand(kReloadMenuCommands[i]);
228 if (accelerator) {
229 const ui::PlatformAcceleratorCocoa* platform =
230 static_cast<const ui::PlatformAcceleratorCocoa*>(
231 accelerator->platform_accelerator());
232 if (platform) {
233 [item setKeyEquivalent:platform->characters()];
234 [item setKeyEquivalentModifierMask:platform->modifier_mask()];
235 }
236 }
237
238 [item setTag:kReloadMenuCommands[i]];
239 [item setTarget:self];
240 [item setEnabled:YES];
241
242 [menu_ addItem:item];
243 }
244 }
245
246 // Action for menu items.
247 - (void)executeMenuItem:(id)sender {
248 if (!commandUpdater_)
249 return;
250 DCHECK([sender isKindOfClass:[NSMenuItem class]]);
251 int command = [sender tag];
252 int event_flags = ui::EventFlagsFromNative([NSApp currentEvent]);
253 commandUpdater_->ExecuteCommandWithDisposition(
254 command, ui::DispositionFromEventFlags(event_flags));
255 }
256
257 @end // ReloadButton
258
259 @implementation ReloadButton (Testing)
260
261 + (void)setPendingReloadTimeout:(NSTimeInterval)seconds {
262 kPendingReloadTimeout = seconds;
263 }
264
265 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/toolbar/reload_button.h ('k') | chrome/browser/ui/cocoa/toolbar/reload_button_cocoa.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698