OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 #import "ios/clean/chrome/browser/ui/presenters/menu_presentation_controller.h" | |
6 | |
7 #import <QuartzCore/QuartzCore.h> | |
8 | |
9 #include "ios/clean/chrome/browser/ui/commands/tools_menu_commands.h" | |
10 #include "ios/clean/chrome/browser/ui/presenters/menu_presentation_delegate.h" | |
11 | |
12 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
13 #error "This file requires ARC support." | |
14 #endif | |
15 | |
16 @interface MenuPresentationController () | |
17 @property(nonatomic, weak) id<MenuPresentationDelegate> presentationDelegate; | |
18 @property(nonatomic, assign) CGRect presentationFrame; | |
19 @property(nonatomic, strong) UITapGestureRecognizer* dismissRecognizer; | |
20 @end | |
21 | |
22 @implementation MenuPresentationController | |
23 @synthesize presentationDelegate = _presentationDelegate; | |
24 @synthesize presentationFrame = _presentationFrame; | |
25 @synthesize dispatcher = _dispatcher; | |
26 @synthesize dismissRecognizer = _dismissRecognizer; | |
27 | |
28 #pragma mark - UIPresentationDelegate | |
29 | |
30 - (CGRect)frameOfPresentedViewInContainerView { | |
31 if (CGRectIsEmpty(self.presentationFrame)) { | |
32 [self updatePresentationDelegate]; | |
33 if (self.presentationDelegate) { | |
34 self.presentationFrame = [self | |
35 frameForPresentationWithSize:self.presentedView.frame.size | |
36 origin:[self.presentationDelegate | |
37 originForMenuPresentation] | |
38 bounds:[self.presentationDelegate | |
39 boundsForMenuPresentation]]; | |
40 } else { | |
41 // Placeholder default frame: centered in the presenting view. | |
42 CGSize menuSize = self.presentedView.frame.size; | |
43 self.presentationFrame.size = menuSize; | |
44 self.presentationFrame.origin = CGPointMake( | |
45 (self.containerView.bounds.size.width - menuSize.width) / 2.0, | |
46 (self.containerView.bounds.size.height - menuSize.height) / 2.0); | |
47 } | |
48 } | |
49 return self.presentationFrame; | |
50 } | |
51 | |
52 - (void)presentationTransitionWillBegin { | |
53 self.presentedView.layer.shadowRadius = 5.0f; | |
54 self.presentedView.layer.shadowOpacity = 0.4f; | |
55 self.presentedView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f); | |
56 self.presentedView.layer.cornerRadius = 2.0f; | |
57 | |
58 self.dismissRecognizer = | |
59 [[UITapGestureRecognizer alloc] initWithTarget:self | |
60 action:@selector(tapToDismiss:)]; | |
61 [self.containerView addGestureRecognizer:self.dismissRecognizer]; | |
62 } | |
63 | |
64 #pragma mark - Private methods. | |
65 | |
66 - (void)tapToDismiss:(UIGestureRecognizer*)recognizer { | |
67 [self.dispatcher closeToolsMenu]; | |
68 } | |
69 | |
70 // Checks if the presenting view controller conforms to | |
71 // MenuPresentationDelegate and, if so, sets that view controller as the | |
72 // presentation delegate. This can't be done at init time, becuase the | |
73 // presenting view controller may not have been determined by UIKit yet. | |
74 - (void)updatePresentationDelegate { | |
75 if ([self.presentingViewController | |
76 conformsToProtocol:@protocol(MenuPresentationDelegate)]) { | |
77 self.presentationDelegate = static_cast<id<MenuPresentationDelegate>>( | |
78 self.presentingViewController); | |
79 } | |
80 } | |
81 | |
82 - (CGRect)frameForPresentationWithSize:(CGSize)menuSize | |
83 origin:(CGRect)menuOriginRect | |
84 bounds:(CGRect)presentationBounds { | |
85 CGRect menuRect; | |
86 menuRect.size = menuSize; | |
87 | |
88 if (CGRectIsNull(menuOriginRect)) { | |
89 menuRect.origin = CGPointMake(50, 50); | |
90 return menuRect; | |
91 } | |
92 // Calculate which corner of the menu the origin rect is in. This is | |
93 // determined by comparing frames, and thus is RTL-independent. | |
94 if (CGRectGetMinX(menuOriginRect) - CGRectGetMinX(presentationBounds) < | |
95 CGRectGetMaxX(presentationBounds) - CGRectGetMaxX(menuOriginRect)) { | |
96 // Origin rect is closer to the left edge of |self.view| than to the right. | |
97 menuRect.origin.x = CGRectGetMinX(menuOriginRect); | |
98 } else { | |
99 // Origin rect is closer to the right edge of |self.view| than to the left. | |
100 menuRect.origin.x = CGRectGetMaxX(menuOriginRect) - menuSize.width; | |
101 } | |
102 | |
103 if (CGRectGetMinY(menuOriginRect) - CGRectGetMinY(presentationBounds) < | |
104 CGRectGetMaxY(presentationBounds) - CGRectGetMaxY(menuOriginRect)) { | |
105 // Origin rect is closer to the top edge of |self.view| than to the bottom. | |
106 menuRect.origin.y = CGRectGetMinY(menuOriginRect); | |
107 } else { | |
108 // Origin rect is closer to the bottom edge of |self.view| than to the top. | |
109 menuRect.origin.y = CGRectGetMaxY(menuOriginRect) - menuSize.height; | |
110 } | |
111 | |
112 return menuRect; | |
113 } | |
114 | |
115 @end | |
OLD | NEW |