OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "ios/clean/chrome/browser/ui/context_menu/context_menu_view_controller.h " | 5 #import "ios/clean/chrome/browser/ui/context_menu/context_menu_view_controller.h " |
6 | 6 |
7 #include "base/logging.h" | |
8 #import "ios/clean/chrome/browser/ui/context_menu/context_menu_context.h" | |
9 | |
7 #if !defined(__has_feature) || !__has_feature(objc_arc) | 10 #if !defined(__has_feature) || !__has_feature(objc_arc) |
8 #error "This file requires ARC support." | 11 #error "This file requires ARC support." |
9 #endif | 12 #endif |
10 | 13 |
11 namespace { | 14 namespace { |
12 // Typedef the block parameter for UIAlertAction for readability. | 15 // Typedef the block parameter for UIAlertAction for readability. |
13 typedef void (^AlertActionHandler)(UIAlertAction*); | 16 typedef void (^AlertActionHandler)(UIAlertAction*); |
17 // Sends |commands| to |dispatcher| using |context| as the menu context. | |
18 void DispatchContextMenuCommands(const std::vector<SEL>& commands, | |
19 id dispatcher, | |
20 ContextMenuContext* context) { | |
21 DCHECK(dispatcher); | |
22 DCHECK(context); | |
23 for (SEL command : commands) { | |
24 IMP command_imp = [dispatcher methodForSelector:command]; | |
25 DCHECK(command_imp); | |
26 command_imp(dispatcher, command, context); | |
27 } | |
28 } | |
14 } | 29 } |
15 | 30 |
16 @interface ContextMenuViewController () | 31 @interface ContextMenuViewController () |
17 // Object to which command messages will be sent. | 32 // The dispatcher passed on initialization. |
18 @property(nonatomic, weak) id dispatcher; | 33 @property(nonatomic, readonly, weak) id<ContextMenuCommands> dispatcher; |
34 // The context passed on initialization. | |
35 @property(nonatomic, weak) ContextMenuContext* context; | |
edchin
2017/05/25 21:41:53
Should this be strong?
kkhorimoto
2017/05/26 23:20:09
The context object is owned by the coordinator, so
| |
36 | |
37 // Creates an UIAlertAction for |item| using |style| to manage the action's | |
38 // appearance. | |
39 - (UIAlertAction*)alertActionForItem:(ContextMenuItem*)item | |
40 style:(UIAlertActionStyle)style; | |
41 | |
19 @end | 42 @end |
20 | 43 |
21 @implementation ContextMenuViewController | 44 @implementation ContextMenuViewController |
22 @synthesize dispatcher = _dispatcher; | 45 @synthesize dispatcher = _dispatcher; |
46 @synthesize context = _context; | |
23 | 47 |
24 - (instancetype)initWithDispatcher:(id)dispatcher { | 48 - (instancetype)initWithDispatcher:(id<ContextMenuCommands>)dispatcher { |
25 self = | 49 self = |
26 [[self class] alertControllerWithTitle:nil | 50 [[self class] alertControllerWithTitle:nil |
27 message:nil | 51 message:nil |
28 preferredStyle:UIAlertControllerStyleActionSheet]; | 52 preferredStyle:UIAlertControllerStyleActionSheet]; |
29 if (self) { | 53 if (self) { |
54 DCHECK(dispatcher); | |
30 _dispatcher = dispatcher; | 55 _dispatcher = dispatcher; |
31 } | 56 } |
32 return self; | 57 return self; |
33 } | 58 } |
34 | 59 |
35 #pragma mark - ContextMenuConsumer | 60 #pragma mark - ContextMenuConsumer |
36 | 61 |
62 - (void)setContextMenuContext:(ContextMenuContext*)context { | |
63 self.context = context; | |
edchin
2017/05/25 21:41:53
DCHECK(context)
kkhorimoto
2017/05/26 23:20:09
Done.
| |
64 } | |
65 | |
37 - (void)setContextMenuTitle:(NSString*)title { | 66 - (void)setContextMenuTitle:(NSString*)title { |
38 self.title = title; | 67 self.title = title; |
39 } | 68 } |
40 | 69 |
41 - (void)setContextMenuItems:(NSArray<ContextMenuItem*>*)items { | 70 - (void)setContextMenuItems:(NSArray<ContextMenuItem*>*)items |
71 cancelItem:(ContextMenuItem*)cancelItem { | |
72 // Add an alert action for each item in |items|, then add |cancelItem|. | |
42 for (ContextMenuItem* item in items) { | 73 for (ContextMenuItem* item in items) { |
43 // Create a block that sends the invocation passed in with the item's | 74 [self addAction:[self alertActionForItem:item |
44 // configuration to the dispatcher. | 75 style:UIAlertActionStyleDefault]]; |
45 AlertActionHandler handler = ^(UIAlertAction* action) { | |
46 [item.command invokeWithTarget:self.dispatcher]; | |
47 }; | |
48 [self addAction:[UIAlertAction actionWithTitle:item.title | |
49 style:UIAlertActionStyleDefault | |
50 handler:handler]]; | |
51 } | 76 } |
77 [self addAction:[self alertActionForItem:cancelItem | |
78 style:UIAlertActionStyleCancel]]; | |
79 } | |
52 | 80 |
53 // Always add a cancel action. | 81 #pragma mark - |
54 [self addAction:[UIAlertAction actionWithTitle:@"Cancel" | 82 |
55 style:UIAlertActionStyleCancel | 83 - (UIAlertAction*)alertActionForItem:(ContextMenuItem*)item |
56 handler:nil]]; | 84 style:(UIAlertActionStyle)style { |
85 DCHECK(item); | |
86 // Create a block that dispatches |item|'s ContextMenuCommands. | |
87 AlertActionHandler handler = ^(UIAlertAction* action) { | |
88 DispatchContextMenuCommands(item.commands, self.dispatcher, self.context); | |
89 }; | |
90 return [UIAlertAction actionWithTitle:item.title style:style handler:handler]; | |
57 } | 91 } |
58 | 92 |
59 @end | 93 @end |
OLD | NEW |