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

Side by Side Diff: ui/app_list/cocoa/apps_search_results_model_bridge.mm

Issue 19460003: One-click install for the OSX App Launcher Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Cleaner, more future-proof Created 6 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/cocoa/apps_search_results_model_bridge.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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 #import "ui/app_list/cocoa/apps_search_results_model_bridge.h" 5 #import "ui/app_list/cocoa/apps_search_results_model_bridge.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #include "base/strings/sys_string_conversions.h" 9 #include "base/strings/sys_string_conversions.h"
10 #include "ui/app_list/app_list_model.h" 10 #include "ui/app_list/app_list_model.h"
11 #import "ui/app_list/cocoa/apps_search_results_controller.h" 11 #import "ui/app_list/cocoa/apps_search_results_controller.h"
12 #include "ui/app_list/search_result.h" 12 #include "ui/app_list/search_result.h"
13 #include "ui/app_list/search_result_observer.h" 13 #include "ui/app_list/search_result_observer.h"
14 #import "ui/base/cocoa/controls/blue_label_button.h"
14 #import "ui/base/cocoa/menu_controller.h" 15 #import "ui/base/cocoa/menu_controller.h"
15 16
17 namespace {
18
19 // Padding on the left and right of action buttons.
20 const CGFloat kActionButtonPadding = 10;
21
22 }
23
24 // Action target for all the action buttons on a result row.
25 @interface ActionButtonTarget : NSObject {
26 @private
27 app_list::AppsSearchResultsModelBridge::ItemObserver* parent_;
28 }
29
30 // Designated initializer.
31 - (id)initWithParent:
32 (app_list::AppsSearchResultsModelBridge::ItemObserver*)parent;
33
34 // |sender| is the NSButton for the action.
35 - (void)onActionButtonClicked:(id)sender;
36
37 @end
38
16 namespace app_list { 39 namespace app_list {
17 40
18 class AppsSearchResultsModelBridge::ItemObserver : public SearchResultObserver { 41 class AppsSearchResultsModelBridge::ItemObserver : public SearchResultObserver {
19 public: 42 public:
20 ItemObserver(AppsSearchResultsModelBridge* bridge, size_t index) 43 ItemObserver(AppsSearchResultsModelBridge* bridge, size_t index)
21 : bridge_(bridge), row_in_view_(index) { 44 : bridge_(bridge), row_in_view_(index) {
22 // Cache the result, because the results array is updated before notifying 45 // Cache the result, because the results array is updated before notifying
23 // observers (which happens before deleting the SearchResult). 46 // observers (which happens before deleting the SearchResult).
24 result_ = [bridge_->parent_ results]->GetItemAt(index); 47 result_ = [bridge_->parent_ results]->GetItemAt(index);
48 OnActionsChanged();
25 result_->AddObserver(this); 49 result_->AddObserver(this);
26 } 50 }
27 51
28 virtual ~ItemObserver() { 52 virtual ~ItemObserver() {
29 result_->RemoveObserver(this); 53 result_->RemoveObserver(this);
54 [action_button_ removeFromSuperview];
55 [action_button_ setTarget:nil];
30 } 56 }
31 57
32 NSMenu* GetContextMenu() { 58 NSMenu* GetContextMenu() {
33 if (!context_menu_controller_) { 59 if (!context_menu_controller_) {
34 ui::MenuModel* menu_model = result_->GetContextMenuModel(); 60 ui::MenuModel* menu_model = result_->GetContextMenuModel();
35 if (!menu_model) 61 if (!menu_model)
36 return nil; 62 return nil;
37 63
38 context_menu_controller_.reset( 64 context_menu_controller_.reset(
39 [[MenuController alloc] initWithModel:menu_model 65 [[MenuController alloc] initWithModel:menu_model
40 useWithPopUpButtonCell:NO]); 66 useWithPopUpButtonCell:NO]);
41 } 67 }
42 return [context_menu_controller_ menu]; 68 return [context_menu_controller_ menu];
43 } 69 }
44 70
71 CGFloat GetActionButtonWidth() {
72 CGFloat width = NSWidth([action_button_ bounds]);
73 if (width != 0)
74 width += kActionButtonPadding;
75 return width;
76 }
77
78 void InvokeActionAtIndex(int action_index) {
79 [[bridge_->parent_ delegate] invokeResultAction:result_
80 atIndex:action_index];
81 }
82
45 // SearchResultObserver overrides: 83 // SearchResultObserver overrides:
46 virtual void OnIconChanged() OVERRIDE { 84 virtual void OnIconChanged() OVERRIDE {
47 bridge_->ReloadDataForItems(row_in_view_, 1); 85 bridge_->ReloadDataForItems(row_in_view_, 1);
48 } 86 }
49 virtual void OnActionsChanged() OVERRIDE {} 87 virtual void OnActionsChanged() OVERRIDE;
50 virtual void OnIsInstallingChanged() OVERRIDE {} 88 virtual void OnIsInstallingChanged() OVERRIDE {}
51 virtual void OnPercentDownloadedChanged() OVERRIDE {} 89 virtual void OnPercentDownloadedChanged() OVERRIDE {}
52 virtual void OnItemInstalled() OVERRIDE {} 90 virtual void OnItemInstalled() OVERRIDE {}
53 virtual void OnItemUninstalled() OVERRIDE; 91 virtual void OnItemUninstalled() OVERRIDE;
54 92
55 private: 93 private:
56 AppsSearchResultsModelBridge* bridge_; // Weak. Owns us. 94 AppsSearchResultsModelBridge* bridge_; // Weak. Owns us.
57 SearchResult* result_; // Weak. Owned by AppListModel::SearchResults. 95 SearchResult* result_; // Weak. Owned by AppListModel::SearchResults.
58 size_t row_in_view_; 96 size_t row_in_view_;
97 base::scoped_nsobject<ActionButtonTarget> action_target_;
98 base::scoped_nsobject<NSButton> action_button_;
59 base::scoped_nsobject<MenuController> context_menu_controller_; 99 base::scoped_nsobject<MenuController> context_menu_controller_;
60 100
61 DISALLOW_COPY_AND_ASSIGN(ItemObserver); 101 DISALLOW_COPY_AND_ASSIGN(ItemObserver);
62 }; 102 };
63 103
64 void AppsSearchResultsModelBridge::ItemObserver::OnItemUninstalled() { 104 void AppsSearchResultsModelBridge::ItemObserver::OnItemUninstalled() {
65 // Performing the search again will destroy |this|, so post a task. This also 105 // Performing the search again will destroy |this|, so post a task. This also
66 // ensures that the AppSearchProvider has observed the uninstall before 106 // ensures that the AppSearchProvider has observed the uninstall before
67 // performing the search again, otherwise it will provide a NULL result. 107 // performing the search again, otherwise it will provide a NULL result.
68 [[bridge_->parent_ delegate] performSelector:@selector(redoSearch) 108 [[bridge_->parent_ delegate] performSelector:@selector(redoSearch)
69 withObject:nil 109 withObject:nil
70 afterDelay:0]; 110 afterDelay:0];
71 } 111 }
72 112
113 void AppsSearchResultsModelBridge::ItemObserver::OnActionsChanged() {
114 [action_button_ removeFromSuperview];
115 action_button_.reset();
116 const SearchResult::Actions& actions = result_->actions();
117 if (actions.empty())
118 return;
119
120 size_t action_index = 0;
121 const SearchResult::Action& action = actions[action_index];
122 if (action.label_text.empty() || actions.size() != 1) {
123 // TODO(tapted) Support multiple action buttons.
124 NOTIMPLEMENTED();
125 return;
126 }
127
128 if (!action_target_)
129 action_target_.reset([[ActionButtonTarget alloc] initWithParent:this]);
130
131 action_button_.reset([[BlueLabelButton alloc] initWithFrame:NSZeroRect]);
132 [action_button_ setTitle:base::SysUTF16ToNSString(action.label_text)];
133 [action_button_ setTarget:action_target_];
134 [action_button_ setAction:@selector(onActionButtonClicked:)];
135 [action_button_ setTag:action_index];
136 [action_button_ sizeToFit];
137 NSRect button_frame = [action_button_ frame];
138 NSRect cell_frame =
139 [[bridge_->parent_ tableView] frameOfCellAtColumn:0
140 row:row_in_view_];
141 NSPoint origin = NSMakePoint(
142 NSWidth(cell_frame) - NSWidth(button_frame) - kActionButtonPadding,
143 ceil(NSMidY(cell_frame) - NSMidY(button_frame)));
144 [action_button_ setFrameOrigin:origin];
145 [[bridge_->parent_ tableView] addSubview:action_button_];
146 }
147
73 AppsSearchResultsModelBridge::AppsSearchResultsModelBridge( 148 AppsSearchResultsModelBridge::AppsSearchResultsModelBridge(
74 AppsSearchResultsController* results_controller) 149 AppsSearchResultsController* results_controller)
75 : parent_(results_controller) { 150 : parent_(results_controller) {
76 UpdateItemObservers(); 151 UpdateItemObservers();
77 [parent_ results]->AddObserver(this); 152 [parent_ results]->AddObserver(this);
78 } 153 }
79 154
80 AppsSearchResultsModelBridge::~AppsSearchResultsModelBridge() { 155 AppsSearchResultsModelBridge::~AppsSearchResultsModelBridge() {
81 [parent_ results]->RemoveObserver(this); 156 [parent_ results]->RemoveObserver(this);
82 } 157 }
83 158
84 NSMenu* AppsSearchResultsModelBridge::MenuForItem(size_t index) { 159 NSMenu* AppsSearchResultsModelBridge::MenuForItem(size_t index) {
85 DCHECK_LT(index, item_observers_.size()); 160 DCHECK_LT(index, item_observers_.size());
86 return item_observers_[index]->GetContextMenu(); 161 return item_observers_[index]->GetContextMenu();
87 } 162 }
88 163
164 CGFloat AppsSearchResultsModelBridge::ActionButtonWidthForItem(size_t index) {
165 DCHECK_LT(index, item_observers_.size());
166 return item_observers_[index]->GetActionButtonWidth();
167 }
168
89 void AppsSearchResultsModelBridge::UpdateItemObservers() { 169 void AppsSearchResultsModelBridge::UpdateItemObservers() {
90 DCHECK(item_observers_.empty()); 170 DCHECK(item_observers_.empty());
91 const size_t itemCount = [parent_ results]->item_count(); 171 const size_t itemCount = [parent_ results]->item_count();
92 for (size_t i = 0 ; i < itemCount; ++i) 172 for (size_t i = 0 ; i < itemCount; ++i)
93 item_observers_.push_back(new ItemObserver(this, i)); 173 item_observers_.push_back(new ItemObserver(this, i));
94 } 174 }
95 175
96 void AppsSearchResultsModelBridge::ReloadDataForItems( 176 void AppsSearchResultsModelBridge::ReloadDataForItems(
97 size_t start, size_t count) const { 177 size_t start, size_t count) const {
98 NSIndexSet* column = [NSIndexSet indexSetWithIndex:0]; 178 NSIndexSet* column = [NSIndexSet indexSetWithIndex:0];
(...skipping 29 matching lines...) Expand all
128 } 208 }
129 209
130 void AppsSearchResultsModelBridge::ListItemsChanged( 210 void AppsSearchResultsModelBridge::ListItemsChanged(
131 size_t start, size_t count) { 211 size_t start, size_t count) {
132 item_observers_.clear(); 212 item_observers_.clear();
133 ReloadDataForItems(start, count); 213 ReloadDataForItems(start, count);
134 UpdateItemObservers(); 214 UpdateItemObservers();
135 } 215 }
136 216
137 } // namespace app_list 217 } // namespace app_list
218
219 @implementation ActionButtonTarget
220
221 - (id)initWithParent:
222 (app_list::AppsSearchResultsModelBridge::ItemObserver*)parent {
223 if ((self = [super init])) {
224 parent_ = parent;
225 }
226 return self;
227 }
228
229 - (void)onActionButtonClicked:(id)sender {
230 parent_->InvokeActionAtIndex([sender tag]);
231 }
232
233 @end
OLDNEW
« no previous file with comments | « ui/app_list/cocoa/apps_search_results_model_bridge.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698