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

Side by Side Diff: chrome/browser/ui/views/web_intent_picker_view.cc

Issue 9148032: [Web Intents] Refactor picker to use WebIntentPickerModel. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: vertical layout for views Created 8 years, 11 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
1 // Copyright (c) 2011 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 <algorithm> 5 #include <algorithm>
6 #include <vector> 6 #include <vector>
7 7
8 #include "chrome/browser/ui/browser.h" 8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/intents/web_intent_picker.h" 9 #include "chrome/browser/ui/intents/web_intent_picker.h"
10 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" 10 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
11 #include "chrome/browser/ui/intents/web_intent_picker_model.h"
12 #include "chrome/browser/ui/intents/web_intent_picker_model_observer.h"
11 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 13 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
12 #include "chrome/browser/ui/views/frame/browser_view.h" 14 #include "chrome/browser/ui/views/frame/browser_view.h"
13 #include "chrome/browser/ui/views/location_bar/location_icon_view.h" 15 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
14 #include "chrome/browser/ui/views/toolbar_view.h" 16 #include "chrome/browser/ui/views/toolbar_view.h"
15 #include "chrome/browser/ui/views/window.h" 17 #include "chrome/browser/ui/views/window.h"
16 #include "grit/generated_resources.h" 18 #include "grit/generated_resources.h"
17 #include "grit/theme_resources.h" 19 #include "grit/theme_resources.h"
18 #include "grit/theme_resources_standard.h" 20 #include "grit/theme_resources_standard.h"
19 #include "grit/ui_resources.h" 21 #include "grit/ui_resources.h"
20 #include "ui/base/l10n/l10n_util.h" 22 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/resource/resource_bundle.h" 23 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/gfx/canvas.h" 24 #include "ui/gfx/canvas.h"
23 #include "ui/gfx/canvas_skia.h" 25 #include "ui/gfx/canvas_skia.h"
24 #include "ui/gfx/image/image.h" 26 #include "ui/gfx/image/image.h"
25 #include "ui/views/bubble/bubble_delegate.h" 27 #include "ui/views/bubble/bubble_delegate.h"
26 #include "ui/views/controls/button/image_button.h" 28 #include "ui/views/controls/button/text_button.h"
27 #include "ui/views/controls/image_view.h" 29 #include "ui/views/controls/image_view.h"
28 #include "ui/views/controls/label.h" 30 #include "ui/views/controls/label.h"
29 #include "ui/views/layout/box_layout.h" 31 #include "ui/views/layout/box_layout.h"
30 32
31 using content::WebContents; 33 using content::WebContents;
32 34
33 namespace { 35 namespace {
34 36
35 // The space in pixels between the top-level groups in the dialog. 37 // The space in pixels between the top-level groups in the dialog.
36 const int kContentAreaSpacing = 18; 38 const int kContentAreaSpacing = 18;
(...skipping 17 matching lines...) Expand all
54 SkPaint paint; 56 SkPaint paint;
55 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrcOver_Mode)); 57 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrcOver_Mode));
56 58
57 SkCanvas bg_canvas(*out_image); 59 SkCanvas bg_canvas(*out_image);
58 bg_canvas.drawBitmap(image, 60 bg_canvas.drawBitmap(image,
59 SkIntToScalar((bg_bitmap.width() - image.width()) / 2), 61 SkIntToScalar((bg_bitmap.width() - image.width()) / 2),
60 SkIntToScalar((bg_bitmap.height() - image.height()) / 2), 62 SkIntToScalar((bg_bitmap.height() - image.height()) / 2),
61 &paint); 63 &paint);
62 } 64 }
63 65
64 // Set the images on |button| for states normal, hot, and pushed.
65 // The images are generated by drawing |image| on top of the identified by
66 // |bg_normal_id|, |bg_hot_id|, and |bg_pushed_id| respectively.
67 void SetButtonImages(views::ImageButton* button,
68 const SkBitmap& image,
69 int bg_normal_id, int bg_hot_id, int bg_pushed_id) {
70 SkBitmap image_normal;
71 CreateButtonImage(bg_normal_id, image, &image_normal);
72 button->SetImage(views::CustomButton::BS_NORMAL, &image_normal);
73
74 SkBitmap image_hot;
75 CreateButtonImage(bg_hot_id, image, &image_hot);
76 button->SetImage(views::CustomButton::BS_HOT, &image_hot);
77
78 SkBitmap image_pushed;
79 CreateButtonImage(bg_pushed_id, image, &image_pushed);
80 button->SetImage(views::CustomButton::BS_PUSHED, &image_pushed);
81 }
82
83 } // namespace 66 } // namespace
84 67
85 // Views implementation of WebIntentPicker. 68 // Views implementation of WebIntentPicker.
86 class WebIntentPickerView : public views::BubbleDelegateView, 69 class WebIntentPickerView : public views::BubbleDelegateView,
87 public views::ButtonListener, 70 public views::ButtonListener,
88 public WebIntentPicker { 71 public WebIntentPicker,
72 public WebIntentPickerModelObserver {
89 public: 73 public:
90 WebIntentPickerView(views::View* anchor_view, 74 WebIntentPickerView(views::View* anchor_view,
91 TabContentsWrapper* tab_contents, 75 TabContentsWrapper* tab_contents,
92 WebIntentPickerDelegate* delegate); 76 WebIntentPickerDelegate* delegate,
77 WebIntentPickerModel* model);
93 virtual ~WebIntentPickerView(); 78 virtual ~WebIntentPickerView();
94 79
95 // views::ButtonListener implementation. 80 // views::ButtonListener implementation.
96 virtual void ButtonPressed(views::Button* sender, 81 virtual void ButtonPressed(views::Button* sender,
97 const views::Event& event) OVERRIDE; 82 const views::Event& event) OVERRIDE;
98 83
99 // views::WidgetDelegate implementation. 84 // views::WidgetDelegate implementation.
100 virtual void WindowClosing() OVERRIDE; 85 virtual void WindowClosing() OVERRIDE;
101 86
102 // WebIntentPicker implementation. 87 // WebIntentPicker implementation.
103 virtual void SetServiceURLs(const std::vector<GURL>& urls) OVERRIDE;
104 virtual void SetServiceIcon(size_t index, const SkBitmap& icon) OVERRIDE;
105 virtual void SetDefaultServiceIcon(size_t index) OVERRIDE;
106 virtual void Close() OVERRIDE; 88 virtual void Close() OVERRIDE;
107 virtual content::WebContents* SetInlineDisposition(const GURL& url) OVERRIDE; 89
90 // WebIntentPickerModelObserver implementation.
91 virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE;
92 virtual void OnFaviconChanged(WebIntentPickerModel* model,
93 size_t index) OVERRIDE;
94 virtual void OnInlineDisposition(WebIntentPickerModel* model) OVERRIDE;
108 95
109 protected: 96 protected:
110 // views::BubbleDelegateView overrides: 97 // views::BubbleDelegateView overrides:
111 void Init() OVERRIDE; 98 void Init() OVERRIDE;
112 99
113 private: 100 private:
114 // A weak pointer to the WebIntentPickerDelegate to notify when the user 101 // A weak pointer to the WebIntentPickerDelegate to notify when the user
115 // chooses a service or cancels. 102 // chooses a service or cancels.
116 WebIntentPickerDelegate* delegate_; 103 WebIntentPickerDelegate* delegate_;
117 104
105 // Web pointer to the picker model.
106 WebIntentPickerModel* model_;
107
118 // A weak pointer to the hbox that contains the buttons used to choose the 108 // A weak pointer to the hbox that contains the buttons used to choose the
119 // service. 109 // service.
120 views::View* button_hbox_; 110 views::View* button_vbox_;
121 111
122 // A vector of weak pointers to each of the service buttons. 112 // A vector of weak pointers to each of the service buttons.
123 std::vector<views::Button*> buttons_; 113 std::vector<views::Button*> buttons_;
124 114
125 // A weak pointer to the plus button, used to search for more services on the
126 // Chrome Web Store.
127 views::ImageButton* plus_button_;
128
129 DISALLOW_COPY_AND_ASSIGN(WebIntentPickerView); 115 DISALLOW_COPY_AND_ASSIGN(WebIntentPickerView);
130 }; 116 };
131 117
132 // static 118 // static
133 WebIntentPicker* WebIntentPicker::Create(Browser* browser, 119 WebIntentPicker* WebIntentPicker::Create(Browser* browser,
134 TabContentsWrapper* wrapper, 120 TabContentsWrapper* wrapper,
135 WebIntentPickerDelegate* delegate) { 121 WebIntentPickerDelegate* delegate,
122 WebIntentPickerModel* model) {
136 // Find where to point the bubble at. 123 // Find where to point the bubble at.
137 BrowserView* browser_view = 124 BrowserView* browser_view =
138 BrowserView::GetBrowserViewForBrowser(browser); 125 BrowserView::GetBrowserViewForBrowser(browser);
139 views::View* anchor_view = 126 views::View* anchor_view =
140 browser_view->toolbar()->location_bar()->location_icon_view(); 127 browser_view->toolbar()->location_bar()->location_icon_view();
141 WebIntentPickerView* bubble_delegate = 128 WebIntentPickerView* bubble_delegate =
142 new WebIntentPickerView(anchor_view, wrapper, delegate); 129 new WebIntentPickerView(anchor_view, wrapper, delegate, model);
143 browser::CreateViewsBubble(bubble_delegate); 130 browser::CreateViewsBubble(bubble_delegate);
144 bubble_delegate->Show(); 131 bubble_delegate->Show();
145 return bubble_delegate; 132 return bubble_delegate;
146 } 133 }
147 134
148 WebIntentPickerView::WebIntentPickerView(views::View* anchor_view, 135 WebIntentPickerView::WebIntentPickerView(views::View* anchor_view,
149 TabContentsWrapper* wrapper, 136 TabContentsWrapper* wrapper,
150 WebIntentPickerDelegate* delegate) 137 WebIntentPickerDelegate* delegate,
138 WebIntentPickerModel* model)
151 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT), 139 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_LEFT),
152 delegate_(delegate), 140 delegate_(delegate),
153 button_hbox_(NULL), 141 model_(model),
154 plus_button_(NULL) { 142 button_vbox_(NULL) {
143 model_->set_observer(this);
155 } 144 }
156 145
157 WebIntentPickerView::~WebIntentPickerView() { 146 WebIntentPickerView::~WebIntentPickerView() {
147 model_->set_observer(NULL);
158 } 148 }
159 149
160 void WebIntentPickerView::ButtonPressed(views::Button* sender, 150 void WebIntentPickerView::ButtonPressed(views::Button* sender,
161 const views::Event& event) { 151 const views::Event& event) {
162 // TODO(binji) When we support the plus button, pressing it should forward the
163 // user to services in the Chrome Web Store that provide this intent.
164 if (sender == plus_button_)
165 return;
166
167 std::vector<views::Button*>::iterator iter = 152 std::vector<views::Button*>::iterator iter =
168 std::find(buttons_.begin(), buttons_.end(), sender); 153 std::find(buttons_.begin(), buttons_.end(), sender);
169 DCHECK(iter != buttons_.end()); 154 DCHECK(iter != buttons_.end());
170 155
171 size_t index = iter - buttons_.begin(); 156 size_t index = iter - buttons_.begin();
172 delegate_->OnServiceChosen(index); 157 const WebIntentPickerModel::Item& item = model_->GetItemAt(index);
158
159 delegate_->OnServiceChosen(index, item.disposition);
173 } 160 }
174 161
175 void WebIntentPickerView::WindowClosing() { 162 void WebIntentPickerView::WindowClosing() {
176 delegate_->OnCancelled(); 163 delegate_->OnClosing();
177 }
178
179 void WebIntentPickerView::SetServiceURLs(const std::vector<GURL>& urls) {
180 for (size_t i = 0; i < urls.size(); ++i) {
181 views::ImageButton* button = new views::ImageButton(this);
182 button->SetTooltipText(UTF8ToUTF16(urls[i].spec().c_str()));
183 button_hbox_->AddChildView(button);
184 buttons_.push_back(button);
185 }
186
187 // Add the '+' button, to use the Chrome Web Store.
188 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
189 plus_button_ = new views::ImageButton(this);
190 plus_button_->SetTooltipText(
191 l10n_util::GetStringUTF16(IDS_FIND_MORE_INTENT_HANDLER_TOOLTIP));
192 SetButtonImages(plus_button_, rb.GetImageNamed(IDR_SIDETABS_NEW_TAB),
193 IDR_BROWSER_ACTION, IDR_BROWSER_ACTION_H, IDR_BROWSER_ACTION_P);
194 button_hbox_->AddChildView(plus_button_);
195 }
196
197 void WebIntentPickerView::SetServiceIcon(size_t index, const SkBitmap& icon) {
198 views::ImageButton* button =
199 static_cast<views::ImageButton*>(button_hbox_->child_at(index));
200 SetButtonImages(button, icon,
201 IDR_BROWSER_ACTION, IDR_BROWSER_ACTION_H, IDR_BROWSER_ACTION_P);
202
203 Layout();
204 SizeToContents();
205 }
206
207 void WebIntentPickerView::SetDefaultServiceIcon(size_t index) {
208 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
209 SetServiceIcon(index, rb.GetImageNamed(IDR_DEFAULT_FAVICON));
210 } 164 }
211 165
212 void WebIntentPickerView::Close() { 166 void WebIntentPickerView::Close() {
213 GetWidget()->Close(); 167 GetWidget()->Close();
214 } 168 }
215 169
216 WebContents* WebIntentPickerView::SetInlineDisposition(const GURL& url) { 170 void WebIntentPickerView::OnModelChanged(WebIntentPickerModel* model) {
171 button_vbox_->RemoveAllChildViews(true);
172 buttons_.clear();
173
174 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
175
176 for (size_t i = 0; i < model->GetItemCount(); ++i) {
177 const WebIntentPickerModel::Item& item = model_->GetItemAt(i);
178
179 views::TextButton* button = new views::TextButton(this, item.title);
180 button->SetTooltipText(UTF8ToUTF16(item.url.spec().c_str()));
181 button->SetIcon(rb.GetImageNamed(IDR_DEFAULT_FAVICON));
groby-ooo-7-16 2012/01/25 22:03:13 Favicons should probably be handled by the model.
182 button_vbox_->AddChildView(button);
183
184 buttons_.push_back(button);
185 }
186 }
187
188 void WebIntentPickerView::OnFaviconChanged(WebIntentPickerModel* model,
189 size_t index) {
190 const WebIntentPickerModel::Item& item = model_->GetItemAt(index);
191 views::TextButton* button =
192 static_cast<views::TextButton*>(buttons_[index]);
193
194 button->SetIcon(*item.favicon->ToSkBitmap());
195
196 Layout();
197 SizeToContents();
198 }
199
200 void WebIntentPickerView::OnInlineDisposition(WebIntentPickerModel* model) {
217 // TODO(gbillock): add support here. 201 // TODO(gbillock): add support here.
218 return NULL; 202 delegate_->OnInlineDispositionWebContentsCreated(NULL);
219 } 203 }
220 204
221 void WebIntentPickerView::Init() { 205 void WebIntentPickerView::Init() {
222 SetLayoutManager(new views::BoxLayout( 206 SetLayoutManager(new views::BoxLayout(
223 views::BoxLayout::kHorizontal, 207 views::BoxLayout::kHorizontal,
224 kContentAreaBorder, // inside border horizontal spacing 208 kContentAreaBorder, // inside border horizontal spacing
225 kContentAreaBorder, // inside border vertical spacing 209 kContentAreaBorder, // inside border vertical spacing
226 kContentAreaSpacing)); // between child spacing 210 kContentAreaSpacing)); // between child spacing
227 211
228 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
229 SkBitmap image_bitmap = rb.GetImageNamed(IDR_PAGEINFO_INFO);
230 views::ImageView* image = new views::ImageView();
231 image->SetImage(image_bitmap);
232 image->SetVerticalAlignment(views::ImageView::LEADING);
233 AddChildView(image);
234
235 views::View* main_content = new views::View(); 212 views::View* main_content = new views::View();
236 main_content->SetLayoutManager(new views::BoxLayout( 213 main_content->SetLayoutManager(new views::BoxLayout(
237 views::BoxLayout::kVertical, 214 views::BoxLayout::kVertical,
238 0, // inside border horizontal spacing 215 0, // inside border horizontal spacing
239 0, // inside border vertical spacing 216 0, // inside border vertical spacing
240 kContentAreaSpacing)); // between child spacing 217 kContentAreaSpacing)); // between child spacing
241 218
242 views::Label* top_label = new views::Label( 219 views::Label* top_label = new views::Label(
243 l10n_util::GetStringUTF16(IDS_CHOOSE_INTENT_HANDLER_MESSAGE)); 220 l10n_util::GetStringUTF16(IDS_CHOOSE_INTENT_HANDLER_MESSAGE));
244 top_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 221 top_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
245 main_content->AddChildView(top_label); 222 main_content->AddChildView(top_label);
246 223
247 button_hbox_ = new views::View(); 224 button_vbox_ = new views::View();
248 button_hbox_->SetLayoutManager(new views::BoxLayout( 225 button_vbox_->SetLayoutManager(new views::BoxLayout(
249 views::BoxLayout::kHorizontal, 226 views::BoxLayout::kVertical,
250 0, // inside border horizontal spacing 227 0, // inside border horizontal spacing
251 0, // inside border vertical spacing 228 0, // inside border vertical spacing
252 kControlSpacing)); // between child spacing 229 kControlSpacing)); // between child spacing
253 main_content->AddChildView(button_hbox_); 230 main_content->AddChildView(button_vbox_);
254 231
255 views::Label* bottom_label = new views::Label( 232 views::Label* bottom_label = new views::Label(
256 l10n_util::GetStringUTF16(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE)); 233 l10n_util::GetStringUTF16(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE));
257 bottom_label->SetMultiLine(true); 234 bottom_label->SetMultiLine(true);
258 bottom_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 235 bottom_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
259 bottom_label->SetFont( 236 bottom_label->SetFont(
260 bottom_label->font().DeriveFont(kWebStoreLabelFontDelta)); 237 bottom_label->font().DeriveFont(kWebStoreLabelFontDelta));
261 main_content->AddChildView(bottom_label); 238 main_content->AddChildView(bottom_label);
262 239
263 AddChildView(main_content); 240 AddChildView(main_content);
264 } 241 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698