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

Side by Side Diff: chrome/browser/ui/panels/panel_browser_window_cocoa.mm

Issue 10908153: [Panel refactor] Deprecate old panels. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix linux_chromeos test failure Created 8 years, 3 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 | Annotate | Revision Log
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 #include "chrome/browser/ui/panels/panel_browser_window_cocoa.h"
6
7 #include "base/logging.h"
8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/browser_command_controller.h"
10 #include "chrome/browser/ui/browser_list.h"
11 #import "chrome/browser/ui/cocoa/browser_window_utils.h"
12 #include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
13 #include "chrome/browser/ui/cocoa/task_manager_mac.h"
14 #include "chrome/browser/ui/panels/panel.h"
15 #include "chrome/browser/ui/panels/panel_manager.h"
16 #import "chrome/browser/ui/panels/panel_titlebar_view_cocoa.h"
17 #import "chrome/browser/ui/panels/panel_utils_cocoa.h"
18 #import "chrome/browser/ui/panels/panel_window_controller_cocoa.h"
19 #include "chrome/browser/ui/tab_contents/tab_contents.h"
20 #include "chrome/browser/ui/tabs/tab_strip_model.h"
21 #include "chrome/common/chrome_notification_types.h"
22 #include "content/public/browser/native_web_keyboard_event.h"
23 #include "content/public/browser/notification_source.h"
24
25 using content::NativeWebKeyboardEvent;
26 using content::WebContents;
27
28 namespace {
29
30 // Use this instead of 0 for minimum size of a window when doing opening and
31 // closing animations, since OSX window manager does not like 0-sized windows
32 // (according to avi@).
33 const int kMinimumWindowSize = 1;
34
35 } // namespace
36
37 // This creates a shim window class, which in turn creates a Cocoa window
38 // controller which in turn creates actual NSWindow by loading a nib.
39 // Overall chain of ownership is:
40 // PanelWindowControllerCocoa -> PanelBrowserWindowCocoa -> Panel.
41 NativePanel* Panel::CreateNativePanel(Browser* browser, Panel* panel,
42 const gfx::Rect& bounds) {
43 return new PanelBrowserWindowCocoa(browser, panel, bounds);
44 }
45
46 PanelBrowserWindowCocoa::PanelBrowserWindowCocoa(Browser* browser,
47 Panel* panel,
48 const gfx::Rect& bounds)
49 : browser_(browser),
50 panel_(panel),
51 bounds_(bounds),
52 is_shown_(false),
53 has_find_bar_(false),
54 attention_request_id_(0) {
55 controller_ = [[PanelWindowControllerCocoa alloc] initWithPanel:this];
56 browser_->tab_strip_model()->AddObserver(this);
57 registrar_.Add(
58 this,
59 chrome::NOTIFICATION_PANEL_CHANGED_EXPANSION_STATE,
60 content::Source<Panel>(panel_.get()));
61 }
62
63 PanelBrowserWindowCocoa::~PanelBrowserWindowCocoa() {
64 browser_->tab_strip_model()->RemoveObserver(this);
65 }
66
67 bool PanelBrowserWindowCocoa::isClosed() {
68 return !controller_;
69 }
70
71 void PanelBrowserWindowCocoa::ShowPanel() {
72 // The Browser associated with this browser window must become the active
73 // browser at the time |Show()| is called. This is the natural behaviour under
74 // Windows, but |-makeKeyAndOrderFront:| won't send |-windowDidBecomeKey:|
75 // until we return to the runloop. Therefore any calls to
76 // |BrowserList::GetLastActive()| (for example, in bookmark_util), will return
77 // the previous browser instead if we don't explicitly set it here.
78 BrowserList::SetLastActive(GetPanelBrowser());
79
80 ShowPanelInactive();
81 ActivatePanel();
82 }
83
84 void PanelBrowserWindowCocoa::ShowPanelInactive() {
85 if (isClosed())
86 return;
87
88 // Browser calls this several times, meaning 'ensure it's shown'.
89 // Animations don't look good when repeated - hence this flag is needed.
90 if (is_shown_) {
91 return;
92 }
93 // A call to SetPanelBounds() before showing it is required to set
94 // the panel frame properly.
95 SetPanelBoundsInstantly(bounds_);
96 is_shown_ = true;
97
98 NSRect finalFrame = cocoa_utils::ConvertRectToCocoaCoordinates(bounds_);
99 [controller_ revealAnimatedWithFrame:finalFrame];
100 }
101
102 gfx::Rect PanelBrowserWindowCocoa::GetPanelBounds() const {
103 return bounds_;
104 }
105
106 // |bounds| is the platform-independent screen coordinates, with (0,0) at
107 // top-left of the primary screen.
108 void PanelBrowserWindowCocoa::SetPanelBounds(const gfx::Rect& bounds) {
109 setBoundsInternal(bounds, true);
110 }
111
112 void PanelBrowserWindowCocoa::SetPanelBoundsInstantly(const gfx::Rect& bounds) {
113 setBoundsInternal(bounds, false);
114 }
115
116 void PanelBrowserWindowCocoa::setBoundsInternal(const gfx::Rect& bounds,
117 bool animate) {
118 // We will call SetPanelBoundsInstantly() once before showing the panel
119 // and it should set the panel frame correctly.
120 if (bounds_ == bounds && is_shown_)
121 return;
122
123 bounds_ = bounds;
124
125 // Safely ignore calls to animate bounds before the panel is shown to
126 // prevent the window from loading prematurely.
127 if (animate && !is_shown_)
128 return;
129
130 NSRect frame = cocoa_utils::ConvertRectToCocoaCoordinates(bounds);
131 [controller_ setPanelFrame:frame animate:animate];
132 }
133
134 void PanelBrowserWindowCocoa::ClosePanel() {
135 if (isClosed())
136 return;
137
138 NSWindow* window = [controller_ window];
139 [window performClose:controller_];
140 }
141
142 void PanelBrowserWindowCocoa::ActivatePanel() {
143 if (!is_shown_)
144 return;
145
146 [controller_ activate];
147 }
148
149 void PanelBrowserWindowCocoa::DeactivatePanel() {
150 [controller_ deactivate];
151 }
152
153 bool PanelBrowserWindowCocoa::IsPanelActive() const {
154 // TODO(dcheng): It seems like a lot of these methods can be called before
155 // our NSWindow is created. Do we really need to check in every one of these
156 // methods if the NSWindow is created, or is there a better way to
157 // gracefully handle this?
158 if (!is_shown_)
159 return false;
160 return [[controller_ window] isMainWindow];
161 }
162
163 void PanelBrowserWindowCocoa::PreventActivationByOS(bool prevent_activation) {
164 [controller_ preventBecomingKeyWindow:prevent_activation];
165 return;
166 }
167
168 gfx::NativeWindow PanelBrowserWindowCocoa::GetNativePanelHandle() {
169 return [controller_ window];
170 }
171
172 void PanelBrowserWindowCocoa::UpdatePanelTitleBar() {
173 if (!is_shown_)
174 return;
175 [controller_ updateTitleBar];
176 }
177
178 void PanelBrowserWindowCocoa::UpdatePanelLoadingAnimations(
179 bool should_animate) {
180 [controller_ updateThrobber:should_animate];
181 }
182
183 void PanelBrowserWindowCocoa::ShowTaskManagerForPanel() {
184 TaskManagerMac::Show(false);
185 }
186
187 FindBar* PanelBrowserWindowCocoa::CreatePanelFindBar() {
188 DCHECK(!has_find_bar_) << "find bar should only be created once";
189 has_find_bar_ = true;
190
191 FindBarBridge* bridge = new FindBarBridge();
192 [controller_ addFindBar:bridge->find_bar_cocoa_controller()];
193 return bridge;
194 }
195
196 void PanelBrowserWindowCocoa::NotifyPanelOnUserChangedTheme() {
197 NOTIMPLEMENTED();
198 }
199
200 void PanelBrowserWindowCocoa::PanelWebContentsFocused(
201 WebContents* contents) {
202 // TODO(jianli): to be implemented.
203 }
204
205 void PanelBrowserWindowCocoa::PanelCut() {
206 // Nothing to do since we do not have panel-specific system menu on Mac.
207 }
208
209 void PanelBrowserWindowCocoa::PanelCopy() {
210 // Nothing to do since we do not have panel-specific system menu on Mac.
211 }
212
213 void PanelBrowserWindowCocoa::PanelPaste() {
214 // Nothing to do since we do not have panel-specific system menu on Mac.
215 }
216
217 void PanelBrowserWindowCocoa::DrawAttention(bool draw_attention) {
218 DCHECK((panel_->attention_mode() & Panel::USE_PANEL_ATTENTION) != 0);
219
220 PanelTitlebarViewCocoa* titlebar = [controller_ titlebarView];
221 if (draw_attention)
222 [titlebar drawAttention];
223 else
224 [titlebar stopDrawingAttention];
225
226 if ((panel_->attention_mode() & Panel::USE_SYSTEM_ATTENTION) != 0) {
227 if (draw_attention) {
228 DCHECK(!attention_request_id_);
229 attention_request_id_ =
230 [NSApp requestUserAttention:NSInformationalRequest];
231 } else {
232 [NSApp cancelUserAttentionRequest:attention_request_id_];
233 attention_request_id_ = 0;
234 }
235 }
236 }
237
238 bool PanelBrowserWindowCocoa::IsDrawingAttention() const {
239 PanelTitlebarViewCocoa* titlebar = [controller_ titlebarView];
240 return [titlebar isDrawingAttention];
241 }
242
243 bool PanelBrowserWindowCocoa::PreHandlePanelKeyboardEvent(
244 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
245 if (![BrowserWindowUtils shouldHandleKeyboardEvent:event])
246 return false;
247
248 int id = [BrowserWindowUtils getCommandId:event];
249 if (id == -1)
250 return false;
251
252 if (GetPanelBrowser()->command_controller()->IsReservedCommandOrKey(id,
253 event)) {
254 return [BrowserWindowUtils handleKeyboardEvent:event.os_event
255 inWindow:GetNativePanelHandle()];
256 }
257
258 DCHECK(is_keyboard_shortcut);
259 *is_keyboard_shortcut = true;
260 return false;
261 }
262
263 void PanelBrowserWindowCocoa::HandlePanelKeyboardEvent(
264 const NativeWebKeyboardEvent& event) {
265 if ([BrowserWindowUtils shouldHandleKeyboardEvent:event]) {
266 [BrowserWindowUtils handleKeyboardEvent:event.os_event
267 inWindow:GetNativePanelHandle()];
268 }
269 }
270
271 void PanelBrowserWindowCocoa::FullScreenModeChanged(
272 bool is_full_screen) {
273 [controller_ fullScreenModeChanged:is_full_screen];
274 }
275
276 Browser* PanelBrowserWindowCocoa::GetPanelBrowser() const {
277 return browser_.get();
278 }
279
280 void PanelBrowserWindowCocoa::DestroyPanelBrowser() {
281 [controller_ close];
282 }
283
284 void PanelBrowserWindowCocoa::EnsurePanelFullyVisible() {
285 [controller_ ensureFullyVisible];
286 }
287
288 void PanelBrowserWindowCocoa::SetPanelAlwaysOnTop(bool on_top) {
289 [controller_ updateWindowLevel];
290 }
291
292 void PanelBrowserWindowCocoa::EnableResizeByMouse(bool enable) {
293 [controller_ enableResizeByMouse:enable];
294 }
295
296 void PanelBrowserWindowCocoa::UpdatePanelMinimizeRestoreButtonVisibility() {
297 [controller_ updateTitleBarMinimizeRestoreButtonVisibility];
298 }
299
300 Panel* PanelBrowserWindowCocoa::panel() const {
301 return panel_.get();
302 }
303
304 void PanelBrowserWindowCocoa::DidCloseNativeWindow() {
305 DCHECK(!isClosed());
306 panel_->OnNativePanelClosed();
307 controller_ = NULL;
308 }
309
310 gfx::Size PanelBrowserWindowCocoa::WindowSizeFromContentSize(
311 const gfx::Size& content_size) const {
312 NSRect content = NSMakeRect(0, 0,
313 content_size.width(), content_size.height());
314 NSRect frame = [controller_ frameRectForContentRect:content];
315 return gfx::Size(NSWidth(frame), NSHeight(frame));
316 }
317
318 gfx::Size PanelBrowserWindowCocoa::ContentSizeFromWindowSize(
319 const gfx::Size& window_size) const {
320 NSRect frame = NSMakeRect(0, 0, window_size.width(), window_size.height());
321 NSRect content = [controller_ contentRectForFrameRect:frame];
322 return gfx::Size(NSWidth(content), NSHeight(content));
323 }
324
325 int PanelBrowserWindowCocoa::TitleOnlyHeight() const {
326 return [controller_ titlebarHeightInScreenCoordinates];
327 }
328
329 void PanelBrowserWindowCocoa::TabInsertedAt(TabContents* contents,
330 int index,
331 bool foreground) {
332 [controller_ webContentsInserted:contents->web_contents()];
333 }
334
335 void PanelBrowserWindowCocoa::TabDetachedAt(TabContents* contents,
336 int index) {
337 [controller_ webContentsDetached:contents->web_contents()];
338 }
339
340 void PanelBrowserWindowCocoa::Observe(
341 int type,
342 const content::NotificationSource& source,
343 const content::NotificationDetails& details) {
344 DCHECK_EQ(chrome::NOTIFICATION_PANEL_CHANGED_EXPANSION_STATE, type);
345 [controller_ updateWindowLevel];
346 }
347
348 void PanelBrowserWindowCocoa::PanelExpansionStateChanging(
349 Panel::ExpansionState old_state, Panel::ExpansionState new_state) {
350 }
351
352 // NativePanelTesting implementation.
353 class NativePanelTestingCocoa : public NativePanelTesting {
354 public:
355 NativePanelTestingCocoa(NativePanel* native_panel);
356 virtual ~NativePanelTestingCocoa() { }
357 // Overridden from NativePanelTesting
358 virtual void PressLeftMouseButtonTitlebar(
359 const gfx::Point& mouse_location, panel::ClickModifier modifier) OVERRIDE;
360 virtual void ReleaseMouseButtonTitlebar(
361 panel::ClickModifier modifier) OVERRIDE;
362 virtual void DragTitlebar(const gfx::Point& mouse_location) OVERRIDE;
363 virtual void CancelDragTitlebar() OVERRIDE;
364 virtual void FinishDragTitlebar() OVERRIDE;
365 virtual bool VerifyDrawingAttention() const OVERRIDE;
366 virtual bool VerifyActiveState(bool is_active) OVERRIDE;
367 virtual bool IsWindowSizeKnown() const OVERRIDE;
368 virtual bool IsAnimatingBounds() const OVERRIDE;
369 virtual bool IsButtonVisible(
370 panel::TitlebarButtonType button_type) const OVERRIDE;
371
372 private:
373 PanelTitlebarViewCocoa* titlebar() const;
374 // Weak, assumed always to outlive this test API object.
375 PanelBrowserWindowCocoa* native_panel_window_;
376 };
377
378 NativePanelTesting* PanelBrowserWindowCocoa::CreateNativePanelTesting() {
379 return new NativePanelTestingCocoa(this);
380 }
381
382 NativePanelTestingCocoa::NativePanelTestingCocoa(NativePanel* native_panel)
383 : native_panel_window_(static_cast<PanelBrowserWindowCocoa*>(native_panel)) {
384 }
385
386 PanelTitlebarViewCocoa* NativePanelTestingCocoa::titlebar() const {
387 return [native_panel_window_->controller_ titlebarView];
388 }
389
390 void NativePanelTestingCocoa::PressLeftMouseButtonTitlebar(
391 const gfx::Point& mouse_location, panel::ClickModifier modifier) {
392 // Convert from platform-indepedent screen coordinates to Cocoa's screen
393 // coordinates because PanelTitlebarViewCocoa method takes Cocoa's screen
394 // coordinates.
395 int modifierFlags =
396 (modifier == panel::APPLY_TO_ALL ? NSShiftKeyMask : 0);
397 [titlebar() pressLeftMouseButtonTitlebar:
398 cocoa_utils::ConvertPointToCocoaCoordinates(mouse_location)
399 modifiers:modifierFlags];
400 }
401
402 void NativePanelTestingCocoa::ReleaseMouseButtonTitlebar(
403 panel::ClickModifier modifier) {
404 int modifierFlags =
405 (modifier == panel::APPLY_TO_ALL ? NSShiftKeyMask : 0);
406 [titlebar() releaseLeftMouseButtonTitlebar:modifierFlags];
407 }
408
409 void NativePanelTestingCocoa::DragTitlebar(const gfx::Point& mouse_location) {
410 // Convert from platform-indepedent screen coordinates to Cocoa's screen
411 // coordinates because PanelTitlebarViewCocoa method takes Cocoa's screen
412 // coordinates.
413 [titlebar() dragTitlebar:
414 cocoa_utils::ConvertPointToCocoaCoordinates(mouse_location)];
415 }
416
417 void NativePanelTestingCocoa::CancelDragTitlebar() {
418 [titlebar() cancelDragTitlebar];
419 }
420
421 void NativePanelTestingCocoa::FinishDragTitlebar() {
422 [titlebar() finishDragTitlebar];
423 }
424
425 bool NativePanelTestingCocoa::VerifyDrawingAttention() const {
426 return [titlebar() isDrawingAttention];
427 }
428
429 bool NativePanelTestingCocoa::VerifyActiveState(bool is_active) {
430 // TODO(jianli): to be implemented.
431 return false;
432 }
433
434 bool NativePanelTestingCocoa::IsWindowSizeKnown() const {
435 return true;
436 }
437
438 bool NativePanelTestingCocoa::IsAnimatingBounds() const {
439 return [native_panel_window_->controller_ isAnimatingBounds];
440 }
441
442 bool NativePanelTestingCocoa::IsButtonVisible(
443 panel::TitlebarButtonType button_type) const {
444 switch (button_type) {
445 case panel::CLOSE_BUTTON:
446 return ![[titlebar() closeButton] isHidden];
447 case panel::MINIMIZE_BUTTON:
448 return ![[titlebar() minimizeButton] isHidden];
449 case panel::RESTORE_BUTTON:
450 return ![[titlebar() restoreButton] isHidden];
451 default:
452 NOTREACHED();
453 }
454 return false;
455 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/panels/panel_browser_window_cocoa.h ('k') | chrome/browser/ui/panels/panel_browser_window_cocoa_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698