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

Side by Side Diff: chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm

Issue 9310074: Switch to using WebIntentPickerModel, and bring picker closer to mocks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Re-merging to HEAD Created 8 years, 10 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
« no previous file with comments | « chrome/browser/ui/cocoa/web_intent_picker_cocoa.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/cocoa/web_intent_picker_cocoa.h" 5 #include "chrome/browser/ui/cocoa/web_intent_picker_cocoa.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #include "base/bind.h"
10 #include "base/message_loop.h"
9 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ui/browser.h" 12 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/browser_window.h" 13 #include "chrome/browser/ui/browser_window.h"
12 #import "chrome/browser/ui/cocoa/browser_window_controller.h" 14 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
13 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" 15 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
14 #import "chrome/browser/ui/cocoa/web_intent_bubble_controller.h" 16 #import "chrome/browser/ui/cocoa/web_intent_bubble_controller.h"
15 #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h" 17 #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h"
16 #include "chrome/browser/ui/intents/web_intent_picker.h" 18 #include "chrome/browser/ui/intents/web_intent_picker.h"
17 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" 19 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
18 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 20 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
19 #include "content/public/browser/web_contents.h" 21 #include "content/public/browser/web_contents.h"
20 #include "skia/ext/skia_utils_mac.h" 22 #include "skia/ext/skia_utils_mac.h"
21 #include "ui/gfx/image/image.h" 23 #include "ui/gfx/image/image.h"
22 24
23 using content::WebContents; 25 using content::WebContents;
24 26
25 // static 27 // static
26 WebIntentPicker* WebIntentPicker::Create(Browser* browser, 28 WebIntentPicker* WebIntentPicker::Create(Browser* browser,
27 TabContentsWrapper* wrapper, 29 TabContentsWrapper* wrapper,
28 WebIntentPickerDelegate* delegate, 30 WebIntentPickerDelegate* delegate,
29 WebIntentPickerModel* model) { 31 WebIntentPickerModel* model) {
30 return new WebIntentPickerCocoa(browser, wrapper, delegate, model); 32 return new WebIntentPickerCocoa(browser, wrapper, delegate, model);
31 } 33 }
32 34
33 WebIntentPickerCocoa::WebIntentPickerCocoa() 35 WebIntentPickerCocoa::WebIntentPickerCocoa()
34 : delegate_(NULL), 36 : delegate_(NULL),
35 model_(NULL), 37 model_(NULL),
36 browser_(NULL), 38 browser_(NULL),
37 controller_(NULL) { 39 controller_(nil),
40 weak_ptr_factory_(this) {
38 } 41 }
39 42
40 43
41 WebIntentPickerCocoa::WebIntentPickerCocoa(Browser* browser, 44 WebIntentPickerCocoa::WebIntentPickerCocoa(Browser* browser,
42 TabContentsWrapper* wrapper, 45 TabContentsWrapper* wrapper,
43 WebIntentPickerDelegate* delegate, 46 WebIntentPickerDelegate* delegate,
44 WebIntentPickerModel* model) 47 WebIntentPickerModel* model)
45 : delegate_(delegate), 48 : delegate_(delegate),
46 model_(model), 49 model_(model),
47 browser_(browser), 50 browser_(browser),
48 controller_(NULL) { 51 controller_(nil),
52 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
49 model_->set_observer(this); 53 model_->set_observer(this);
50 54
51 DCHECK(browser); 55 DCHECK(browser);
52 DCHECK(delegate); 56 DCHECK(delegate);
53 NSWindow* parentWindow = browser->window()->GetNativeHandle(); 57 NSWindow* parentWindow = browser->window()->GetNativeHandle();
54 58
55 // Compute the anchor point, relative to location bar. 59 // Compute the anchor point, relative to location bar.
56 BrowserWindowController* controller = [parentWindow windowController]; 60 BrowserWindowController* controller = [parentWindow windowController];
57 LocationBarViewMac* locationBar = [controller locationBarBridge]; 61 LocationBarViewMac* locationBar = [controller locationBarBridge];
58 NSPoint anchor = locationBar->GetPageInfoBubblePoint(); 62 NSPoint anchor = locationBar->GetPageInfoBubblePoint();
59 anchor = [browser->window()->GetNativeHandle() convertBaseToScreen:anchor]; 63 anchor = [browser->window()->GetNativeHandle() convertBaseToScreen:anchor];
60 64
61 // The controller is deallocated when the window is closed, so no need to 65 // The controller is deallocated when the window is closed, so no need to
62 // worry about it here. 66 // worry about it here.
63 [[WebIntentBubbleController alloc] initWithPicker:this 67 [[WebIntentBubbleController alloc] initWithPicker:this
64 parentWindow:parentWindow 68 parentWindow:parentWindow
65 anchoredAt:anchor]; 69 anchoredAt:anchor];
66 } 70 }
67 71
68 WebIntentPickerCocoa::~WebIntentPickerCocoa() { 72 WebIntentPickerCocoa::~WebIntentPickerCocoa() {
69 if (model_ != NULL) 73 if (model_ != NULL)
70 model_->set_observer(NULL); 74 model_->set_observer(NULL);
71 } 75 }
72 76
73 void WebIntentPickerCocoa::Close() { 77 void WebIntentPickerCocoa::Close() {
74 } 78 }
75 79
80 void WebIntentPickerCocoa::PerformDelayedLayout() {
81 // Check to see if a layout has already been scheduled.
82 if (weak_ptr_factory_.HasWeakPtrs())
83 return;
84
85 // Delay performing layout by a second so that all the animations from
86 // InfoBubbleWindow and origin updates from BaseBubbleController finish, so
87 // that we don't all race trying to change the frame's origin.
88 //
89 // Using MessageLoop is superior here to |-performSelector:| because it will
90 // not retain its target; if the child outlives its parent, zombies get left
91 // behind (http://crbug.com/59619). This will cancel the scheduled task if
92 // the controller get destroyed before the message
93 // can be delivered.
94 MessageLoop::current()->PostDelayedTask(FROM_HERE,
95 base::Bind(&WebIntentPickerCocoa::PerformLayout,
96 weak_ptr_factory_.GetWeakPtr()),
97 100 /* milliseconds */);
98 }
99
100 void WebIntentPickerCocoa::PerformLayout() {
101 DCHECK(controller_);
102 // If the window is animating closed when this is called, the
103 // animation could be holding the last reference to |controller_|
104 // (and thus |this|). Pin it until the task is completed.
105 scoped_nsobject<WebIntentBubbleController> keep_alive([controller_ retain]);
106 [controller_ performLayoutWithModel:model_];
107 }
108
76 void WebIntentPickerCocoa::OnModelChanged(WebIntentPickerModel* model) { 109 void WebIntentPickerCocoa::OnModelChanged(WebIntentPickerModel* model) {
77 DCHECK(controller_); 110 PerformDelayedLayout();
78 scoped_nsobject<NSMutableArray> urlArray(
79 [[NSMutableArray alloc] initWithCapacity:model->GetItemCount()]);
80
81 for (size_t i = 0; i < model->GetItemCount(); ++i) {
82 const WebIntentPickerModel::Item& item = model->GetItemAt(i);
83
84 [urlArray addObject:
85 [NSString stringWithUTF8String:item.url.spec().c_str()]];
86 [controller_ replaceImageAtIndex:i withImage:item.favicon.ToNSImage()];
87 }
88
89 [controller_ setServiceURLs:urlArray];
90 } 111 }
91 112
92 void WebIntentPickerCocoa::OnFaviconChanged(WebIntentPickerModel* model, 113 void WebIntentPickerCocoa::OnFaviconChanged(WebIntentPickerModel* model,
93 size_t index) { 114 size_t index) {
94 DCHECK(controller_); 115 // We don't handle individual icon changes - just redo the whole model.
95 116 PerformDelayedLayout();
96 const WebIntentPickerModel::Item& item = model->GetItemAt(index);
97 [controller_ replaceImageAtIndex:index withImage:item.favicon.ToNSImage()];
98 } 117 }
99 118
100 void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model) { 119 void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model) {
101 const WebIntentPickerModel::Item& item = model->GetItemAt( 120 const WebIntentPickerModel::Item& item = model->GetItemAt(
102 model->inline_disposition_index()); 121 model->inline_disposition_index());
103 122
104 content::WebContents* web_contents = content::WebContents::Create( 123 content::WebContents* web_contents = content::WebContents::Create(
105 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); 124 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
106 inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents)); 125 inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents));
107 inline_disposition_delegate_.reset(new WebIntentInlineDispositionDelegate); 126 inline_disposition_delegate_.reset(new WebIntentInlineDispositionDelegate);
108 web_contents->SetDelegate(inline_disposition_delegate_.get()); 127 web_contents->SetDelegate(inline_disposition_delegate_.get());
109 128
110 inline_disposition_tab_contents_->web_contents()->GetController().LoadURL( 129 inline_disposition_tab_contents_->web_contents()->GetController().LoadURL(
111 item.url, 130 item.url,
112 content::Referrer(), 131 content::Referrer(),
113 content::PAGE_TRANSITION_START_PAGE, 132 content::PAGE_TRANSITION_START_PAGE,
114 std::string()); 133 std::string());
115 134
116 [controller_ setInlineDispositionTabContents: 135 [controller_ setInlineDispositionTabContents:
117 inline_disposition_tab_contents_.get()]; 136 inline_disposition_tab_contents_.get()];
137 PerformDelayedLayout();
118 138
119 delegate_->OnInlineDispositionWebContentsCreated(web_contents); 139 delegate_->OnInlineDispositionWebContentsCreated(web_contents);
120 } 140 }
121 141
122 void WebIntentPickerCocoa::OnCancelled() { 142 void WebIntentPickerCocoa::OnCancelled() {
123 DCHECK(delegate_); 143 DCHECK(delegate_);
124 delegate_->OnCancelled(); 144 delegate_->OnCancelled();
125 controller_ = NULL; // Controller will be unusable soon, abandon. 145 controller_ = NULL; // Controller will be unusable soon, abandon.
126 } 146 }
127 147
128 void WebIntentPickerCocoa::OnServiceChosen(size_t index) { 148 void WebIntentPickerCocoa::OnServiceChosen(size_t index) {
129 DCHECK(delegate_); 149 DCHECK(delegate_);
130 const WebIntentPickerModel::Item& item = model_->GetItemAt(index); 150 const WebIntentPickerModel::Item& item = model_->GetItemAt(index);
131 delegate_->OnServiceChosen(index, item.disposition); 151 delegate_->OnServiceChosen(index, item.disposition);
132 } 152 }
133 153
134 void WebIntentPickerCocoa::set_controller( 154 void WebIntentPickerCocoa::set_controller(
135 WebIntentBubbleController* controller) { 155 WebIntentBubbleController* controller) {
136 controller_ = controller; 156 controller_ = controller;
137 } 157 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/web_intent_picker_cocoa.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698