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

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

Issue 11784034: Skeleton for app_list on OSX, and refactoring for enable_app_list=1 on OS=="mac". (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase for 175876 and 175961 Created 7 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
« no previous file with comments | « ui/app_list/app_list_view.h ('k') | ui/app_list/apps_grid_view.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "ui/app_list/app_list_view.h"
6
7 #include <algorithm>
8
9 #include "base/string_util.h"
10 #include "ui/app_list/app_list_background.h"
11 #include "ui/app_list/app_list_constants.h"
12 #include "ui/app_list/app_list_item_model.h"
13 #include "ui/app_list/app_list_item_view.h"
14 #include "ui/app_list/app_list_model.h"
15 #include "ui/app_list/app_list_view_delegate.h"
16 #include "ui/app_list/contents_view.h"
17 #include "ui/app_list/pagination_model.h"
18 #include "ui/app_list/search_box_model.h"
19 #include "ui/app_list/search_box_view.h"
20 #include "ui/base/events/event.h"
21 #include "ui/gfx/insets.h"
22 #include "ui/gfx/path.h"
23 #include "ui/gfx/skia_util.h"
24 #include "ui/views/bubble/bubble_frame_view.h"
25 #include "ui/views/controls/textfield/textfield.h"
26 #include "ui/views/layout/box_layout.h"
27 #include "ui/views/widget/widget.h"
28
29 namespace app_list {
30
31 namespace {
32
33 // Inner padding space in pixels of bubble contents.
34 const int kInnerPadding = 1;
35
36 // The distance between the arrow tip and edge of the anchor view.
37 const int kArrowOffset = 10;
38
39 // The maximum allowed time to wait for icon loading in milliseconds.
40 const int kMaxIconLoadingWaitTimeInMs = 50;
41
42 } // namespace
43
44 ////////////////////////////////////////////////////////////////////////////////
45 // AppListView::IconLoader
46
47 class AppListView::IconLoader : public AppListItemModelObserver {
48 public:
49 IconLoader(AppListView* owner,
50 AppListItemModel* item,
51 ui::ScaleFactor scale_factor)
52 : owner_(owner),
53 item_(item) {
54 item_->AddObserver(this);
55
56 // Triggers icon loading for given |scale_factor|.
57 item_->icon().GetRepresentation(scale_factor);
58 }
59
60 virtual ~IconLoader() {
61 item_->RemoveObserver(this);
62 }
63
64 private:
65 // AppListItemModelObserver overrides:
66 virtual void ItemIconChanged() OVERRIDE {
67 owner_->OnItemIconLoaded(this);
68 // Note that IconLoader is released here.
69 }
70 virtual void ItemTitleChanged() OVERRIDE {}
71 virtual void ItemHighlightedChanged() OVERRIDE {}
72
73 AppListView* owner_;
74 AppListItemModel* item_;
75
76 DISALLOW_COPY_AND_ASSIGN(IconLoader);
77 };
78
79 ////////////////////////////////////////////////////////////////////////////////
80 // AppListView:
81
82 AppListView::AppListView(AppListViewDelegate* delegate)
83 : model_(new AppListModel),
84 delegate_(delegate),
85 search_box_view_(NULL),
86 contents_view_(NULL) {
87 if (delegate_)
88 delegate_->SetModel(model_.get());
89 }
90
91 AppListView::~AppListView() {
92 // Models are going away, ensure their references are cleared.
93 RemoveAllChildViews(true);
94 pending_icon_loaders_.clear();
95 }
96
97 void AppListView::InitAsBubble(
98 gfx::NativeView parent,
99 PaginationModel* pagination_model,
100 views::View* anchor,
101 const gfx::Point& anchor_point,
102 views::BubbleBorder::ArrowLocation arrow_location) {
103 // Starts icon loading early.
104 PreloadIcons(pagination_model, anchor);
105
106 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
107 kInnerPadding,
108 kInnerPadding,
109 kInnerPadding));
110
111 search_box_view_ = new SearchBoxView(this);
112 AddChildView(search_box_view_);
113
114 contents_view_ = new ContentsView(this, pagination_model);
115 AddChildView(contents_view_);
116
117 search_box_view_->set_contents_view(contents_view_);
118
119 set_anchor_view(anchor);
120 set_anchor_point(anchor_point);
121 set_color(kContentsBackgroundColor);
122 set_margins(gfx::Insets());
123 set_move_with_anchor(true);
124 set_parent_window(parent);
125 set_close_on_deactivate(false);
126 set_close_on_esc(false);
127 set_anchor_insets(gfx::Insets(kArrowOffset, kArrowOffset,
128 kArrowOffset, kArrowOffset));
129 set_shadow(views::BubbleBorder::BIG_SHADOW);
130 views::BubbleDelegateView::CreateBubble(this);
131 SetBubbleArrowLocation(arrow_location);
132
133 #if defined(USE_AURA)
134 GetBubbleFrameView()->set_background(new AppListBackground(
135 GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(),
136 search_box_view_));
137
138 contents_view_->SetPaintToLayer(true);
139 contents_view_->SetFillsBoundsOpaquely(false);
140 contents_view_->layer()->SetMasksToBounds(true);
141 set_background(NULL);
142 #else
143 set_background(new AppListBackground(
144 GetBubbleFrameView()->bubble_border()->GetBorderCornerRadius(),
145 search_box_view_));
146 #endif
147
148 search_box_view_->SetModel(model_->search_box());
149 contents_view_->SetModel(model_.get());
150 }
151
152 void AppListView::SetBubbleArrowLocation(
153 views::BubbleBorder::ArrowLocation arrow_location) {
154 GetBubbleFrameView()->bubble_border()->set_arrow_location(arrow_location);
155 SizeToContents(); // Recalcuates with new border.
156 GetBubbleFrameView()->SchedulePaint();
157 }
158
159 void AppListView::SetAnchorPoint(const gfx::Point& anchor_point) {
160 set_anchor_point(anchor_point);
161 SizeToContents(); // Repositions view relative to the anchor.
162 }
163
164 void AppListView::ShowWhenReady() {
165 if (pending_icon_loaders_.empty()) {
166 icon_loading_wait_timer_.Stop();
167 GetWidget()->Show();
168 return;
169 }
170
171 if (icon_loading_wait_timer_.IsRunning())
172 return;
173
174 icon_loading_wait_timer_.Start(
175 FROM_HERE,
176 base::TimeDelta::FromMilliseconds(kMaxIconLoadingWaitTimeInMs),
177 this, &AppListView::OnIconLoadingWaitTimer);
178 }
179
180 void AppListView::Close() {
181 icon_loading_wait_timer_.Stop();
182
183 if (delegate_.get())
184 delegate_->Dismiss();
185 else
186 GetWidget()->Close();
187 }
188
189 void AppListView::UpdateBounds() {
190 SizeToContents();
191 }
192
193 void AppListView::PreloadIcons(PaginationModel* pagination_model,
194 views::View* anchor) {
195 ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P;
196 if (anchor && anchor->GetWidget()) {
197 scale_factor = ui::GetScaleFactorForNativeView(
198 anchor->GetWidget()->GetNativeView());
199 }
200
201 // |pagination_model| could have -1 as the initial selected page and
202 // assumes first page (i.e. index 0) will be used in this case.
203 const int selected_page = std::max(0, pagination_model->selected_page());
204
205 const int tiles_per_page = kPreferredCols * kPreferredRows;
206 const int start_model_index = selected_page * tiles_per_page;
207 const int end_model_index = std::min(
208 static_cast<int>(model_->apps()->item_count()),
209 start_model_index + tiles_per_page);
210
211 pending_icon_loaders_.clear();
212 for (int i = start_model_index; i < end_model_index; ++i) {
213 AppListItemModel* item = model_->apps()->GetItemAt(i);
214 if (item->icon().HasRepresentation(scale_factor))
215 continue;
216
217 pending_icon_loaders_.push_back(new IconLoader(this, item, scale_factor));
218 }
219 }
220
221 void AppListView::OnIconLoadingWaitTimer() {
222 GetWidget()->Show();
223 }
224
225 void AppListView::OnItemIconLoaded(IconLoader* loader) {
226 ScopedVector<IconLoader>::iterator it = std::find(
227 pending_icon_loaders_.begin(), pending_icon_loaders_.end(), loader);
228 DCHECK(it != pending_icon_loaders_.end());
229 pending_icon_loaders_.erase(it);
230
231 if (pending_icon_loaders_.empty() && icon_loading_wait_timer_.IsRunning()) {
232 icon_loading_wait_timer_.Stop();
233 GetWidget()->Show();
234 }
235 }
236
237 views::View* AppListView::GetInitiallyFocusedView() {
238 return search_box_view_->search_box();
239 }
240
241 bool AppListView::WidgetHasHitTestMask() const {
242 return true;
243 }
244
245 void AppListView::GetWidgetHitTestMask(gfx::Path* mask) const {
246 DCHECK(mask);
247 mask->addRect(gfx::RectToSkRect(
248 GetBubbleFrameView()->GetContentsBounds()));
249 }
250
251 bool AppListView::AcceleratorPressed(const ui::Accelerator& accelerator) {
252 // The accelerator is added by BubbleDelegateView.
253 if (accelerator.key_code() == ui::VKEY_ESCAPE) {
254 Close();
255 return true;
256 }
257
258 return false;
259 }
260
261 void AppListView::ActivateApp(AppListItemModel* item, int event_flags) {
262 if (delegate_.get())
263 delegate_->ActivateAppListItem(item, event_flags);
264 }
265
266 void AppListView::QueryChanged(SearchBoxView* sender) {
267 string16 query;
268 TrimWhitespace(model_->search_box()->text(), TRIM_ALL, &query);
269 bool should_show_search = !query.empty();
270 contents_view_->ShowSearchResults(should_show_search);
271
272 if (delegate_.get()) {
273 if (should_show_search)
274 delegate_->StartSearch();
275 else
276 delegate_->StopSearch();
277 }
278 }
279
280 void AppListView::OpenResult(const SearchResult& result, int event_flags) {
281 if (delegate_.get())
282 delegate_->OpenSearchResult(result, event_flags);
283 }
284
285 void AppListView::InvokeResultAction(const SearchResult& result,
286 int action_index,
287 int event_flags) {
288 if (delegate_.get())
289 delegate_->InvokeSearchResultAction(result, action_index, event_flags);
290 }
291
292 void AppListView::OnWidgetClosing(views::Widget* widget) {
293 BubbleDelegateView::OnWidgetClosing(widget);
294 if (delegate_.get() && widget == GetWidget())
295 delegate_->ViewClosing();
296 }
297
298 void AppListView::OnWidgetActivationChanged(views::Widget* widget,
299 bool active) {
300 // Do not called inherited function as the bubble delegate auto close
301 // functionality is not used.
302 if (delegate_.get() && widget == GetWidget())
303 delegate_->ViewActivationChanged(active);
304 }
305
306 } // namespace app_list
OLDNEW
« no previous file with comments | « ui/app_list/app_list_view.h ('k') | ui/app_list/apps_grid_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698