1 // Copyright 2012 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 #ifndef IOS_CHROME_BROWSER_UI_UTIL_UIKIT_UI_UTIL_H_ 6 #define IOS_CHROME_BROWSER_UI_UTIL_UIKIT_UI_UTIL_H_ 7 8 #include <CoreGraphics/CoreGraphics.h> 9 #import <Foundation/Foundation.h> 10 #import <UIKit/UIKit.h> 11 12 #import "ios/chrome/browser/ui/util/ui_util.h" 13 14 // UI Util containing functions that require UIKit. 15 16 // Utility function to set the |element|'s accessibility label to the localized 17 // message corresponding to |idsAccessibilityLabel| and its accessibility 18 // identifier to |englishUiAutomationName|. 19 // Call SetA11yLabelAndUiAutomationName() if |element| is accessible and its 20 // a11y label should be localized. 21 // By convention |englishUiAutomationName| must be equal to the English 22 // localized string corresponding to |idsAccessibilityLabel|. 23 // |englishUiAutomationName| is the name used in JavaScript UI Automation test 24 // scripts to identify the |element|. 25 void SetA11yLabelAndUiAutomationName( 26 NSObject<UIAccessibilityIdentification>* element, 27 int idsAccessibilityLabel, 28 NSString* englishUiAutomationName); 29 30 // Sets dynamic font for the given |font| on iOS 11+ on the givel |label| or 31 // |textField|. Use |maybe| versions to keep code short when dynamic types are 32 // not in use yet. 33 void SetUILabelScaledFont(UILabel* label, UIFont* font); 34 void MaybeSetUILabelScaledFont(BOOL maybe, UILabel* label, UIFont* font); 35 void SetUITextFieldScaledFont(UITextField* textField, UIFont* font); 36 void MaybeSetUITextFieldScaledFont(BOOL maybe, 37 UITextField* textField, 38 UIFont* font); 39 40 enum CaptureViewOption { 41 kNoCaptureOption, // Equivalent to calling CaptureView without options. 42 kAfterScreenUpdate, // Require a synchronization with CA process which can 43 // have side effects. 44 kClientSideRendering, // Triggers a client side compositing, very slow. 45 }; 46 47 // Captures and returns an autoreleased rendering of the |view|. 48 // The |view| is assumed to be opaque and the returned image does 49 // not have an alpha channel. The scale parameter is used as a scale factor 50 // for the rendering context. Using 0.0 as scale will result in the device's 51 // main screen scale to be used. 52 // The CaptureViewWithOption function can be used with the |option| 53 // parameter set to kAfterScreenUpdate if some changes performed in the view 54 // and/or it's subtree that have not yet been part of a committed implicit 55 // transaction must be reflected in the snapshot. 56 // For example, it should be used if you just performed changes in the view or 57 // its subviews before calling that function and wants those changes to be 58 // reflected in the snapshot. 59 // Calling CaptureView without option gives the best performances. If you only 60 // need to hide subviews consider selectively rendering subviews in a bitmap 61 // context using drawViewHierarchyInRect:afterScreenUpdates:NO. 62 // The kClientSideRendering option can be used to directly re-render the view 63 // client side instead of reusing the core animation layer's backing store, this 64 // is slow. 65 // On iOS < 9 this function is slow and always behave as if the option was set 66 // to kClientSideRendering. 67 UIImage* CaptureViewWithOption(UIView* view, 68 CGFloat scale, 69 CaptureViewOption option); 70 UIImage* CaptureView(UIView* view, CGFloat scale); 71 72 // Converts input image and returns a grey scaled version. 73 UIImage* GreyImage(UIImage* image); 74 75 // Returns an UIColor with |rgb| and |alpha|. The caller should pass the RGB 76 // value in hexadecimal as this is the typical way they are provided by UX. 77 // For example a call to |UIColorFromRGB(0xFF7D40, 1.0)| returns an orange 78 // UIColor object. 79 inline UIColor* UIColorFromRGB(int rgb, CGFloat alpha = 1.0) { 80 return [UIColor colorWithRed:((CGFloat)((rgb & 0xFF0000) >> 16)) / 255.0 81 green:((CGFloat)((rgb & 0x00FF00) >> 8)) / 255.0 82 blue:((CGFloat)(rgb & 0x0000FF)) / 255.0 83 alpha:alpha]; 84 } 85 86 // Returns the image from the shared resource bundle with the image id 87 // |imageID|. If |reversable| is YES and RTL layout is in use, the image 88 // will be flipped for RTL. 89 UIImage* NativeReversableImage(int imageID, BOOL reversable); 90 91 // Convenience version of NativeReversableImage for images that are never 92 // reversable; equivalent to NativeReversableImage(imageID, NO). 93 UIImage* NativeImage(int imageID); 94 95 // Returns an image resized to |targetSize|. It first calculate the projection 96 // by calling CalculateProjection() and then create a new image of the desired 97 // size and project the correct subset of the original image onto it. 98 // The resulting image will have an alpha channel. 99 // 100 // Image interpolation level for resizing is set to kCGInterpolationDefault. 101 // 102 // The resize always preserves the scale of the original image. 103 UIImage* ResizeImage(UIImage* image, 104 CGSize targetSize, 105 ProjectionMode projectionMode); 106 107 // Returns an image resized to |targetSize|. It first calculate the projection 108 // by calling CalculateProjection() and then create a new image of the desired 109 // size and project the correct subset of the original image onto it. 110 // |opaque| determine whether resulting image should have an alpha channel. 111 // Prefer setting |opaque| to YES for better performances. 112 // 113 // Image interpolation level for resizing is set to kCGInterpolationDefault. 114 // 115 // The resize always preserves the scale of the original image. 116 UIImage* ResizeImage(UIImage* image, 117 CGSize targetSize, 118 ProjectionMode projectionMode, 119 BOOL opaque); 120 121 // Returns an output image where each pixel has RGB values equal to a color and 122 // the alpha value sampled from the given image. The RGB values of the image are 123 // ignored. If the color has alpha value of less than one, then the entire 124 // output image's alpha is scaled by the color's alpha value. 125 UIImage* TintImage(UIImage* image, UIColor* color); 126 127 // Returns the first responder in the subviews of |view|, or nil if no view in 128 // the subtree is the first responder. 129 UIView* GetFirstResponderSubview(UIView* view); 130 131 // Returns the interface orientation of the given window in the app. 132 UIInterfaceOrientation GetInterfaceOrientation(UIWindow* window); 133 134 // Returns the height of the keyboard in the current orientation. 135 CGFloat CurrentKeyboardHeight(NSValue* keyboardFrameValue); 136 137 // Create 1x1px image from |color|. 138 UIImage* ImageWithColor(UIColor* color); 139 140 // Returns a circular image of width |width| based on |image| scaled up or 141 // down. If the source image is not square, the image is first cropped. 142 UIImage* CircularImageFromImage(UIImage* image, CGFloat width); 143 144 // Returns true if the window is in portrait orientation or if orientation is 145 // unknown. 146 bool IsPortrait(UIWindow* window); 147 148 // Returns true if the window is in landscape orientation. 149 bool IsLandscape(UIWindow* window); 150 151 // Whether the |environment| has a compact horizontal size class. 152 bool IsCompactWidth(id<UITraitEnvironment> environment); 153 154 // Whether the |traitCollection| has a compact horizontal size class. 155 bool IsCompactWidth(UITraitCollection* traitCollection); 156 157 // Whether the |environment| has a compact vertical size class. 158 bool IsCompactHeight(id<UITraitEnvironment> environment); 159 160 // Whether the |traitCollection| has a compact vertical size class. 161 bool IsCompactHeight(UITraitCollection* traitCollection); 162 163 // Whether toolbar should be shown in compact mode in |environment|. 164 bool ShouldShowCompactToolbar(id<UITraitEnvironment> environment); 165 166 // Whether toolbar should be shown in compact mode in |traitCollection|. 167 bool ShouldShowCompactToolbar(UITraitCollection* traitCollection); 168 169 // Whether the |environment| has a regular vertical and regular horizontal 170 // size class. 171 bool IsRegularXRegularSizeClass(id<UITraitEnvironment> environment); 172 // Whether the |traitCollection| has a regular vertical and regular horizontal 173 // size class. 174 bool IsRegularXRegularSizeClass(UITraitCollection* traitCollection); 175 176 // Returns whether the |environment|'s toolbar is split between top and bottom 177 // toolbar or if it is displayed as only one toolbar. 178 bool IsSplitToolbarMode(id<UITraitEnvironment> environment); 179 180 // Returns whether the |traitCollection|'s toolbar is split between top and 181 // bottom toolbar or if it is displayed as only one toolbar. 182 bool IsSplitToolbarMode(UITraitCollection* traitCollection); 183 184 // Returns the current first responder for keyWindow. 185 UIResponder* GetFirstResponder(); 186 187 // Trigger a haptic vibration for various types of actions. This is a no-op for 188 // devices that do not support haptic feedback. 189 void TriggerHapticFeedbackForSelectionChange(); 190 // |impactStyle| should represent the mass of the object in the collision 191 // simulated by this feedback. 192 void TriggerHapticFeedbackForImpact(UIImpactFeedbackStyle impactStyle); 193 // |type| represent the type of notification associated with this feedback. 194 void TriggerHapticFeedbackForNotification(UINotificationFeedbackType type); 195 196 // Returns the text for tabs count to be displayed in toolbar and tab_grid. 197 // As an easter egg, show a smiley face instead of the count if the user has 198 // more than 99 tabs open. 199 NSString* TextForTabCount(long count); 200 201 // Adds |item| to the global Edit Menu configuration (UIMenuController). No-op 202 // if a UIMenuItem with the same selector as |item| has already been registered. 203 void RegisterEditMenuItem(UIMenuItem* item); 204 205 // Finds the root of |view|'s view hierarchy -- its window if it has one, or 206 // the first (recursive) superview with no superview. 207 UIView* ViewHierarchyRootForView(UIView* view); 208 209 #endif // IOS_CHROME_BROWSER_UI_UTIL_UIKIT_UI_UTIL_H_ 210