Chromium Code Reviews| 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); | |
|
marq (ping after 24h)
2017/05/31 12:26:09
Why not -performSelector:withObject: ?
(my concer
kkhorimoto
2017/05/31 18:00:20
|-performSelector:withObject| doesn't compile unde
| |
| 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, strong) ContextMenuContext* context; | |
| 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 DCHECK(context); | |
| 64 self.context = context; | |
| 65 } | |
| 66 | |
| 37 - (void)setContextMenuTitle:(NSString*)title { | 67 - (void)setContextMenuTitle:(NSString*)title { |
| 38 self.title = title; | 68 self.title = title; |
| 39 } | 69 } |
| 40 | 70 |
| 41 - (void)setContextMenuItems:(NSArray<ContextMenuItem*>*)items { | 71 - (void)setContextMenuItems:(NSArray<ContextMenuItem*>*)items |
| 72 cancelItem:(ContextMenuItem*)cancelItem { | |
| 73 // Add an alert action for each item in |items|, then add |cancelItem|. | |
| 42 for (ContextMenuItem* item in items) { | 74 for (ContextMenuItem* item in items) { |
| 43 // Create a block that sends the invocation passed in with the item's | 75 [self addAction:[self alertActionForItem:item |
| 44 // configuration to the dispatcher. | 76 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 } | 77 } |
| 78 [self addAction:[self alertActionForItem:cancelItem | |
| 79 style:UIAlertActionStyleCancel]]; | |
| 80 } | |
| 52 | 81 |
| 53 // Always add a cancel action. | 82 #pragma mark - |
| 54 [self addAction:[UIAlertAction actionWithTitle:@"Cancel" | 83 |
| 55 style:UIAlertActionStyleCancel | 84 - (UIAlertAction*)alertActionForItem:(ContextMenuItem*)item |
| 56 handler:nil]]; | 85 style:(UIAlertActionStyle)style { |
| 86 DCHECK(item); | |
| 87 // Create a block that dispatches |item|'s ContextMenuCommands. | |
| 88 AlertActionHandler handler = ^(UIAlertAction* action) { | |
| 89 DispatchContextMenuCommands(item.commands, self.dispatcher, self.context); | |
| 90 }; | |
| 91 return [UIAlertAction actionWithTitle:item.title style:style handler:handler]; | |
| 57 } | 92 } |
| 58 | 93 |
| 59 @end | 94 @end |
| OLD | NEW |