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

Side by Side Diff: ui/app_list/search_result_view.cc

Issue 10872099: ash: Add support for additional icons in apps search list. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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
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 "ui/app_list/search_result_view.h" 5 #include "ui/app_list/search_result_view.h"
6 6
7 #include "ui/app_list/search_result.h" 7 #include "ui/app_list/search_result.h"
8 #include "ui/app_list/search_result_list_view.h" 8 #include "ui/app_list/search_result_list_view.h"
9 #include "ui/gfx/canvas.h" 9 #include "ui/gfx/canvas.h"
10 #include "ui/gfx/font.h" 10 #include "ui/gfx/font.h"
11 #include "ui/gfx/image/image_skia_operations.h"
11 #include "ui/gfx/render_text.h" 12 #include "ui/gfx/render_text.h"
13 #include "ui/views/controls/button/image_button.h"
12 #include "ui/views/controls/image_view.h" 14 #include "ui/views/controls/image_view.h"
13 15
14 namespace { 16 namespace {
15 17
16 const int kPreferredWidth = 300; 18 const int kPreferredWidth = 300;
17 const int kPreferredHeight = 52; 19 const int kPreferredHeight = 52;
18 const int kIconDimension = 32; 20 const int kIconDimension = 32;
19 const int kIconPadding = 14; 21 const int kIconPadding = 14;
20 const int kIconViewWidth = kIconDimension + 2 * kIconPadding; 22 const int kIconViewWidth = kIconDimension + 2 * kIconPadding;
21 const int kTextTrailPadding = kIconPadding; 23 const int kTextTrailPadding = kIconPadding;
22 const int kBorderSize = 1; 24 const int kBorderSize = 1;
23 25
26 // Maximum dimensions of a search result's action icons.
27 const int kActionIconDimension = 24;
28
29 // Total space (including padding) used for each action icon's button.
30 const int kActionButtonWidth = 32;
31
32 // Extra margin at the right of the rightmost action icon.
33 const int kActionButtonRightMargin = 8;
34
24 const SkColor kBorderColor = SkColorSetARGB(0x0F, 0, 0, 0); 35 const SkColor kBorderColor = SkColorSetARGB(0x0F, 0, 0, 0);
25 36
26 const SkColor kDefaultTextColor = SkColorSetRGB(0x33, 0x33, 0x33); 37 const SkColor kDefaultTextColor = SkColorSetRGB(0x33, 0x33, 0x33);
27 const SkColor kDimmedTextColor = SkColorSetRGB(0x96, 0x96, 0x96); 38 const SkColor kDimmedTextColor = SkColorSetRGB(0x96, 0x96, 0x96);
28 const SkColor kURLTextColor = SkColorSetRGB(0x00, 0x99, 0x33); 39 const SkColor kURLTextColor = SkColorSetRGB(0x00, 0x99, 0x33);
29 40
30 const SkColor kSelectedBorderColor = kBorderColor; 41 const SkColor kSelectedBorderColor = kBorderColor;
31 const SkColor kSelectedBackgroundColor = SkColorSetARGB(0x0F, 0x4D, 0x90, 0xFE); 42 const SkColor kSelectedBackgroundColor = SkColorSetARGB(0x0F, 0x4D, 0x90, 0xFE);
32 const SkColor kHoverAndPushedColor = SkColorSetARGB(0x05, 0, 0, 0); 43 const SkColor kHoverAndPushedColor = SkColorSetARGB(0x05, 0, 0, 0);
33 44
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 } 93 }
83 94
84 } // namespace 95 } // namespace
85 96
86 namespace app_list { 97 namespace app_list {
87 98
88 // static 99 // static
89 const char SearchResultView::kViewClassName[] = "ui/app_list/SearchResultView"; 100 const char SearchResultView::kViewClassName[] = "ui/app_list/SearchResultView";
90 101
91 SearchResultView::SearchResultView(SearchResultListView* list_view, 102 SearchResultView::SearchResultView(SearchResultListView* list_view,
92 views::ButtonListener* listener) 103 SearchResultViewDelegate* delegate)
93 : views::CustomButton(listener), 104 : views::CustomButton(this),
94 result_(NULL), 105 result_(NULL),
95 list_view_(list_view), 106 list_view_(list_view),
107 delegate_(delegate),
96 icon_(new IconView) { 108 icon_(new IconView) {
97 AddChildView(icon_); 109 AddChildView(icon_);
98 } 110 }
99 111
100 SearchResultView::~SearchResultView() { 112 SearchResultView::~SearchResultView() {
101 ClearResultNoRepaint(); 113 ClearResultNoRepaint();
102 } 114 }
103 115
104 void SearchResultView::SetResult(SearchResult* result) { 116 void SearchResultView::SetResult(SearchResult* result) {
105 ClearResultNoRepaint(); 117 ClearResultNoRepaint();
106 118
107 result_ = result; 119 result_ = result;
108 if (result_) 120 if (result_)
109 result_->AddObserver(this); 121 result_->AddObserver(this);
110 122
111 OnIconChanged(); 123 OnIconChanged();
124 OnActionIconsChanged();
112 UpdateTitleText(); 125 UpdateTitleText();
113 UpdateDetailsText(); 126 UpdateDetailsText();
114 SchedulePaint(); 127 SchedulePaint();
115 } 128 }
116 129
117 void SearchResultView::ClearResultNoRepaint() { 130 void SearchResultView::ClearResultNoRepaint() {
118 if (result_) 131 if (result_)
119 result_->RemoveObserver(this); 132 result_->RemoveObserver(this);
120 result_ = NULL; 133 result_ = NULL;
121 } 134 }
(...skipping 26 matching lines...) Expand all
148 161
149 void SearchResultView::Layout() { 162 void SearchResultView::Layout() {
150 gfx::Rect rect(GetContentsBounds()); 163 gfx::Rect rect(GetContentsBounds());
151 if (rect.IsEmpty()) 164 if (rect.IsEmpty())
152 return; 165 return;
153 166
154 gfx::Rect icon_bounds(rect); 167 gfx::Rect icon_bounds(rect);
155 icon_bounds.set_width(kIconViewWidth); 168 icon_bounds.set_width(kIconViewWidth);
156 icon_bounds.Inset(kIconPadding, (rect.height() - kIconDimension) / 2); 169 icon_bounds.Inset(kIconPadding, (rect.height() - kIconDimension) / 2);
157 icon_->SetBoundsRect(icon_bounds.Intersect(rect)); 170 icon_->SetBoundsRect(icon_bounds.Intersect(rect));
171
172 size_t num_buttons = action_buttons_.size();
173 for (size_t i = 0; i < num_buttons; ++i) {
174 views::ImageButton* button = action_buttons_[i];
175 gfx::Rect button_bounds(
176 rect.width() - kActionButtonRightMargin -
xiyuan 2012/08/28 01:01:49 nit: rect.width() -> rect.right() Currently it is
Daniel Erat 2012/08/28 16:45:37 Done.
177 (num_buttons - i) * kActionButtonWidth,
178 (rect.height() - kActionIconDimension) / 2,
xiyuan 2012/08/28 01:01:49 nit: similar to above, add "rect.y() +" so that it
Daniel Erat 2012/08/28 16:45:37 Done.
179 kActionButtonWidth, kActionIconDimension);
180 button->SetBoundsRect(button_bounds);
181 }
158 } 182 }
159 183
160 void SearchResultView::OnPaint(gfx::Canvas* canvas) { 184 void SearchResultView::OnPaint(gfx::Canvas* canvas) {
161 gfx::Rect rect(GetContentsBounds()); 185 gfx::Rect rect(GetContentsBounds());
162 if (rect.IsEmpty()) 186 if (rect.IsEmpty())
163 return; 187 return;
164 188
165 gfx::Rect content_rect(rect); 189 gfx::Rect content_rect(rect);
166 content_rect.set_height(rect.height() - kBorderSize); 190 content_rect.set_height(rect.height() - kBorderSize);
167 191
168 bool selected = list_view_->IsResultViewSelected(this); 192 bool selected = list_view_->IsResultViewSelected(this);
169 if (selected) { 193 if (selected) {
170 canvas->FillRect(content_rect, kSelectedBackgroundColor); 194 canvas->FillRect(content_rect, kSelectedBackgroundColor);
171 } else if (state() == BS_HOT || state() == BS_PUSHED) { 195 } else if (state() == BS_HOT || state() == BS_PUSHED) {
172 canvas->FillRect(content_rect, kHoverAndPushedColor); 196 canvas->FillRect(content_rect, kHoverAndPushedColor);
173 } 197 }
174 198
175 gfx::Rect border_bottom = rect.Subtract(content_rect); 199 gfx::Rect border_bottom = rect.Subtract(content_rect);
176 canvas->FillRect(border_bottom, 200 canvas->FillRect(border_bottom,
177 selected ? kSelectedBorderColor : kBorderColor); 201 selected ? kSelectedBorderColor : kBorderColor);
178 202
179 gfx::Rect text_bounds(rect); 203 gfx::Rect text_bounds(rect);
180 text_bounds.set_x(kIconViewWidth); 204 text_bounds.set_x(kIconViewWidth);
181 text_bounds.set_width(rect.width() - kIconViewWidth - kTextTrailPadding); 205 text_bounds.set_width(
206 rect.width() - kIconViewWidth - kTextTrailPadding -
207 action_buttons_.size() * kActionButtonWidth -
208 (!action_buttons_.empty() ? kActionButtonRightMargin : 0));
182 209
183 if (title_text_.get() && details_text_.get()) { 210 if (title_text_.get() && details_text_.get()) {
184 gfx::Size title_size(text_bounds.width(), 211 gfx::Size title_size(text_bounds.width(),
185 title_text_->GetStringSize().height()); 212 title_text_->GetStringSize().height());
186 gfx::Size details_size(text_bounds.width(), 213 gfx::Size details_size(text_bounds.width(),
187 details_text_->GetStringSize().height()); 214 details_text_->GetStringSize().height());
188 int total_height = title_size.height() + + details_size.height(); 215 int total_height = title_size.height() + + details_size.height();
189 int y = text_bounds.y() + (text_bounds.height() - total_height) / 2; 216 int y = text_bounds.y() + (text_bounds.height() - total_height) / 2;
190 217
191 title_text_->SetDisplayRect(gfx::Rect(gfx::Point(text_bounds.x(), y), 218 title_text_->SetDisplayRect(gfx::Rect(gfx::Point(text_bounds.x(), y),
192 title_size)); 219 title_size));
193 title_text_->Draw(canvas); 220 title_text_->Draw(canvas);
194 221
195 y += title_size.height(); 222 y += title_size.height();
196 details_text_->SetDisplayRect(gfx::Rect(gfx::Point(text_bounds.x(), y), 223 details_text_->SetDisplayRect(gfx::Rect(gfx::Point(text_bounds.x(), y),
197 details_size)); 224 details_size));
198 details_text_->Draw(canvas); 225 details_text_->Draw(canvas);
199 } else if (title_text_.get()) { 226 } else if (title_text_.get()) {
200 gfx::Size title_size(text_bounds.width(), 227 gfx::Size title_size(text_bounds.width(),
201 title_text_->GetStringSize().height()); 228 title_text_->GetStringSize().height());
202 title_text_->SetDisplayRect(text_bounds.Center(title_size)); 229 title_text_->SetDisplayRect(text_bounds.Center(title_size));
203 title_text_->Draw(canvas); 230 title_text_->Draw(canvas);
204 } 231 }
205 } 232 }
206 233
234 void SearchResultView::ButtonPressed(views::Button* sender,
235 const ui::Event& event) {
236 if (sender == this) {
237 delegate_->SearchResultActivated(this, event);
238 return;
239 }
240
241 for (size_t i = 0; i < action_buttons_.size(); ++i) {
242 if (sender == action_buttons_[i]) {
243 delegate_->SearchResultActionActivated(this, i, event);
244 return;
245 }
246 }
247 NOTREACHED() << "Got unexpected button press on " << sender;
248 }
249
207 void SearchResultView::OnIconChanged() { 250 void SearchResultView::OnIconChanged() {
208 gfx::ImageSkia image(result_ ? result_->icon() : gfx::ImageSkia()); 251 gfx::ImageSkia image(result_ ? result_->icon() : gfx::ImageSkia());
209 // Note this might leave the view with an old icon. But it is needed to avoid 252 // Note this might leave the view with an old icon. But it is needed to avoid
210 // flash when a SearchResult's icon is loaded asynchronously. In this case, it 253 // flash when a SearchResult's icon is loaded asynchronously. In this case, it
211 // looks nicer to keep the stale icon for a little while on screen instead of 254 // looks nicer to keep the stale icon for a little while on screen instead of
212 // clearing it out. It should work correctly as long as the SearchResult does 255 // clearing it out. It should work correctly as long as the SearchResult does
213 // not forget to SetIcon when it's ready. 256 // not forget to SetIcon when it's ready.
214 if (image.isNull()) 257 if (image.isNull())
215 return; 258 return;
216 259
217 // Scales down big icons but leave small ones unchanged. 260 // Scales down big icons but leave small ones unchanged.
218 if (image.width() > kIconDimension || image.height() > kIconDimension) 261 if (image.width() > kIconDimension || image.height() > kIconDimension) {
219 icon_->SetImageSize(gfx::Size(kIconDimension, kIconDimension)); 262 image = gfx::ImageSkiaOperations::CreateResizedImage(
Daniel Erat 2012/08/27 23:16:51 I can take this out if you were intentionally usin
xiyuan 2012/08/28 01:01:49 Think your change is better than old code. The per
220 else 263 image,
264 skia::ImageOperations::RESIZE_BEST,
265 gfx::Size(kIconDimension, kIconDimension));
266 } else {
221 icon_->ResetImageSize(); 267 icon_->ResetImageSize();
268 }
222 269
223 icon_->SetImage(image); 270 icon_->SetImage(image);
224 } 271 }
225 272
273 void SearchResultView::OnActionIconsChanged() {
274 while (action_buttons_.size() >
275 (result_ ? result_->action_icons().size() : 0)) {
276 RemoveChildView(action_buttons_.back());
277 action_buttons_.pop_back();
278 }
279
280 if (result_) {
281 while (action_buttons_.size() < result_->action_icons().size()) {
282 views::ImageButton* button = new views::ImageButton(this);
283 button->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
284 views::ImageButton::ALIGN_MIDDLE);
285 AddChildView(button);
286 action_buttons_.push_back(button);
287 }
288
289 const SearchResult::ActionIconSets& icons = result_->action_icons();
290 for (size_t i = 0; i < icons.size(); ++i) {
291 const SearchResult::ActionIconSet& icon = icons.at(i);
292 views::ImageButton* button = action_buttons_[i];
293 button->SetImage(views::CustomButton::BS_NORMAL, &icon.base_image);
294 button->SetImage(views::CustomButton::BS_HOT, &icon.hover_image);
295 button->SetImage(views::CustomButton::BS_PUSHED, &icon.pressed_image);
296 button->SetTooltipText(icon.tooltip_text);
297 }
298 }
299 }
300
226 } // namespace app_list 301 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698