| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ios/chrome/browser/ui/ui_util.h" |
| |
| #import <UIKit/UIKit.h> |
| |
| #include "base/logging.h" |
| #import "ios/chrome/browser/ui/uikit_ui_util.h" |
| #include "ui/gfx/ios/uikit_util.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| bool IsIPadIdiom() { |
| UIUserInterfaceIdiom idiom = [[UIDevice currentDevice] userInterfaceIdiom]; |
| return idiom == UIUserInterfaceIdiomPad; |
| } |
| |
| const CGFloat kPortraitWidth[INTERFACE_IDIOM_COUNT] = { |
| 320, // IPHONE_IDIOM |
| 768 // IPAD_IDIOM |
| }; |
| |
| bool IsHighResScreen() { |
| return [[UIScreen mainScreen] scale] > 1.0; |
| } |
| |
| bool IsPortrait() { |
| UIInterfaceOrientation orient = GetInterfaceOrientation(); |
| // If building with an SDK prior to iOS 8 don't worry about |
| // UIInterfaceOrientationUnknown because it wasn't defined. |
| #if !defined(__IPHONE_8_0) || __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0 |
| return UIInterfaceOrientationIsPortrait(orient); |
| #else |
| return UIInterfaceOrientationIsPortrait(orient) || |
| orient == UIInterfaceOrientationUnknown; |
| #endif // SDK |
| } |
| |
| bool IsLandscape() { |
| return UIInterfaceOrientationIsLandscape(GetInterfaceOrientation()); |
| } |
| |
| CGFloat CurrentScreenHeight() { |
| return [UIScreen mainScreen].bounds.size.height; |
| } |
| |
| CGFloat CurrentScreenWidth() { |
| return [UIScreen mainScreen].bounds.size.width; |
| } |
| |
| CGFloat StatusBarHeight() { |
| // Checking [UIApplication sharedApplication].statusBarFrame will return the |
| // wrong offset when the application is started while in a phone call, so |
| // simply return 20 here. |
| return 20; |
| } |
| |
| CGFloat AlignValueToPixel(CGFloat value) { |
| static CGFloat scale = [[UIScreen mainScreen] scale]; |
| return floor(value * scale) / scale; |
| } |
| |
| CGPoint AlignPointToPixel(CGPoint point) { |
| return CGPointMake(AlignValueToPixel(point.x), AlignValueToPixel(point.y)); |
| } |
| |
| CGRect AlignRectToPixel(CGRect rect) { |
| rect.origin = AlignPointToPixel(rect.origin); |
| return rect; |
| } |
| |
| CGRect AlignRectOriginAndSizeToPixels(CGRect rect) { |
| rect.origin = AlignPointToPixel(rect.origin); |
| rect.size = ui::AlignSizeToUpperPixel(rect.size); |
| return rect; |
| } |
| |
| CGRect CGRectCopyWithOrigin(CGRect rect, CGFloat x, CGFloat y) { |
| return CGRectMake(x, y, rect.size.width, rect.size.height); |
| } |
| |
| CGRect CGRectMakeAlignedAndCenteredAt(CGFloat x, CGFloat y, CGFloat width) { |
| return AlignRectOriginAndSizeToPixels( |
| CGRectMake(x - width / 2.0, y - width / 2.0, width, width)); |
| } |
| |
| // Based on an original size and a target size applies the transformations. |
| void CalculateProjection(CGSize originalSize, |
| CGSize desiredTargetSize, |
| ProjectionMode projectionMode, |
| CGSize& targetSize, |
| CGRect& projectTo) { |
| targetSize = desiredTargetSize; |
| projectTo = CGRectZero; |
| if (originalSize.height < 1 || originalSize.width < 1) |
| return; |
| if (targetSize.height < 1 || targetSize.width < 1) |
| return; |
| |
| CGFloat aspectRatio = originalSize.width / originalSize.height; |
| CGFloat targetAspectRatio = targetSize.width / targetSize.height; |
| switch (projectionMode) { |
| case ProjectionMode::kFill: |
| // Don't preserve the aspect ratio. |
| projectTo.size = targetSize; |
| break; |
| |
| case ProjectionMode::kAspectFill: |
| if (targetAspectRatio < aspectRatio) { |
| // Clip the x-axis. |
| projectTo.size.width = targetSize.height * aspectRatio; |
| projectTo.size.height = targetSize.height; |
| projectTo.origin.x = (targetSize.width - projectTo.size.width) / 2; |
| projectTo.origin.y = 0; |
| } else { |
| // Clip the y-axis. |
| projectTo.size.width = targetSize.width; |
| projectTo.size.height = targetSize.width / aspectRatio; |
| projectTo.origin.x = 0; |
| projectTo.origin.y = (targetSize.height - projectTo.size.height) / 2; |
| } |
| break; |
| |
| case ProjectionMode::kAspectFit: |
| if (targetAspectRatio < aspectRatio) { |
| projectTo.size.width = targetSize.width; |
| projectTo.size.height = projectTo.size.width / aspectRatio; |
| targetSize = projectTo.size; |
| } else { |
| projectTo.size.height = targetSize.height; |
| projectTo.size.width = projectTo.size.height * aspectRatio; |
| targetSize = projectTo.size; |
| } |
| break; |
| |
| case ProjectionMode::kAspectFillNoClipping: |
| if (targetAspectRatio < aspectRatio) { |
| targetSize.width = targetSize.height * aspectRatio; |
| targetSize.height = targetSize.height; |
| } else { |
| targetSize.width = targetSize.width; |
| targetSize.height = targetSize.width / aspectRatio; |
| } |
| projectTo.size = targetSize; |
| break; |
| } |
| |
| projectTo = CGRectIntegral(projectTo); |
| // There's no CGSizeIntegral, faking one instead. |
| CGRect integralRect = CGRectZero; |
| integralRect.size = targetSize; |
| targetSize = CGRectIntegral(integralRect).size; |
| } |