Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / ios / chrome / browser / ui / ui_util.mm
blob036c5f3462967909be30b76ce1a32d5b1c458427
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
3 // found in the LICENSE file.
5 #include "ios/chrome/browser/ui/ui_util.h"
7 #import <UIKit/UIKit.h>
9 #include "base/ios/ios_util.h"
10 #import "ios/chrome/browser/ui/uikit_ui_util.h"
11 #include "ui/gfx/ios/uikit_util.h"
13 bool IsIPadIdiom() {
14   UIUserInterfaceIdiom idiom = [[UIDevice currentDevice] userInterfaceIdiom];
15   return idiom == UIUserInterfaceIdiomPad;
18 bool IsHighResScreen() {
19   return [[UIScreen mainScreen] scale] > 1.0;
22 bool IsPortrait() {
23   UIInterfaceOrientation orient = GetInterfaceOrientation();
24 // If building with an SDK prior to iOS 8 don't worry about
25 // UIInterfaceOrientationUnknown because it wasn't defined.
26 #if !defined(__IPHONE_8_0) || __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0
27   return UIInterfaceOrientationIsPortrait(orient);
28 #else
29   return UIInterfaceOrientationIsPortrait(orient) ||
30          orient == UIInterfaceOrientationUnknown;
31 #endif  // SDK
34 bool IsLandscape() {
35   return UIInterfaceOrientationIsLandscape(GetInterfaceOrientation());
38 CGFloat CurrentScreenHeight() {
39   CGSize screenSize = [UIScreen mainScreen].bounds.size;
40   if (base::ios::IsRunningOnIOS8OrLater()) {
41     return screenSize.height;
42   } else {
43     return IsPortrait() ? screenSize.height : screenSize.width;
44   }
47 CGFloat CurrentScreenWidth() {
48   CGSize screenSize = [UIScreen mainScreen].bounds.size;
49   if (base::ios::IsRunningOnIOS8OrLater()) {
50     return screenSize.width;
51   } else {
52     return IsPortrait() ? screenSize.width : screenSize.height;
53   }
56 CGFloat StatusBarHeight() {
57   // TODO(justincohen): This is likely not correct, but right now iOS7 betas are
58   // doing strange things when handling calls that change the status bar height.
59   // For now, just return 20. crbug/264367
60   return 20;
63 CGFloat AlignValueToPixel(CGFloat value) {
64   static CGFloat scale = [[UIScreen mainScreen] scale];
65   return floor(value * scale) / scale;
68 CGPoint AlignPointToPixel(CGPoint point) {
69   return CGPointMake(AlignValueToPixel(point.x), AlignValueToPixel(point.y));
72 CGRect AlignRectToPixel(CGRect rect) {
73   rect.origin = AlignPointToPixel(rect.origin);
74   return rect;
77 CGRect AlignRectOriginAndSizeToPixels(CGRect rect) {
78   rect.origin = AlignPointToPixel(rect.origin);
79   rect.size = ui::AlignSizeToUpperPixel(rect.size);
80   return rect;
83 CGRect CGRectCopyWithOrigin(CGRect rect, CGFloat x, CGFloat y) {
84   return CGRectMake(x, y, rect.size.width, rect.size.height);
87 CGRect CGRectMakeAlignedAndCenteredAt(CGFloat x, CGFloat y, CGFloat width) {
88   return AlignRectOriginAndSizeToPixels(
89       CGRectMake(x - width / 2.0, y - width / 2.0, width, width));
92 // Based on an original size and a target size applies the transformations.
93 void CalculateProjection(CGSize originalSize,
94                          CGSize desiredTargetSize,
95                          ProjectionMode projectionMode,
96                          CGSize& targetSize,
97                          CGRect& projectTo) {
98   targetSize = desiredTargetSize;
99   projectTo = CGRectZero;
100   if (originalSize.height < 1 || originalSize.width < 1)
101     return;
102   if (targetSize.height < 1 || targetSize.width < 1)
103     return;
105   CGFloat aspectRatio = originalSize.width / originalSize.height;
106   CGFloat targetAspectRatio = targetSize.width / targetSize.height;
107   switch (projectionMode) {
108     case ProjectionMode::kFill:
109       // Don't preserve the aspect ratio.
110       projectTo.size = targetSize;
111       break;
113     case ProjectionMode::kAspectFill:
114       if (targetAspectRatio < aspectRatio) {
115         // Clip the x-axis.
116         projectTo.size.width = targetSize.height * aspectRatio;
117         projectTo.size.height = targetSize.height;
118         projectTo.origin.x = (targetSize.width - projectTo.size.width) / 2;
119         projectTo.origin.y = 0;
120       } else {
121         // Clip the y-axis.
122         projectTo.size.width = targetSize.width;
123         projectTo.size.height = targetSize.width / aspectRatio;
124         projectTo.origin.x = 0;
125         projectTo.origin.y = (targetSize.height - projectTo.size.height) / 2;
126       }
127       break;
129     case ProjectionMode::kAspectFit:
130       if (targetAspectRatio < aspectRatio) {
131         projectTo.size.width = targetSize.width;
132         projectTo.size.height = projectTo.size.width / aspectRatio;
133         targetSize = projectTo.size;
134       } else {
135         projectTo.size.height = targetSize.height;
136         projectTo.size.width = projectTo.size.height * aspectRatio;
137         targetSize = projectTo.size;
138       }
139       break;
141     case ProjectionMode::kAspectFillNoClipping:
142       if (targetAspectRatio < aspectRatio) {
143         targetSize.width = targetSize.height * aspectRatio;
144         targetSize.height = targetSize.height;
145       } else {
146         targetSize.width = targetSize.width;
147         targetSize.height = targetSize.width / aspectRatio;
148       }
149       projectTo.size = targetSize;
150       break;
151   }
153   projectTo = CGRectIntegral(projectTo);
154   // There's no CGSizeIntegral, faking one instead.
155   CGRect integralRect = CGRectZero;
156   integralRect.size = targetSize;
157   targetSize = CGRectIntegral(integralRect).size;