From 8cdbcab935eef41197620a9ccbd1509f38e8557b Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Tue, 26 Apr 2016 12:15:11 -0700 Subject: [PATCH 01/31] Fix bug 7344396 - Shadow color can be in uninitailized state and causes app av (1601 app e.g.) --- Frameworks/CoreGraphics/CGContextCairo.mm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Frameworks/CoreGraphics/CGContextCairo.mm b/Frameworks/CoreGraphics/CGContextCairo.mm index da814ba3d7..55f04fed23 100644 --- a/Frameworks/CoreGraphics/CGContextCairo.mm +++ b/Frameworks/CoreGraphics/CGContextCairo.mm @@ -753,14 +753,20 @@ states[curStateNum].curBlendMode = curState->curBlendMode; states[curStateNum]._imgClip = NULL; states[curStateNum]._imgMask = NULL; + states[curStateNum].shadowColor = NULL; if (curState->_imgClip) { states[curStateNum]._imgClip = curState->_imgClip->Backing()->Copy(); } + if (curState->_imgMask) { states[curStateNum]._imgMask = curState->_imgMask->Backing()->Copy(); } + if (curState->shadowColor) { + states[curStateNum].shadowColor = CGColorCreateCopy(curState->shadowColor); + } + memcpy(&states[curStateNum].curTransform, &curState->curTransform, sizeof(curState->curTransform)); curState = &states[curStateNum]; @@ -777,9 +783,15 @@ if (curState->_imgClip) { delete curState->_imgClip; } + if (curState->_imgMask) { delete curState->_imgMask; } + + if (curState->shadowColor) { + CGColorRelease(curState->shadowColor); + } + curStateNum--; curState = &states[curStateNum]; From cee149c77d8a6e2989c76c108b73bb1033ed8d9a Mon Sep 17 00:00:00 2001 From: Nithish Mahalingam Date: Tue, 26 Apr 2016 11:27:32 -0700 Subject: [PATCH 02/31] Functional test script changes to work with WTT --- tests/Run-FunctionalTests.ps1 | 179 ++++++++++++++++++++++------------ 1 file changed, 118 insertions(+), 61 deletions(-) diff --git a/tests/Run-FunctionalTests.ps1 b/tests/Run-FunctionalTests.ps1 index 56f0da5ac1..4461dd689b 100644 --- a/tests/Run-FunctionalTests.ps1 +++ b/tests/Run-FunctionalTests.ps1 @@ -1,35 +1,83 @@ <# .SYNOPSIS Runs Functional Tests for Islandwood project. + +.PARAMETER TAEFDirectory + The path to TAEF binaries + +.PARAMETER TestDirectory + The path to test binaries + +.PARAMETER Platform + platform to run tests on. Valid values are Win32 or ARM + +.PARAMETER Config + Test configuration to use for the test. Valid values are Debug or Release + +.PARAMETER Device + IP or MAC address of the device to run tests on + +.PARAMETER TestFilter + Test filter to use for the test. Supports wildcard characters + +.PARAMETER WTLOutputDirectory + Path to test output. If not set, no result file will be saved. + +.PARAMETER NoCopy + Switch to disable copying test to the device + +.PARAMETER TestWorkingDirectory + Path to the working test directory from where the tests will be run + +.PARAMETER PackageRootPath + Path to build share where the TAEF package can be found + + +.EXAMPLE + Run-FunctionalTests.ps1 -TAEFDirectory D:\TAEF + Run-FunctionalTests.ps1 -TAEFDirectory \data\test\bin -Platform ARM + #> param( - [Parameter(HelpMessage="Directory of TAEF binaries")] [string]$TAEFDirectory = "", - - [Parameter(ParameterSetName="TestLocation", HelpMessage="Directory of Tests to run")] + [string]$TestDirectory = "", - [Parameter(HelpMessage="Architecture of tests to run")] [string][ValidateSet("Win32", "ARM")] $Platform = "Win32", - [Parameter(ParameterSetName="TestLocation", HelpMessage="Directory of Tests to run")] [string][ValidateSet("Debug", "Release")] $Config = "Debug", - [Parameter(HelpMessage="IP or MAC address of remote device to run tests on")] [string]$Device = "127.0.0.1", - [Parameter(HelpMessage="Regex of Tests to run")] [string]$TestFilter = $null, - [Parameter(HelpMessage="Location to place output wtl files. If not set, no result files will be saved.")] [string]$WTLOutputDirectory = $null, - - [Parameter(HelpMessage="TAEF package install path.")] + + [switch]$NoCopy, + + [string]$TestWorkingDirectory = "", + [string]$PackageRootPath = $null ) +if ($NoCopy) +{ + if ($TestWorkingDirectory -eq "") + { + throw "Please specify -TestWorkingDirectory argument with -NoCopy option." + } +} + +if ($TestWorkingDirectory -ne "") +{ + if (!$NoCopy) + { + throw "Please specify -NoCopy option when using -TestWorkingDirectory argument." + } +} + $TargetingDevice = ($Platform -eq "ARM") function EnsureDeviceConnection @@ -59,10 +107,10 @@ function DeployTests dird \data\test\bin\TE.TestMode.UAP.dll | Out-Null } Catch - { + { $TAEFPackageName = "Microsoft.Windows.Test.Taef" - - Write-Host -ForegroundColor Cyan "Installing $TAEFPackageName package - this may take a while... (about 5 minutes)" + + Write-Host -ForegroundColor Cyan "Installing $TAEFPackageName package - this may take about a minute" if ($TAEFDirectory -eq [string]$null) { deployd -Packages $TAEFPackageName -OnDevice @@ -73,22 +121,25 @@ function DeployTests } } - # Copy the tests to the device - Write-Host -ForegroundColor Cyan "Copying tests to the device - this may take about a minute" - - Try + if (!$NoCopy) { - mdd $TestDstDirectory - } - Catch - { - # putd fails if the directory doesn't already exist. - # mdd fails if the directory does already exist. - # This is awkward. + + # Copy the tests to the device + Write-Host -ForegroundColor Cyan "Copying tests to the device - this may take about a minute" + + Try + { + mdd $TestDstDirectory + } + Catch + { + # putd fails if the directory doesn't already exist. + # mdd fails if the directory does already exist. + # This is awkward. + } + + putd -recurse $TestSrcDirectory\* $TestDstDirectory } - - - putd -recurse $TestSrcDirectory\* $TestDstDirectory } else { @@ -99,7 +150,7 @@ function DeployTests function ExecTest($argList) { Write-Host -ForegroundColor Cyan "Starting test execution..." - + if ($TAEFDirectory -eq "") { $taefPath = "te.exe" @@ -108,17 +159,19 @@ function ExecTest($argList) { $taefPath = Join-Path $TAEFDirectory te.exe } - + $testPath = Join-Path $TestDstDirectory $DefaultTestBinary if ($TargetingDevice) { - Write-Host $argList cmdd $taefPath $testPath $argList - # Fetch the output from the device - getd $outputRemoteName $outputLocalName - deld $outputRemoteName + if ($WTLOutputDirectory -ne [string]$null) + { + # Fetch the output from the device + getd $outputRemoteName $outputLocalName + deld $outputRemoteName + } } else { @@ -127,23 +180,30 @@ function ExecTest($argList) } } -if ($TestDirectory -eq "") +if (!$NoCopy) { - $MyPath = (get-item $MyInvocation.MyCommand.Path).Directory.FullName; - $TestSrcDirectory = Join-Path $MyPath "..\build\Tests\FunctionalTests\$Platform\$Config\FunctionalTests" -} -else -{ - $TestSrcDirectory = $TestDirectory -} + if ($TestDirectory -eq "") + { + $MyPath = (get-item $MyInvocation.MyCommand.Path).Directory.FullName; + $TestSrcDirectory = Join-Path $MyPath "..\build\Tests\FunctionalTests\$Platform\$Config\FunctionalTests" + } + else + { + $TestSrcDirectory = $TestDirectory + } -if ($TargetingDevice) -{ - $TestDstDirectory = "\data\test\bin\islandwood\FunctionalTests" + if ($TargetingDevice) + { + $TestDstDirectory = "\data\test\bin\islandwood\FunctionalTests" + } + else + { + $TestDstDirectory = $TestSrcDirectory + } } else { - $TestDstDirectory = $TestSrcDirectory + $TestDstDirectory = $TestWorkingDirectory } if ($TargetingDevice) @@ -162,29 +222,26 @@ if (($WTLOutputDirectory -ne [string]$null) -and ((Test-Path -Path $WTLOutputDir $outputLocalName = $null; $outputRemoteName = $null; +$argList = ""; -$outputFileName = [System.IO.Path]::GetRandomFileName() + ".wtl" +$outputFileName = "FunctionalTestsResult.wtl" # Decide where the WTL output files will live -if ($WTLOutputDirectory -eq [string]$null) -{ - $outputLocalName = $outputFileName -} -else +if ($WTLOutputDirectory -ne [string]$null) { - $outputLocalName = Join-Path -Path $WTLOutputDirectory -ChildPath $outputFileName -} + if ($TargetingDevice) + { + $outputRemoteName = Join-Path -Path $TestDstDirectory -ChildPath $outputFileName + } + else + { + $outputLocalName = Join-Path -Path $WTLOutputDirectory -ChildPath $outputFileName + $outputRemoteName = $outputLocalName + } -if ($TargetingDevice) -{ - $outputRemoteName = Join-Path -Path $TestDstDirectory -ChildPath $outputFileName -} -else -{ - $outputRemoteName = $outputLocalName + $argList += " /logFile:$outputRemoteName /enableWttLogging" } -$argList = " /logFile:$outputRemoteName" if($TestFilter -ne [string]$null) { From 50fa8277acc979edec0d0278c44eabbd37466714 Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Wed, 20 Apr 2016 19:09:40 -0700 Subject: [PATCH 03/31] Implement UITextField using textBox and passwordBox --- Frameworks/QuartzCore/CATextLayer.mm | 4 + Frameworks/StarboardXaml/CALayerXaml.cpp | 17 +- Frameworks/StarboardXaml/CALayerXaml.h | 4 +- Frameworks/StarboardXaml/XamlCompositor.cpp | 7 +- Frameworks/UIKit/UITextField.mm | 1276 ++++++++++------- Frameworks/UIKit/XamlUtilities.h | 36 + Frameworks/UIKit/XamlUtilities.mm | 158 ++ build/UIKit/lib/UIKitLib.vcxproj | 7 +- include/UIKit/UITextField.h | 152 +- .../WOCCatalog/TextFieldsViewController.h | 4 +- .../WOCCatalog/TextFieldsViewController.m | 234 ++- .../WOCCatalog/XamlViewController.m | 1 + 12 files changed, 1178 insertions(+), 722 deletions(-) create mode 100644 Frameworks/UIKit/XamlUtilities.h create mode 100644 Frameworks/UIKit/XamlUtilities.mm diff --git a/Frameworks/QuartzCore/CATextLayer.mm b/Frameworks/QuartzCore/CATextLayer.mm index b26b865b65..68081deb2e 100644 --- a/Frameworks/QuartzCore/CATextLayer.mm +++ b/Frameworks/QuartzCore/CATextLayer.mm @@ -54,6 +54,10 @@ - (instancetype)init { if (self = [super init]) { __font = nil; _centerVertically = true; + + // CATextLayer is the CALayer for UILabel. By default, when text is centered vertical, + // it will take left alignment as well. Thus we should set contentGravity to left + self.contentsGravity = kCAGravityLeft; } return self; } diff --git a/Frameworks/StarboardXaml/CALayerXaml.cpp b/Frameworks/StarboardXaml/CALayerXaml.cpp index ec59c9bb96..8b0c321c23 100644 --- a/Frameworks/StarboardXaml/CALayerXaml.cpp +++ b/Frameworks/StarboardXaml/CALayerXaml.cpp @@ -388,7 +388,7 @@ void LayerContent::SetElementContent(FrameworkElement^ source) { } } -void LayerContent::SetImageParams(float width, float height, float scale) { +void LayerContent::SetContentParams(float width, float height, float scale) { Size oldSize = m_contentSize; float oldScale = scale; @@ -1365,7 +1365,7 @@ void CALayerXaml::_SetContent(FrameworkElement^ element) { } } -LayerContent^ CALayerXaml::_GetImageContent(bool create) { +LayerContent^ CALayerXaml::_GetLayerContent(bool create) { if (!Util::isInstanceOf(m_content)) { if (!create) { return nullptr; @@ -1387,7 +1387,7 @@ LayerContent^ CALayerXaml::_GetImageContent(bool create) { void CALayerXaml::SetContentGravity(ContentGravity gravity) { m_contentGravity = gravity; - auto layoutContent = _GetImageContent(); + auto layoutContent = _GetLayerContent(); if (layoutContent != nullptr) { layoutContent->SetGravity(gravity); } @@ -1395,7 +1395,7 @@ void CALayerXaml::SetContentGravity(ContentGravity gravity) { void CALayerXaml::SetContentsCenter(Rect rect) { m_contentsCenter = rect; - auto layoutContent = _GetImageContent(); + auto layoutContent = _GetLayerContent(); if (layoutContent != nullptr) { layoutContent->SetContentsCenter(m_contentsCenter); } @@ -1440,9 +1440,9 @@ void CALayerXaml::setContentImage(ImageSource^ source, float width, float height SetupBackground(); } } else { - LayerContent^ c = _GetImageContent(true); + LayerContent^ c = _GetLayerContent(true); c->SetImageContent(source, width, height); - c->SetImageParams(width, height, scale); + c->SetContentParams(width, height, scale); } } @@ -1453,10 +1453,9 @@ void CALayerXaml::setContentElement(FrameworkElement^ elem, float width, float h SetupBackground(); } } else { - LayerContent^ c = _GetImageContent(true); - c->SetGravity(ContentGravity::Left); + LayerContent^ c = _GetLayerContent(true); c->SetElementContent(elem); - c->SetImageParams(width, height, scale); + c->SetContentParams(width, height, scale); } } diff --git a/Frameworks/StarboardXaml/CALayerXaml.h b/Frameworks/StarboardXaml/CALayerXaml.h index 0ac05f3151..ff9ad815fd 100644 --- a/Frameworks/StarboardXaml/CALayerXaml.h +++ b/Frameworks/StarboardXaml/CALayerXaml.h @@ -88,7 +88,7 @@ ref class LayerContent sealed : Windows::UI::Xaml::Controls::Panel, ICacheableOb void SetContentsCenter(Windows::Foundation::Rect rect); void SetGravity(ContentGravity imgGravity); void SetImageContent(Windows::UI::Xaml::Media::ImageSource^ source, float width, float height); - void SetImageParams(float width, float height, float scale); + void SetContentParams(float width, float height, float scale); void SetElementContent(Windows::UI::Xaml::FrameworkElement^ source); protected: @@ -319,7 +319,7 @@ public ref class CALayerXaml sealed : Windows::UI::Xaml::Controls::Panel, ICache void _CALayerXaml_PointerCanceled(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e); void _CALayerXaml_PointerMoved(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ e); void _SetContent(Windows::UI::Xaml::FrameworkElement^ element); - LayerContent^ _GetImageContent(bool create = false); + LayerContent^ _GetLayerContent(bool create = false); }; /// diff --git a/Frameworks/StarboardXaml/XamlCompositor.cpp b/Frameworks/StarboardXaml/XamlCompositor.cpp index 8d8b0c8e79..5b6baa67b7 100644 --- a/Frameworks/StarboardXaml/XamlCompositor.cpp +++ b/Frameworks/StarboardXaml/XamlCompositor.cpp @@ -517,7 +517,6 @@ void DisplayNode::SetContents(winobjc::Id& bitmap, float width, float height, fl XamlCompositor::Controls::CALayerXaml ^ xamlNode = GetCALayer(this); if (((void*)bitmap) != NULL) { Windows::UI::Xaml::Media::ImageSource ^ contents = (Windows::UI::Xaml::Media::ImageSource ^ )(Platform::Object ^ )bitmap; - xamlNode->setContentImage(contents, width, height, scale); } else { xamlNode->setContentImage(nullptr, width, height, scale); @@ -531,12 +530,8 @@ void DisplayNode::SetContentsElement(winobjc::Id& elem, float width, float heigh } void DisplayNode::SetContentsElement(winobjc::Id& elem) { - XamlCompositor::Controls::CALayerXaml ^ xamlNode = GetCALayer(this); Windows::UI::Xaml::FrameworkElement ^ contents = (Windows::UI::Xaml::FrameworkElement ^ )(Platform::Object ^ )elem; - float width = static_cast(contents->Width); - float height = static_cast(contents->Height); - float scale = 1.0f; - xamlNode->setContentElement(contents, width, height, scale); + SetContentsElement(elem, static_cast(contents->Width), static_cast(contents->Height), 1.0f); } DisplayTextureXamlGlyphs::DisplayTextureXamlGlyphs() { diff --git a/Frameworks/UIKit/UITextField.mm b/Frameworks/UIKit/UITextField.mm index 81996f34c8..597cf25ebb 100644 --- a/Frameworks/UIKit/UITextField.mm +++ b/Frameworks/UIKit/UITextField.mm @@ -14,10 +14,13 @@ // //****************************************************************************** +#import "AssertARCEnabled.h" #import #import -#import "CoreGraphics/CGContext.h" + +#import #import "CGContextInternal.h" + #import #import #import @@ -30,8 +33,10 @@ #import #import #import "NSMutableString+Internal.h" -#import "UIResponderInternal.h" -#import "UIApplicationInternal.h" + +#import + +#import "XamlUtilities.h" static const wchar_t* TAG = L"UITextField"; @@ -39,47 +44,64 @@ NSString* const UITextFieldTextDidChangeNotification = @"UITextFieldTextDidChangeNotification"; NSString* const UITextFieldTextDidEndEditingNotification = @"UITextFieldTextDidEndEditingNotification"; -extern float keyboardBaseHeight; -static const float INPUTVIEW_DEFAULT_HEIGHT = 200.f; +// This is a hidden view control used to steal focus typically when a text field OSK (on screen keyboard) is dismissed. +@interface _UIHiddenButtonView : UIView +@end + +@implementation _UIHiddenButtonView +@end @implementation UITextField { - idretaintype(NSString) _text; - idretaintype(UIFont) _font; - idretain _placeholder; - idretain _background; - idretaintype(UIColor) __textColor; - idretaintype(UIColor) _tintColor; - idretain _undoManager; - idretaintype(UIImageView) _cursorBlink; - idretain _popoverController, _inputController; - NSTimer* _cursorTimer; - id _delegate; + StrongId _text; + StrongId _placeHolder; + StrongId _font; + StrongId _textColor; + StrongId _backgroundColor; UITextAlignment _alignment; - idretaintype(UIView) _leftView, _rightView, _inputView, _inputAccessoryView; UITextBorderStyle _borderStyle; - CGRect _leftViewRect; - bool _notifiedBegin; - UITextFieldViewMode _clearButtonMode; - BOOL _isEditing; BOOL _secureTextMode; - unsigned _returnKeyType; + BOOL _isFirstResponder; + // backing keyboard Behavior + UITextAutocapitalizationType _autoCapitalizatonType; UIKeyboardType _keyboardType; - int _showLastCharLen; - int _showLastCharBlinkCount; // Piggyback the disappearing password character on the cursor blink -} -- (void)setTextCentersHorizontally:(BOOL)center { + UITextAutocorrectionType _autoCorrectionType; + UITextSpellCheckingType _spellCheckingType; + BOOL _enablesReturnKeyAutomatically; + + // backing xaml textbox and passwordBox + WXCTextBox* _textBox; + WXCPasswordBox* _passwordBox; + + // lock use to access the properties + StrongId _secureModeLock; + + // dummy control to steal the focus + StrongId _dummyButton; + StrongId<_UIHiddenButtonView> _hiddenView; } +// +// Properties Accessing the Text Attributes +// /** @Status Interoperable */ - (void)setText:(NSString*)text { - if (text != nil) { - _text = [text copy]; - [self setNeedsDisplay]; - } else { - _text = nil; + if (![_text isEqualToString:text]) { + if (text != nil) { + _text = [text copy]; + } else { + _text = nil; + } + + [_secureModeLock lock]; + if (_secureTextMode) { + _passwordBox.password = _text; + } else { + _textBox.text = _text; + } + [_secureModeLock unlock]; } } @@ -91,553 +113,351 @@ - (NSString*)text { } /** - @Status Interoperable + @Status Stub */ -- (void)setFont:(UIFont*)font { - _font = font; +- (void)setAttributedText:(NSString*)attributedText { + UNIMPLEMENTED(); } /** - @Status Interoperable + @Status Stub */ -- (UIFont*)font { - return _font; +- (NSAttributedString*)attributedText { + UNIMPLEMENTED(); + return StubReturn(); } /** - @Status Caveat - @Notes May not be fully implemented + @Status Interoperable */ -- (instancetype)initWithCoder:(NSCoder*)coder { - [super initWithCoder:coder]; - _font = [coder decodeObjectForKey:@"UIFont"]; - _alignment = (UITextAlignment)[coder decodeInt32ForKey:@"UITextAlignment"]; - UITextBorderStyle borderStyle = (UITextBorderStyle)[coder decodeInt32ForKey:@"UIBorderStyle"]; - [self setBorderStyle:borderStyle]; - _keyboardType = (UIKeyboardType)[coder decodeInt32ForKey:@"UIKeyboardType"]; - _secureTextMode = [coder decodeInt32ForKey:@"UISecureTextEntry"]; - //[self setBackgroundColor:[UIColor whiteColor]]; - _text = [coder decodeObjectForKey:@"UIText"]; - __textColor = [coder decodeObjectForKey:@"UITextColor"]; - if (_text == nil) { - _text = @""; - } - if (__textColor == nil) { - __textColor = [UIColor blackColor]; +- (void)setPlaceholder:(NSString*)placeholder { + if (![_placeHolder isEqualToString:placeholder]) { + if (placeholder != nil) { + _placeHolder = [placeholder copy]; + } else { + _placeHolder = nil; + } + + [_secureModeLock lock]; + if (_secureTextMode) { + _passwordBox.placeholderText = _placeHolder; + } else { + _textBox.placeholderText = _placeHolder; + } + [_secureModeLock unlock]; } - _placeholder = [coder decodeObjectForKey:@"UIPlaceholder"]; - _undoManager.attach([NSUndoManager new]); - - id image = [[UIImage imageNamed:@"/img/TextFieldCursor@2x.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(4, 0, 4, 0)]; - _cursorBlink.attach([[UIImageView alloc] initWithImage:image]); - [_cursorBlink setHidden:TRUE]; - [self addSubview:_cursorBlink]; - [self setBackgroundColor:[UIColor clearColor]]; - return self; } /** @Status Interoperable */ -- (instancetype)initWithFrame:(CGRect)frame { - [super initWithFrame:frame]; - _font = [UIFont fontWithName:@"Helvetica" size:[UIFont labelFontSize]]; - __textColor = [UIColor blackColor]; - _text = @""; - [self setOpaque:FALSE]; - _undoManager.attach([NSUndoManager new]); - - id image = [[UIImage imageNamed:@"/img/TextFieldCursor@2x.png"] stretchableImageWithLeftCapWidth:0 topCapHeight:8]; - _cursorBlink.attach([[UIImageView alloc] initWithImage:image]); - [_cursorBlink setHidden:TRUE]; - [self addSubview:_cursorBlink]; - [self setBackgroundColor:[UIColor clearColor]]; - return self; +- (NSString*)placeholder { + return _placeHolder; } /** @Status Stub */ -- (void)setMinimumFontSize:(float)size { +- (void)setAttributedPlaceholder:(NSString*)atributedStr { UNIMPLEMENTED(); } /** - @Status Interoperable -*/ -- (void)setTextColor:(UIColor*)color { - __textColor = color; - [self setNeedsDisplay]; -} - -/** - @Status Interoperable + @Status Stub */ -- (void)setDelegate:(id)delegate { - _delegate = delegate; +- (NSAttributedString*)attributedPlaceholder { + UNIMPLEMENTED(); + return StubReturn(); } /** - @Status Interoperable + @Status Stub */ -- (id)delegate { - return _delegate; +- (void)setDefaultTextAttributes:(NSDictionary*)defaultAttributes { + UNIMPLEMENTED(); } /** - @Status Interoperable + @Status Stub */ -- (void)setEditingDelegate:(id)delegate { +- (NSDictionary*)defaultTextAttributes { UNIMPLEMENTED(); + return StubReturn(); } /** @Status Stub */ -- (void)setClearButtonMode:(UITextFieldViewMode)mode { +- (void)setFont:(UIFont*)font { + _font = font; UNIMPLEMENTED(); - _clearButtonMode = mode; + // TODO: need map UIFont with fontFamily/FontSize/FontWeight/FontStyle on target } /** - @Status Stub + @Status Interoperable */ -- (UITextFieldViewMode)clearButtonMode { - UNIMPLEMENTED(); - return _clearButtonMode; +- (UIFont*)font { + return _font; } /** @Status Interoperable */ -- (void)setTextAlignment:(UITextAlignment)alignment { +- (void)setTextColor:(UIColor*)color { + _textColor = color; + + [_secureModeLock lock]; + if (_secureTextMode) { + _passwordBox.foreground = [WUXMSolidColorBrush makeInstanceWithColor:[XamlUtilities convertUIColorToWUColor:_textColor]]; + } else { + _textBox.foreground = [WUXMSolidColorBrush makeInstanceWithColor:[XamlUtilities convertUIColorToWUColor:_textColor]]; + } + [_secureModeLock unlock]; } /** @Status Interoperable */ -- (void)setBorderStyle:(UITextBorderStyle)style { - _borderStyle = style; - [self setNeedsDisplay]; +- (UIColor*)textColor { + return _textColor; } /** @Status Interoperable */ -- (UITextBorderStyle)borderStyle { - return _borderStyle; +- (void)setBackgroundColor:(UIColor*)color { + _backgroundColor = color; + + [_secureModeLock lock]; + if (_secureTextMode) { + _passwordBox.background = [WUXMSolidColorBrush makeInstanceWithColor:[XamlUtilities convertUIColorToWUColor:_backgroundColor]]; + } else { + _textBox.background = [WUXMSolidColorBrush makeInstanceWithColor:[XamlUtilities convertUIColorToWUColor:_backgroundColor]]; + } + [_secureModeLock unlock]; } /** - @Status Stub + @Status Interoperable */ -- (void)setAutocapitalizationType:(UITextAutocapitalizationType)type { - UNIMPLEMENTED(); +- (UIColor*)backgroundColor { + return _backgroundColor; } /** @Status Interoperable */ -- (void)setKeyboardType:(UIKeyboardType)type { - _keyboardType = type; +- (void)setTextAlignment:(UITextAlignment)alignment { + _alignment = alignment; + + [_secureModeLock lock]; + if (!_secureTextMode) { + // passwordBox does not support text alignment + _textBox.textAlignment = [XamlUtilities convertUITextAlignmentToWXTextAlignment:_alignment]; + } + [_secureModeLock unlock]; } /** @Status Interoperable */ -- (UIKeyboardType)keyboardType { - return _keyboardType; +- (UITextAlignment)textAlignment { + return _alignment; } /** @Status Stub */ -- (void)setKeyboardAppearance:(UIKeyboardAppearance)appearance { +- (void)setTypingAttributes:(NSDictionary*)typingAttributes { UNIMPLEMENTED(); } -- (void)setReturnKeyType:(UIReturnKeyType)type { - _returnKeyType = type; -} - -- (UIReturnKeyType)returnKeyType { - return (UIReturnKeyType)_returnKeyType; +/** + @Status Stub +*/ +- (NSDictionary*)typingAttributes { + UNIMPLEMENTED(); + return StubReturn(); } +// +// Properties: Sizing the Text Field’s Text +// /** @Status Stub */ -- (void)setSpellCheckingType:(UITextSpellCheckingType)type { +- (void)setAdjustsFontSizeToFitWidth:(BOOL)adjust { UNIMPLEMENTED(); } /** - @Status Interoperable + @Status Stub */ -- (void)setPlaceholder:(NSString*)str { - _placeholder = [str copy]; +- (void)adjustsFontSizeToFitWidth:(BOOL)adjust { + UNIMPLEMENTED(); } /** - @Status Interoperable + @Status Stub */ -- (NSString*)placeholder { - return _placeholder; +- (void)setMinimumFontSize:(CGFloat)fontSize { + UNIMPLEMENTED(); } /** @Status Stub */ -- (void)setEnablesReturnKeyAutomatically:(BOOL)type { +- (CGFloat)minimumFontSize { UNIMPLEMENTED(); + return StubReturn(); } +// +// Managing the Editing Behavior +// /** @Status Stub */ -- (void)setClearsOnBeginEditing:(BOOL)type { +- (BOOL)isEditing { UNIMPLEMENTED(); + return StubReturn(); } /** @Status Stub */ -- (void)setAutocorrectionType:(UITextAutocorrectionType)type { +- (void)setClearsOnBeginEditing:(BOOL)value { UNIMPLEMENTED(); } /** - @Status Interoperable + @Status Stub */ -- (void)setSecureTextEntry:(BOOL)secure { - _secureTextMode = secure; +- (BOOL)clearOnBeginEditing { + UNIMPLEMENTED(); + return StubReturn(); } /** - @Status Interoperable + @Status Stub */ -- (void)setBackground:(UIImage*)image { - _background = image; - [self setNeedsDisplay]; +- (void)setclearsOnInsertion:(BOOL)value { + UNIMPLEMENTED(); } /** - @Status Interoperable + @Status Stub */ -- (UIImage*)background { - return _background; +- (BOOL)clearsOnInsertion { + UNIMPLEMENTED(); + return StubReturn(); } /** - @Status Interoperable + @Status Stub */ -- (void)drawRect:(CGRect)rect { - id text = _text; - id textColor = __textColor; - bool _isPlaceholder = false; - if (_text == nil || [_text length] == 0) { - text = _placeholder; - textColor = [UIColor lightGrayColor]; - _isPlaceholder = true; - } else { - if (_secureTextMode) { - WORD* chars = (WORD*)IwMalloc(([text length] + 1) * sizeof(WORD)); - [text getCharacters:chars]; - for (unsigned i = 0; i < [text length] - _showLastCharLen; i++) { - chars[i] = '*'; - } - text = [NSString stringWithCharacters:chars length:[text length]]; - IwFree(chars); - } - } - - if (_borderStyle != UITextBorderStyleNone) { - if ([[self layer] borderWidth] == 0.0f || _borderStyle == UITextBorderStyleRoundedRect) { - switch (_borderStyle) { - case UITextBorderStyleLine: { - // If a background image is set, it takes preference over all borderstyles and the background image is shown, except for - // UITextBorderStyleRoundedRect. - if (_background != nil) { - break; - } - - rect = [self bounds]; - rect.origin.x += 1.0f; - rect.origin.y += 1.0f; - rect.size.width -= 2.0f; - rect.size.height -= 2.0f; - - CGContextRef curContext = UIGraphicsGetCurrentContext(); - - if ([self isFirstResponder]) { - CGContextSetStrokeColorWithColor(curContext, - (CGColorRef)(_tintColor ? [_tintColor CGColor] : - [[UIColor windowsControlFocusedColor] CGColor])); - } else { - CGContextSetStrokeColorWithColor(curContext, (CGColorRef)[UIColor blackColor]); - } - CGContextStrokeRect(curContext, rect); - break; - } - - case UITextBorderStyleRoundedRect: { - rect = [self bounds]; - id image = - [[UIImage imageNamed:@"/img/TextFieldRounded@2x.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(16, 16, 16, 16)]; - rect = [self bounds]; - [image drawInRect:rect]; - break; - } - - case UITextBorderStyleBezel: { - // If a background image is set, it takes preference over all borderstyles and the background image is shown, except for - // UITextBorderStyleRoundedRect. - if (_background != nil) { - break; - } - - rect = [self bounds]; - id image = - [[UIImage imageNamed:@"/img/TextFieldBezel@2x.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(8, 8, 8, 8)]; - rect = [self bounds]; - [image drawInRect:rect]; - break; - } - - case UITextBorderStyleNone: - // Required to suppress warning. - // Execution never reaches here because of the outer if condition. - break; - - default: - TraceWarning(TAG, L"Invalid border style specified: %u", _borderStyle); - } - } - } - - // Out of the 4 border styles that ios supports now, UITextBorderStyleRoundedRect takes preference over background image, for all others - // borderstyles if there is a background image, it is shown and not the borderstyle. This is the default behaviour in ios. - if (_background != nil && _borderStyle != UITextBorderStyleRoundedRect) { - rect = [self bounds]; - [_background drawInRect:rect]; - } - - CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), (CGColorRef)textColor); - - CGSize size; - - rect = [self bounds]; - rect.origin.x += 5.0f; - rect.size.width -= 10.0f; - size = rect.size; - - if (text != nil) { - size = [text sizeWithFont:_font constrainedToSize:CGSizeMake(size.width, size.height) lineBreakMode:UILineBreakModeClip]; - } else { - size = [@"" sizeWithFont:_font constrainedToSize:CGSizeMake(size.width, size.height) lineBreakMode:UILineBreakModeClip]; - } - - rect.origin.x += _leftViewRect.size.width; - EbrCenterTextInRectVertically(&rect, &size, _font); - size = [text drawInRect:rect withFont:_font lineBreakMode:UILineBreakModeClip alignment:_alignment]; - - if (text == nil) { - size.width = 0; - } - switch (_alignment) { - case UITextAlignmentCenter: - rect.origin.x = rect.origin.x + rect.size.width / 2.0f - size.width / 2.0f; - break; - - case UITextAlignmentRight: - rect.origin.x = rect.origin.x + rect.size.width - size.width; - break; - } - - if (!_isPlaceholder) { - rect.origin.x += size.width; - } - rect.size.width = 2; - [_cursorBlink setFrame:rect]; +- (void)setAllowsEditingTextAttributes:(BOOL)value { + UNIMPLEMENTED(); } /** - @Status Interoperable + @Status Stub */ -- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { - if (_curState & UIControlStateDisabled) { - return; - } - - [self becomeFirstResponder]; +- (BOOL)allowsEditingTextAttributes { + UNIMPLEMENTED(); + return StubReturn(); } +// +// Setting the View' Background Appearance +// /** - @Status Interoperable + @Status Caveat + @Notes does not support UITextBorderStyleBezel */ -- (void)deleteBackward { - NSRange range; - bool proceed = false; - - _showLastCharLen = 0; - if (_text == nil) { - _text = [NSMutableString new]; - } - - id oldString = [_text copy]; - id newString = [NSMutableString new]; - [newString setString:_text]; - - id newChar = @""; - - range.location = [newString length]; - if (range.location > 0) { - range.length = 1; - range.location--; - [newString deleteCharactersInRange:range]; - proceed = true; - } - - if (proceed) { - bool setText = true; - if ([_delegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) { - setText = [_delegate textField:self shouldChangeCharactersInRange:range replacementString:newChar] != FALSE; - } +- (void)setBorderStyle:(UITextBorderStyle)style { + if (_borderStyle != style) { + _borderStyle = style; - if (setText) { - _text = newString; - [self sendActionsForControlEvents:UIControlEventEditingChanged]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"UITextFieldTextDidChangeNotification" object:self]; - [self setNeedsDisplay]; + [_secureModeLock lock]; + if (_secureTextMode) { + [XamlUtilities setControlBorderStyle:_passwordBox borderStyle:_borderStyle]; + } else { + [XamlUtilities setControlBorderStyle:_textBox borderStyle:_borderStyle]; } + [_secureModeLock unlock]; } } -- (void)_deleteRange:(NSNumber*)num { - int numToDelete = [num intValue]; - - for (int i = 0; i < numToDelete; i++) { - [self deleteBackward]; - } +/** + @Status Interoperable +*/ +- (UITextBorderStyle)borderStyle { + return _borderStyle; } -- (void)_keyPressed:(unsigned short)key { - _showLastCharLen = 0; - - if (key != 13) { - if (key == 8) { - [self deleteBackward]; - return; - } - - NSRange range; - - id newChar = [NSString stringWithCharacters:&key length:1]; - - if (_text == nil) { - _text = [NSMutableString new]; - } - - id oldString = [_text copy]; - id newString = [NSMutableString new]; - [newString setString:_text]; - - [newString appendString:newChar]; - - range.location = [newString length] - 1; - range.length = 1; - - bool setText = true; - if ([_delegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) { - setText = [_delegate textField:self shouldChangeCharactersInRange:range replacementString:newChar] != FALSE; - } - - if (setText) { - _text = newString; - [self sendActionsForControlEvents:UIControlEventEditingChanged]; - [self setNeedsDisplay]; - } - _showLastCharLen = 1; - _showLastCharBlinkCount = 3; - } else { - BOOL dismiss = TRUE; - - if ([_delegate respondsToSelector:@selector(textFieldShouldReturn:)]) { - dismiss = FALSE; - if ([_delegate textFieldShouldReturn:self]) { - dismiss = TRUE; - } - } - - if (dismiss) { - if ([_delegate respondsToSelector:@selector(textFieldDidEndEditing:)]) { - [_delegate textFieldDidEndEditing:self]; - } - [self sendActionsForControlEvents:UIControlEventEditingDidEndOnExit]; - [[NSNotificationCenter defaultCenter] postNotificationName:@"UITextFieldTextDidEndEditingNotification" object:self]; - - [self resignFirstResponder]; - } - } +/** + @Status Stub +*/ +- (void)setBackground:(UIImage*)image { + UNIMPLEMENTED(); } /** @Status Stub */ -- (void)setAdjustsFontSizeToFitWidth:(BOOL)adjust { +- (UIImage*)background { UNIMPLEMENTED(); + return StubReturn(); } /** - @Status Interoperable + @Status Stub */ -- (void)setLeftView:(UIView*)view { - _leftView = view; - [self setNeedsLayout]; - [self setNeedsDisplay]; +- (void)setDisabledBackground:(UIImage*)image { + UNIMPLEMENTED(); } /** @Status Stub */ -- (void)setInputAccessoryView:(UIView*)view { +- (UIImage*)disabledBackground { UNIMPLEMENTED(); - _inputAccessoryView = view; - [self setNeedsLayout]; + return StubReturn(); } +// +// Managing Overlay Views +// /** @Status Stub */ -- (UIView*)inputAccessoryView { +- (void)setClearButtonMode:(UITextFieldViewMode)mode { UNIMPLEMENTED(); - return _inputAccessoryView; } /** @Status Stub */ -- (void)setInputView:(UIView*)view { +- (UITextFieldViewMode)clearButtonMode { UNIMPLEMENTED(); - keyboardBaseHeight = INPUTVIEW_DEFAULT_HEIGHT; - _inputView = view; - [self setNeedsLayout]; - [[UIApplication sharedApplication] _keyboardChanged]; + return StubReturn(); } /** @Status Stub */ -- (UIView*)inputView { +- (void)setLeftView:(UIView*)view { UNIMPLEMENTED(); - return _inputView; } /** - @Status Interoperable + @Status Stub */ - (UIView*)leftView { - return _leftView; + UNIMPLEMENTED(); + return StubReturn(); } /** @@ -647,14 +467,19 @@ - (void)setLeftViewMode:(UITextFieldViewMode)mode { UNIMPLEMENTED(); } +/** + @Status Stub +*/ +- (UITextFieldViewMode)leftViewMode { + UNIMPLEMENTED(); + return StubReturn(); +} + /** @Status Stub */ - (void)setRightView:(UIView*)view { UNIMPLEMENTED(); - _rightView = view; - [self setNeedsLayout]; - [self setNeedsDisplay]; } /** @@ -662,7 +487,7 @@ - (void)setRightView:(UIView*)view { */ - (UIView*)rightView { UNIMPLEMENTED(); - return _rightView; + return StubReturn(); } /** @@ -673,272 +498,398 @@ - (void)setRightViewMode:(UITextFieldViewMode)mode { } /** - @Status Interoperable + @Status Stub */ -- (void)dealloc { - _text = nil; - _font = nil; - _placeholder = nil; - __textColor = nil; - _background = nil; - _undoManager = nil; - _cursorBlink = nil; - [_cursorTimer invalidate]; - _leftView = nil; - _rightView = nil; - _inputAccessoryView = nil; - _inputView = nil; - _inputController = nil; - _tintColor = nil; - [super dealloc]; +- (UITextFieldViewMode)rightViewMode { + UNIMPLEMENTED(); + return StubReturn(); } +// +// Drawing and positioning Overrides +// /** - @Status Interoperable + @Status Stub */ -- (void)layoutSubviews { - [self setNeedsDisplay]; - if (_leftView != nil) { - CGRect ourBounds; - ourBounds = [self bounds]; - - CGSize viewSize = { 0.0f, 0.0f }; - viewSize = [_leftView sizeThatFits:ourBounds.size]; - _leftViewRect.origin.x = 5.0f; - _leftViewRect.size = viewSize; - _leftViewRect.origin.y = ourBounds.size.height / 2.0f - _leftViewRect.size.height / 2.0f; - [_leftView setFrame:_leftViewRect]; - [self addSubview:_leftView]; - } +- (CGRect)textRectForBounds:(CGRect)bounds { + UNIMPLEMENTED(); + return StubReturn(); } -- (void)_blinkCursor { - if ([_cursorBlink isHidden]) { - [_cursorBlink setHidden:FALSE]; - } else { - [_cursorBlink setHidden:TRUE]; - } - if (_showLastCharBlinkCount > 0) { - _showLastCharBlinkCount--; - } else { - if (_showLastCharLen != 0) { - _showLastCharLen = 0; - [self setNeedsDisplay]; - } - } +/** + @Status Stub +*/ +- (void)drawTextInRect:(CGRect)rect { + UNIMPLEMENTED(); } /** - @Status Interoperable + @Status Stub */ -- (BOOL)becomeFirstResponder { - if (_curState & UIControlStateDisabled) { - return FALSE; - } - - if ([self isFirstResponder]) { - return TRUE; - } - - if ([super becomeFirstResponder] == FALSE) { - return FALSE; - } +- (CGRect)placeholderRectForBounds:(CGRect)bounds { + UNIMPLEMENTED(); + return StubReturn(); +} - if ([_delegate respondsToSelector:@selector(textFieldShouldBeginEditing:)]) { - if (![_delegate textFieldShouldBeginEditing:self]) { - return FALSE; - } - } +/** + @Status Stub +*/ +- (void)drawPlaceholderInRect:(CGRect)rect { + UNIMPLEMENTED(); +} - if (_inputView && [_inputView respondsToSelector:@selector(sendActionsForControlEvents:)]) { - [static_cast(_inputView) sendActionsForControlEvents:UIControlEventValueChanged]; - } +/** + @Status Stub +*/ +- (CGRect)borderRectForBounds:(CGRect)bounds { + UNIMPLEMENTED(); + return StubReturn(); +} - [[UIApplication sharedApplication] _keyboardChanged]; +/** + @Status Stub +*/ +- (CGRect)editingRectForBounds:(CGRect)bounds { + UNIMPLEMENTED(); + return StubReturn(); +} - _cursorTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(_blinkCursor) userInfo:0 repeats:TRUE]; - [_cursorBlink setHidden:FALSE]; +/** + @Status Stub +*/ +- (CGRect)clearButtonRectForBounds:(CGRect)bounds { + UNIMPLEMENTED(); + return StubReturn(); +} - _isEditing = TRUE; +/** + @Status Stub +*/ +- (CGRect)leftViewRectForBounds:(CGRect)bounds { + UNIMPLEMENTED(); + return StubReturn(); +} - [self sendActionsForControlEvents:UIControlEventEditingDidBegin]; - if ([_delegate respondsToSelector:@selector(textFieldDidBeginEditing:)]) { - [_delegate textFieldDidBeginEditing:self]; - } - [[NSNotificationCenter defaultCenter] postNotificationName:@"UITextFieldTextDidBeginEditingNotification" object:self]; - [self setNeedsDisplay]; +/** + @Status Stub +*/ +- (CGRect)rightViewRectForBounds:(CGRect)bounds { + UNIMPLEMENTED(); + return StubReturn(); +} - return TRUE; +// +// Replacing the System Input Views +// +/** + @Status Stub +*/ +- (void)setInputView:(UIView*)view { + UNIMPLEMENTED(); } /** - @Status Interoperable + @Status Stub */ -- (BOOL)resignFirstResponder { - if (![self isFirstResponder]) { - return TRUE; - } +- (UIView*)inputView { + UNIMPLEMENTED(); + return StubReturn(); +} - if (_isEditing) { - if ([_delegate respondsToSelector:@selector(textFieldShouldEndEditing:)]) { - if ([_delegate textFieldShouldEndEditing:self] == FALSE) { - return FALSE; - } - } - } - [_cursorTimer invalidate]; - _cursorTimer = nil; +/** + @Status Stub +*/ +- (void)setInputAccessoryView:(UIView*)view { + UNIMPLEMENTED(); +} - [_cursorBlink setHidden:TRUE]; +/** + @Status Stub +*/ +- (UIView*)inputAccessoryView { + UNIMPLEMENTED(); + return StubReturn(); +} - if (_isEditing) { - _showLastCharLen = 0; - [self setNeedsDisplay]; +// +// UITextInputTraits protocol defined properties, Managing the Keyboard Behavior +// +/** + @Status Stub +*/ +- (void)setAutocapitalizationType:(UITextAutocapitalizationType)type { + _autoCapitalizatonType = type; + UNIMPLEMENTED(); +} - _isEditing = FALSE; - [self sendActionsForControlEvents:UIControlEventEditingDidEnd]; - if ([_delegate respondsToSelector:@selector(textFieldDidEndEditing:)]) { - [_delegate textFieldDidEndEditing:self]; - } - [[NSNotificationCenter defaultCenter] postNotificationName:@"UITextFieldTextDidEndEditingNotification" object:self]; - } - [super resignFirstResponder]; +/** + @Status Stub +*/ +- (UITextAutocapitalizationType)autocapitalizationType { + UNIMPLEMENTED(); + return _autoCapitalizatonType; +} - [[UIApplication sharedApplication] _keyboardChanged]; +/** + @Status Interoperable +*/ +- (void)setAutocorrectionType:(UITextAutocorrectionType)type { + _autoCorrectionType = type; +} - return TRUE; +/** + @Status Interoperable +*/ +- (UITextAutocorrectionType)autocorrectionType { + return _autoCorrectionType; } /** @Status Interoperable */ -- (NSUndoManager*)undoManager { - return _undoManager; +- (void)setSpellCheckingType:(UITextSpellCheckingType)type { + _spellCheckingType = type; } /** @Status Interoperable */ -- (BOOL)isEditing { - return _isEditing; +- (UITextSpellCheckingType)spellCheckingType { + return _spellCheckingType; } /** @Status Interoperable */ -- (void)setTintColor:(UIColor*)color { - _tintColor = color; +- (void)setEnablesReturnKeyAutomatically:(BOOL)enabled { + _enablesReturnKeyAutomatically = enabled; } /** @Status Interoperable */ -- (UIColor*)tintColor { - return _tintColor; +- (BOOL)enablesReturnKeyAutomatically { + return _enablesReturnKeyAutomatically; +} + +/** + @Status Stub +*/ +- (void)setKeyboardAppearance:(UIKeyboardAppearance)appearance { + UNIMPLEMENTED(); +} + +/** + @Status Stub +*/ +- (UIKeyboardAppearance)keyboardAppearance { + UNIMPLEMENTED(); + return StubReturn(); } /** @Status Interoperable */ -- (CGSize)sizeThatFits:(CGSize)curSize { - CGSize ret = { 0, 0 }; +- (void)setKeyboardType:(UIKeyboardType)type { + _keyboardType = type; - if (_font == nil) { - [self setFont:[UIFont fontWithName:@"Helvetica" size:[UIFont labelFontSize]]]; + [_secureModeLock lock]; + if (_secureTextMode) { + _passwordBox.inputScope = [XamlUtilities convertKeyboardTypeToInputScope:_keyboardType secureTextMode:YES]; + } else { + _textBox.inputScope = [XamlUtilities convertKeyboardTypeToInputScope:_keyboardType secureTextMode:NO]; } + [_secureModeLock unlock]; +} - CGSize textSize = { 0 }, placeholderSize = { 0 }; - if (_text != nil) { - textSize = [_text sizeWithFont:_font constrainedToSize:CGSizeMake(curSize.width, curSize.height) lineBreakMode:UILineBreakModeClip]; - } - if (_placeholder != nil) { - placeholderSize = - [_placeholder sizeWithFont:_font constrainedToSize:CGSizeMake(curSize.width, curSize.height) lineBreakMode:UILineBreakModeClip]; +/** + @Status Interoperable +*/ +- (UIKeyboardType)keyboardType { + return _keyboardType; +} + +/** + @Status Stub. +*/ +- (void)setReturnKeyType:(UIReturnKeyType)type { + UNIMPLEMENTED(); +} + +/** + @Status Stub +*/ +- (UIReturnKeyType)returnKeyType { + UNIMPLEMENTED(); + return StubReturn(); +} + +/** + @Status Interoperable +*/ +- (void)setSecureTextEntry:(BOOL)secure { + [_secureModeLock lock]; + if (_secureTextMode != secure) { + _secureTextMode = secure; + if (_secureTextMode) { + [self _initPasswordBox]; + [self layer].contentsElement = _passwordBox; + } else { + [self _initTextBox]; + [self layer].contentsElement = _textBox; + } } + [_secureModeLock unlock]; +} - if (textSize.width > placeholderSize.width) { - ret = textSize; - } else { - ret = placeholderSize; +/** + @Status Interoperable +*/ +- (BOOL)isSecureTextEntry { + return _secureTextMode; +} + +/** + @Status Interoperable +*/ +- (instancetype)initWithCoder:(NSCoder*)coder { + if (self = [super initWithCoder:coder]) { + _font = [coder decodeObjectForKey:@"UIFont"]; + _alignment = (UITextAlignment)[coder decodeInt32ForKey:@"UITextAlignment"]; + _borderStyle = (UITextBorderStyle)[coder decodeInt32ForKey:@"UIBorderStyle"]; + _keyboardType = (UIKeyboardType)[coder decodeInt32ForKey:@"UIKeyboardType"]; + _secureTextMode = [coder decodeInt32ForKey:@"UISecureTextEntry"]; + _text = [coder decodeObjectForKey:@"UIText"]; + _placeHolder = [coder decodeObjectForKey:@"UIPlaceholder"]; + _textColor = [coder decodeObjectForKey:@"UITextColor"]; + if (_textColor == nil) { + _textColor = [UIColor blackColor]; + } + _backgroundColor = [UIColor lightGrayColor]; + _isFirstResponder = NO; + [self _initTextField]; } - if (ret.height == 0.0f) { - CGSize size; - size = [@" " sizeWithFont:_font constrainedToSize:CGSizeMake(curSize.width, curSize.height) lineBreakMode:UILineBreakModeClip]; - ret.height = size.height; + return self; +} + +/** + @Status Interoperable +*/ +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + _font = [UIFont fontWithName:@"Helvetica" size:[UIFont labelFontSize]]; + _textColor = [UIColor blackColor]; + _backgroundColor = [UIColor lightGrayColor]; + _alignment = UITextAlignmentLeft; + _secureTextMode = NO; + _borderStyle = UITextBorderStyleNone; + _spellCheckingType = UITextSpellCheckingTypeDefault; + _text = nil; + _isFirstResponder = NO; + [self _initTextField]; } - return ret; + return self; } /** @Status Stub */ -- (void)drawPlaceholderInRect:(CGRect)rect { +- (void)layoutSubviews { UNIMPLEMENTED(); } /** - @Status Stub + @Status Interoperable */ -- (void)drawTextInRect:(CGRect)rect { - UNIMPLEMENTED(); +- (void)setEnabled:(BOOL)enabled { + if (self.secureTextEntry) { + self->_textBox.isEnabled = enabled; + } else { + self->_passwordBox.isEnabled = enabled; + } } /** - @Status Stub + @Status Interoperable */ -- (CGRect)borderRectForBounds:(CGRect)bounds { - UNIMPLEMENTED(); - return StubReturn(); +- (BOOL)isEnabled { + if (self.secureTextEntry) { + return self->_passwordBox.isEnabled; + } else { + return self->_textBox.isEnabled; + } } +// +// UIControl defined properties override +// /** - @Status Stub + @Status Interoperable */ -- (CGRect)editingRectForBounds:(CGRect)bounds { - UNIMPLEMENTED(); - return StubReturn(); +- (BOOL)becomeFirstResponder { + if (_isFirstResponder) { + return YES; + } + + // Try to become first responder by setting focus + if (self.secureTextEntry) { + _isFirstResponder = [self->_passwordBox focus:WXFocusStateProgrammatic]; + } else { + _isFirstResponder = [self->_textBox focus:WXFocusStateProgrammatic]; + } + + return _isFirstResponder; } /** - @Status Stub + @Status Interoperable */ -- (CGRect)clearButtonRectForBounds:(CGRect)bounds { - UNIMPLEMENTED(); - return StubReturn(); +- (BOOL)isFirstResponder { + return _isFirstResponder; } /** - @Status Stub + @Status Interoperable */ -- (CGRect)leftViewRectForBounds:(CGRect)bounds { - UNIMPLEMENTED(); - return StubReturn(); +- (BOOL)resignFirstResponder { + if (![self isFirstResponder]) { + return YES; + } + + // Lost focus will take care of firstResponder status + [self _killFocus]; + return YES; } /** @Status Stub */ -- (CGRect)placeholderRectForBounds:(CGRect)bounds { +- (void)setTintColor:(UIColor*)color { UNIMPLEMENTED(); - return StubReturn(); } /** @Status Stub */ -- (CGRect)rightViewRectForBounds:(CGRect)bounds { +- (UIColor*)tintColor { UNIMPLEMENTED(); return StubReturn(); } +- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { + [self becomeFirstResponder]; +} + +// +// UIKeyInput Protocol related methods +// /** @Status Stub */ -- (CGRect)textRectForBounds:(CGRect)bounds { +- (void)deleteBackward { UNIMPLEMENTED(); - return StubReturn(); } /** @@ -988,4 +939,213 @@ - (CGRect)caretRectForPosition:(UITextPosition*)position { return StubReturn(); } +// Kill the focus on this UITextField +- (void)_killFocus { + [_dummyButton focus:WXFocusStateProgrammatic]; +} + +// Handler when control GotFocus +- (void)_setupControlGotFocusHandler:(WXCControl*)control { + __weak UITextField* weakSelf = self; + [control addGotFocusEvent:^void(RTObject* sender, WXRoutedEventArgs* e) { + __strong UITextField* strongSelf = weakSelf; + if (strongSelf) { + // when GotFocus, check delegate (if exits) to see if it allows start editing + if ([strongSelf.delegate respondsToSelector:@selector(textFieldShouldBeginEditing:)] && + ![strongSelf.delegate textFieldShouldBeginEditing:strongSelf]) { + // delegate says NO, but we already got the focus at this point, need to kill the focus on this control + [strongSelf _killFocus]; + return; + } + + // no one says NO, update first responder to YES + strongSelf->_isFirstResponder = YES; + + // more delegate update + if ([strongSelf.delegate respondsToSelector:@selector(textFieldDidBeginEditing:)]) { + [strongSelf.delegate textFieldDidBeginEditing:strongSelf]; + } + + // more notification + dispatch_async(dispatch_get_main_queue(), + ^{ + [strongSelf sendActionsForControlEvents:UIControlEventEditingDidBegin]; + [[NSNotificationCenter defaultCenter] postNotificationName:UITextFieldTextDidBeginEditingNotification + object:strongSelf]; + }); + } + }]; +} + +// Handler when control LostFocus +- (void)_setupControlLostFocusHandler:(WXCControl*)control { + __weak WXCControl* weakControl = control; + __weak UITextField* weakSelf = self; + [control addLostFocusEvent:^void(RTObject* sender, WXRoutedEventArgs* e) { + __strong UITextField* strongSelf = weakSelf; + if (strongSelf) { + // when LostFocus, check delegate (if exits) to see if it allows end Editing + if ([strongSelf.delegate respondsToSelector:@selector(textFieldShouldEndEditing:)] && + ![strongSelf.delegate textFieldShouldEndEditing:strongSelf]) { + // delegate does not allow edting to be ended, but we already lost the focus + // we need re-setting the focus back. it will trigger GotFocusEvent again on this control + // and then it will update the firstResponder status as YES + [weakControl focus:WXFocusStateProgrammatic]; + return; + } + + // no delegate say no, update firstResponder status to be NO + strongSelf->_isFirstResponder = NO; + + // more delegate update + if ([strongSelf.delegate respondsToSelector:@selector(textFieldDidEndEditing:)]) { + [strongSelf.delegate textFieldDidEndEditing:strongSelf]; + } + + // more notification + dispatch_async(dispatch_get_main_queue(), + ^{ + [strongSelf sendActionsForControlEvents:UIControlEventEditingDidEnd]; + [[NSNotificationCenter defaultCenter] postNotificationName:UITextFieldTextDidEndEditingNotification + object:strongSelf]; + }); + } + }]; +} + +// Handler when KeyDown +- (void)_setupControlKeyDownHandler:(WXCControl*)control { + __weak UITextField* weakSelf = self; + + // hooking up keydown event to process ENTER key + [control addKeyDownEvent:^void(RTObject* sender, WUXIKeyRoutedEventArgs* e) { + __strong UITextField* strongSelf = weakSelf; + if (strongSelf && e.key == WSVirtualKeyEnter) { + BOOL dismissKeyboard = TRUE; + + // check with delegate if should resign firstResponder and dismiss the keyboard + if ([strongSelf.delegate respondsToSelector:@selector(textFieldShouldReturn:)]) { + dismissKeyboard = [strongSelf.delegate textFieldShouldReturn:strongSelf]; + } + + if (dismissKeyboard) { + [strongSelf resignFirstResponder]; + } + e.handled = YES; + } else { + e.handled = NO; + } + }]; +} + +// Helper to Initialize textbox +- (void)_initTextBox { + self->_textBox = [WXCTextBox make]; + self->_passwordBox = nil; + __weak UITextField* weakSelf = self; + + // setting up textbox properties, e.g., foreground, textalignment, border, and input scope, text content etc... + [self->_textBox addLoadedEvent:^void(RTObject* sender, WXRoutedEventArgs* e) { + __strong UITextField* strongSelf = weakSelf; + if (strongSelf) { + strongSelf->_textBox.background = + [WUXMSolidColorBrush makeInstanceWithColor:[XamlUtilities convertUIColorToWUColor:strongSelf.backgroundColor]]; + strongSelf->_textBox.foreground = + [WUXMSolidColorBrush makeInstanceWithColor:[XamlUtilities convertUIColorToWUColor:strongSelf.textColor]]; + strongSelf->_textBox.textAlignment = [XamlUtilities convertUITextAlignmentToWXTextAlignment:strongSelf.textAlignment]; + [XamlUtilities setControlBorderStyle:strongSelf->_textBox borderStyle:strongSelf.borderStyle]; + strongSelf->_textBox.inputScope = [XamlUtilities convertKeyboardTypeToInputScope:strongSelf->_keyboardType secureTextMode:NO]; + strongSelf->_textBox.text = strongSelf.text; + strongSelf->_textBox.placeholderText = strongSelf.placeholder; + strongSelf->_textBox.isSpellCheckEnabled = (strongSelf.spellCheckingType == UITextSpellCheckingTypeYes); + } + }]; + + // set up text change event handler + [self->_textBox addTextChangedEvent:^void(RTObject* sender, WXRoutedEventArgs* e) { + __strong UITextField* strongSelf = weakSelf; + if (strongSelf) { + strongSelf.text = strongSelf->_textBox.text; + dispatch_async(dispatch_get_main_queue(), + ^{ + [strongSelf sendActionsForControlEvents:UIControlEventEditingChanged]; + [[NSNotificationCenter defaultCenter] postNotificationName:UITextFieldTextDidChangeNotification + object:strongSelf]; + }); + } + }]; + + // set up focus and keydown handlers + [self _setupControlGotFocusHandler:_textBox]; + [self _setupControlLostFocusHandler:_textBox]; + [self _setupControlKeyDownHandler:_textBox]; +} + +// Helper to Initialize passwordBox +- (void)_initPasswordBox { + self->_passwordBox = [WXCPasswordBox make]; + self->_textBox = nil; + + __weak UITextField* weakSelf = self; + + // setting up loadedEvent to update properties + [self->_passwordBox addLoadedEvent:^void(RTObject* sender, WXRoutedEventArgs* e) { + __strong UITextField* strongSelf = weakSelf; + if (strongSelf) { + strongSelf->_passwordBox.background = + [WUXMSolidColorBrush makeInstanceWithColor:[XamlUtilities convertUIColorToWUColor:strongSelf.backgroundColor]]; + strongSelf->_passwordBox.foreground = + [WUXMSolidColorBrush makeInstanceWithColor:[XamlUtilities convertUIColorToWUColor:strongSelf.textColor]]; + // passwordBox does not support textAlignment + + // border manipulate the control tempate and must be done after loaded + [XamlUtilities setControlBorderStyle:strongSelf->_passwordBox borderStyle:strongSelf.borderStyle]; + strongSelf->_passwordBox.inputScope = + [XamlUtilities convertKeyboardTypeToInputScope:strongSelf->_keyboardType secureTextMode:YES]; + strongSelf->_passwordBox.password = strongSelf.text; + strongSelf->_passwordBox.placeholderText = strongSelf.placeholder; + } + }]; + + // set up password change handler + [self->_passwordBox addPasswordChangedEvent:^void(RTObject* sender, WXRoutedEventArgs* e) { + __strong UITextField* strongSelf = weakSelf; + if (strongSelf) { + strongSelf.text = strongSelf->_passwordBox.password; + dispatch_async(dispatch_get_main_queue(), + ^{ + [strongSelf sendActionsForControlEvents:UIControlEventEditingChanged]; + }); + } + }]; + + // set up focus and keydown handlers + [self _setupControlGotFocusHandler:_passwordBox]; + [self _setupControlLostFocusHandler:_passwordBox]; + [self _setupControlKeyDownHandler:_passwordBox]; +} + +// main entrance to initialize TextField +- (void)_initTextField { + self->_secureModeLock = [NSRecursiveLock new]; + + // creating dummy button and hidden view so that it can be used to steal/kill the focus for this UITextField + self->_dummyButton = [WXCButton make]; + self->_dummyButton.visibility = WXVisibilityVisible; + self->_dummyButton.isEnabled = YES; + self->_dummyButton.isTabStop = YES; + + self->_hiddenView = [[_UIHiddenButtonView alloc] initWithFrame:{ 0, 0, 0, 0 }]; + [self->_hiddenView setNativeElement:self->_dummyButton]; + [self addSubview:self->_hiddenView]; + + if (self->_secureTextMode) { + [self _initPasswordBox]; + [self layer].contentsElement = self->_passwordBox; + } else { + [self _initTextBox]; + [self layer].contentsElement = self->_textBox; + } +} + @end diff --git a/Frameworks/UIKit/XamlUtilities.h b/Frameworks/UIKit/XamlUtilities.h new file mode 100644 index 0000000000..abb56ddefb --- /dev/null +++ b/Frameworks/UIKit/XamlUtilities.h @@ -0,0 +1,36 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#import +#import + +@interface XamlUtilities +// convert UIColor to Color on windows ++ (WUColor*)convertUIColorToWUColor:(UIColor*)uiColor; + +// convert UITextAlignment to TextAlignment on windows ++ (WXTextAlignment)convertUITextAlignmentToWXTextAlignment:(UITextAlignment)alignment; + +// convert ios KeyboardType to Windows InputScope ++ (WUXIInputScope*)convertKeyboardTypeToInputScope:(UIKeyboardType)keyboardType secureTextMode:(BOOL)secureTextMode; + +// Find the named template child in control tempate of a xaml control ++ (WXFrameworkElement*)findTemplateChild:(WXCControl*)control name:(NSString*)name; + +// set up border style for a control ++ (void)setControlBorderStyle:(WXCControl*)control borderStyle:(UITextBorderStyle)style; + +@end diff --git a/Frameworks/UIKit/XamlUtilities.mm b/Frameworks/UIKit/XamlUtilities.mm new file mode 100644 index 0000000000..5aa82e9d1e --- /dev/null +++ b/Frameworks/UIKit/XamlUtilities.mm @@ -0,0 +1,158 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#include +#include "XamlUtilities.h" + +// cornerRadius when border style is set to round rectangle +static const int c_borderCornerRadius = 8; + +@implementation XamlUtilities + ++ (WUColor*)convertUIColorToWUColor:(UIColor*)uiColor { + CGFloat r, g, b, a; + [uiColor getRed:&r green:&g blue:&b alpha:&a]; + return + [WUColorHelper fromArgb:(unsigned char)(a * 255) r:(unsigned char)(r * 255) g:(unsigned char)(g * 255) b:(unsigned char)(b * 255)]; +} + ++ (WXTextAlignment)convertUITextAlignmentToWXTextAlignment:(UITextAlignment)alignment { + WXTextAlignment ret = UITextAlignmentLeft; + switch (alignment) { + case UITextAlignmentLeft: + ret = WXTextAlignmentLeft; + break; + case UITextAlignmentCenter: + ret = WXTextAlignmentCenter; + break; + case UITextAlignmentRight: + ret = WXTextAlignmentRight; + break; + } + + return ret; +} + ++ (WUXIInputScope*)convertKeyboardTypeToInputScope:(UIKeyboardType)keyboardType secureTextMode:(BOOL)secureTextMode { + WUXIInputScopeName* inputScopeName = [WUXIInputScopeName make]; + inputScopeName.nameValue = WUXIInputScopeNameValueDefault; + + if (secureTextMode) { + // passwordBox only supports NumbericPin and Password inputscope + if (keyboardType == UIKeyboardTypeNumberPad) { + inputScopeName.nameValue = WUXIInputScopeNameValueNumericPin; + } else { + inputScopeName.nameValue = WUXIInputScopeNameValuePassword; + } + } else { + // normal textmode supports a lot more keyboardType + switch (keyboardType) { + case UIKeyboardTypeDefault: + inputScopeName.nameValue = WUXIInputScopeNameValueDefault; + break; + + case UIKeyboardTypeASCIICapable: + inputScopeName.nameValue = WUXIInputScopeNameValueDefault; + break; + + case UIKeyboardTypeNumbersAndPunctuation: + inputScopeName.nameValue = WUXIInputScopeNameValueDigits; + break; + + case UIKeyboardTypeURL: + inputScopeName.nameValue = WUXIInputScopeNameValueUrl; + break; + + case UIKeyboardTypeNumberPad: + inputScopeName.nameValue = WUXIInputScopeNameValueDigits; + break; + + case UIKeyboardTypePhonePad: + inputScopeName.nameValue = WUXIInputScopeNameValueTelephoneNumber; + break; + + case UIKeyboardTypeNamePhonePad: + inputScopeName.nameValue = WUXIInputScopeNameValueNameOrPhoneNumber; + break; + + case UIKeyboardTypeEmailAddress: + inputScopeName.nameValue = WUXIInputScopeNameValueEmailNameOrAddress; + break; + + case UIKeyboardTypeDecimalPad: + inputScopeName.nameValue = WUXIInputScopeNameValueNumber; + break; + + case UIKeyboardTypeTwitter: + inputScopeName.nameValue = WUXIInputScopeNameValueDefault; + break; + + case UIKeyboardTypeWebSearch: + inputScopeName.nameValue = WUXIInputScopeNameValueSearch; + break; + } + } + + WUXIInputScope* inputScope = [WUXIInputScope make]; + [inputScope.names addObject:inputScopeName]; + + return inputScope; +} + ++ (WXFrameworkElement*)findTemplateChild:(WXCControl*)control name:(NSString*)name { + WXFrameworkElement* target = nullptr; + unsigned int count = [WUXMVisualTreeHelper getChildrenCount:control]; + if (count > 0) { + WXFrameworkElement* templateRoot = rt_dynamic_cast([WUXMVisualTreeHelper getChild:control childIndex:0]); + if (templateRoot != nullptr) { + target = rt_dynamic_cast([templateRoot findName:name]); + } + } + + return target; +} + +// Setup control border style ++ (void)setControlBorderStyle:(WXCControl*)control borderStyle:(UITextBorderStyle)style { + switch (style) { + case UITextBorderStyleNone: + control.borderThickness = [WXThicknessHelper fromUniformLength:0]; + break; + + case UITextBorderStyleLine: + control.borderThickness = [WXThicknessHelper fromUniformLength:1]; + break; + + case UITextBorderStyleBezel: + UNIMPLEMENTED(); + // we don't support UITextBorderStyleBezel, treat it as no border + control.borderThickness = [WXThicknessHelper fromUniformLength:0]; + break; + + case UITextBorderStyleRoundedRect: + [control applyTemplate]; + WXFrameworkElement* elem = [XamlUtilities findTemplateChild:control name:@"BorderElement"]; + + // if the control template has not been loaded yet, it can return nullptr for borderElement + if (elem != nullptr) { + WXCBorder* border = rt_dynamic_cast(elem); + border.cornerRadius = [WXCornerRadiusHelper fromUniformRadius:c_borderCornerRadius]; + } + break; + } +} + +@end diff --git a/build/UIKit/lib/UIKitLib.vcxproj b/build/UIKit/lib/UIKitLib.vcxproj index 0d7793f8be..faf1ae5043 100644 --- a/build/UIKit/lib/UIKitLib.vcxproj +++ b/build/UIKit/lib/UIKitLib.vcxproj @@ -99,7 +99,12 @@ - + + true + + + true + diff --git a/include/UIKit/UITextField.h b/include/UIKit/UITextField.h index ad8cdae056..0a04c4a0af 100644 --- a/include/UIKit/UITextField.h +++ b/include/UIKit/UITextField.h @@ -1,32 +1,31 @@ /* - * Copyright (c) 2011, The Iconfactory. All rights reserved. - * Copyright (c) 2016 Microsoft Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of The Iconfactory nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE ICONFACTORY BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +* Copyright (c) 2016 Microsoft Corporation. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3. Neither the name of The Iconfactory nor the names of its contributors may +* be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE ICONFACTORY BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #pragma once @@ -40,19 +39,19 @@ UIKIT_EXPORT NSString* const UITextFieldTextDidBeginEditingNotification; UIKIT_EXPORT NSString* const UITextFieldTextDidChangeNotification; UIKIT_EXPORT NSString* const UITextFieldTextDidEndEditingNotification; -typedef enum { - UITextBorderStyleNone, - UITextBorderStyleLine, - UITextBorderStyleBezel, - UITextBorderStyleRoundedRect, -} UITextBorderStyle; +typedef NS_ENUM(NSInteger, UITextBorderStyle) { + UITextBorderStyleNone = 0, + UITextBorderStyleLine = 1, + UITextBorderStyleBezel = 2, + UITextBorderStyleRoundedRect = 3, +}; -typedef enum { +typedef NS_ENUM(NSInteger, UITextFieldViewMode) { UITextFieldViewModeNever, UITextFieldViewModeWhileEditing, UITextFieldViewModeUnlessEditing, UITextFieldViewModeAlways -} UITextFieldViewMode; +}; @class UIFont, UIColor, UIImage; @@ -65,56 +64,71 @@ UIKIT_EXPORT_CLASS UIFocusEnvironment, UITextInput, UITraitEnvironment> -- (CGRect)borderRectForBounds:(CGRect)bounds; -- (CGRect)clearButtonRectForBounds:(CGRect)bounds; -- (CGRect)editingRectForBounds:(CGRect)bounds; -- (CGRect)leftViewRectForBounds:(CGRect)bounds; -- (CGRect)placeholderRectForBounds:(CGRect)bounds; -- (CGRect)rightViewRectForBounds:(CGRect)bounds; -- (CGRect)textRectForBounds:(CGRect)bounds; - -- (void)drawPlaceholderInRect:(CGRect)rect; -- (void)drawTextInRect:(CGRect)rect; - -@property (nonatomic, assign) id delegate; -@property (nonatomic, assign) UITextAlignment textAlignment; -@property (nonatomic, copy) NSString* placeholder; -@property (nonatomic, copy) NSAttributedString* attributedPlaceholder; + +// Accessing the Text Attributes @property (nonatomic, copy) NSString* text; -@property (nonatomic, copy) NSAttributedString* attributedText; -@property (copy, nonatomic) NSDictionary* defaultTextAttributes STUB_PROPERTY; -@property (nonatomic, retain) UIFont* font; -@property (copy, nonatomic) NSDictionary* typingAttributes STUB_PROPERTY; -@property (nonatomic) UITextBorderStyle borderStyle; -@property (nonatomic, retain) UIColor* textColor; -@property (nonatomic, readonly, getter=isEditing) BOOL editing; +@property (nonatomic, copy) NSAttributedString* attributedText STUB_PROPERTY; +@property (nonatomic, copy) NSString* placeholder; +@property (nonatomic, copy) NSAttributedString* attributedPlaceholder STUB_PROPERTY; +@property (nonatomic, copy) NSDictionary* defaultTextAttributes STUB_PROPERTY; +@property (nonatomic, strong) UIFont* font STUB_PROPERTY; +@property (nonatomic, strong) UIColor* textColor; +@property (nonatomic) NSTextAlignment textAlignment; +@property (nonatomic, copy) NSDictionary* typingAttributes STUB_PROPERTY; + +// Sizing the Text Field’s Text +@property (nonatomic) BOOL adjustsFontSizeToFitWidth STUB_PROPERTY; +@property (nonatomic) CGFloat minimumFontSize STUB_PROPERTY; + +// Managing the Editing Behavior +@property (nonatomic, readonly, getter=isEditing) BOOL editing STUB_PROPERTY; @property (nonatomic) BOOL clearsOnBeginEditing STUB_PROPERTY; @property (nonatomic) BOOL clearsOnInsertion STUB_PROPERTY; -@property (nonatomic) BOOL adjustsFontSizeToFitWidth STUB_PROPERTY; @property (nonatomic) BOOL allowsEditingTextAttributes STUB_PROPERTY; -@property (nonatomic) CGFloat minimumFontSize STUB_PROPERTY; -@property (nonatomic, retain) UIImage* background; -@property (nonatomic, retain) UIImage* disabledBackground; +// Setting the View’s Background Appearance +@property (nonatomic) UITextBorderStyle borderStyle; +@property (nonatomic, strong) UIImage* background STUB_PROPERTY; +@property (nonatomic, strong) UIImage* disabledBackground STUB_PROPERTY; +// Managing Overlay Views @property (nonatomic) UITextFieldViewMode clearButtonMode STUB_PROPERTY; -@property (nonatomic, retain) UIView* leftView STUB_PROPERTY; +@property (nonatomic, strong) UIView* leftView STUB_PROPERTY; @property (nonatomic) UITextFieldViewMode leftViewMode STUB_PROPERTY; -@property (nonatomic, retain) UIView* rightView STUB_PROPERTY; +@property (nonatomic, strong) UIView* rightView STUB_PROPERTY; @property (nonatomic) UITextFieldViewMode rightViewMode STUB_PROPERTY; -@property (nonatomic, readwrite, retain) UIView* inputAccessoryView STUB_PROPERTY; -@property (nonatomic, readwrite, retain) UIView* inputView STUB_PROPERTY; +// Accessing the Delegate +@property (nonatomic, weak) id delegate; + +// Drawing and positioning Overrides +- (CGRect)textRectForBounds:(CGRect)bounds STUB_METHOD; +- (void)drawTextInRect:(CGRect)rect STUB_METHOD; +- (CGRect)placeholderRectForBounds:(CGRect)bounds STUB_METHOD; +- (void)drawPlaceholderInRect:(CGRect)rect STUB_METHOD; +- (CGRect)borderRectForBounds:(CGRect)bounds STUB_METHOD; +- (CGRect)editingRectForBounds:(CGRect)bounds STUB_METHOD; +- (CGRect)clearButtonRectForBounds:(CGRect)bounds STUB_METHOD; +- (CGRect)leftViewRectForBounds:(CGRect)bounds STUB_METHOD; +- (CGRect)rightViewRectForBounds:(CGRect)bounds STUB_METHOD; + +// Replacing the System Input Views +@property (readwrite, strong) UIView* inputView STUB_PROPERTY; +@property (readwrite, strong) UIView* inputAccessoryView STUB_PROPERTY; +// UITextInputTraits protocol defined properties, Managing the Keyboard Behavior @property (nonatomic) UITextAutocapitalizationType autocapitalizationType STUB_PROPERTY; @property (nonatomic) UITextAutocorrectionType autocorrectionType STUB_PROPERTY; +@property (nonatomic) UITextSpellCheckingType spellCheckingType; @property (nonatomic) BOOL enablesReturnKeyAutomatically STUB_PROPERTY; @property (nonatomic) UIKeyboardAppearance keyboardAppearance STUB_PROPERTY; -@property (nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry STUB_PROPERTY; -@property (nonatomic) UITextSpellCheckingType spellCheckingType STUB_PROPERTY; +@property (nonatomic) UIKeyboardType keyboardType; +@property (nonatomic) UIReturnKeyType returnKeyType STUB_PROPERTY; +@property (nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry; +// UITextInput protocol properties @property (nonatomic, readonly) UITextPosition* beginningOfDocument STUB_PROPERTY; @property (nonatomic, readonly) UITextPosition* endOfDocument STUB_PROPERTY; @property (readwrite, copy) UITextRange* selectedTextRange STUB_PROPERTY; -@end +@end \ No newline at end of file diff --git a/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.h b/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.h index 099b9f1e93..c9f9d3ad28 100644 --- a/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.h +++ b/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.h @@ -16,8 +16,6 @@ #import -@interface TextFieldsViewController : UITableViewController +@interface TextFieldsViewController : UITableViewController @end - - diff --git a/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.m b/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.m index c10c55ab0b..4bfd52d59b 100644 --- a/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.m +++ b/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.m @@ -21,20 +21,176 @@ static const CGFloat c_width = 260; static const CGFloat c_height = 40; -@implementation TextFieldsViewController +@implementation TextFieldsViewController { + NSMutableArray* _textFields; +} + +- (UITextField*)_createTextFieldWithColor:(UIColor*)color + background:(UIColor*)background + secureTextEntry:(BOOL)secureTextEntry + placeHolder:(NSString*)placeHolder + keyboardType:(UIKeyboardType)keyboardType + borderStyle:(UITextBorderStyle)borderStyle + textAlignment:(UITextAlignment)textAlignment + spellCheckingType:(UITextSpellCheckingType)spellCheckingType { + CGRect frame = CGRectMake(c_originX, c_originY, c_width, c_height); + UITextField* textField = [[UITextField alloc] initWithFrame:frame]; + textField.textColor = color; + textField.backgroundColor = background; + textField.secureTextEntry = secureTextEntry; + textField.font = [UIFont systemFontOfSize:17.0]; + textField.placeholder = placeHolder; + textField.keyboardType = keyboardType; + textField.borderStyle = borderStyle; + textField.textAlignment = textAlignment; + textField.spellCheckingType = spellCheckingType; + textField.delegate = self; + + return textField; +} - (void)viewDidLoad { [super viewDidLoad]; + // creating the text Fields + _textFields = [[NSMutableArray alloc] init]; + + // Row 0. password with number keyboard with Round border + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor lightGrayColor] + secureTextEntry:YES + placeHolder:@"password" + keyboardType:UIKeyboardTypeNumberPad + borderStyle:UITextBorderStyleRoundedRect + textAlignment:UITextAlignmentLeft + spellCheckingType:UITextSpellCheckingTypeNo]]; + + // Row 1. Normal text with right aligned and blue ground + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor blueColor] + secureTextEntry:NO + placeHolder:@"blue background, right aligned" + keyboardType:UIKeyboardTypeASCIICapable + borderStyle:UITextBorderStyleRoundedRect + textAlignment:UITextAlignmentRight + spellCheckingType:UITextSpellCheckingTypeNo]]; + + // Row 2. center aligned, red text, line border and spell check enabled + [_textFields addObject:[self _createTextFieldWithColor:[UIColor redColor] + background:[UIColor lightGrayColor] + secureTextEntry:NO + placeHolder:@"red text, alignment center" + keyboardType:UIKeyboardTypeDefault + borderStyle:UITextBorderStyleLine + textAlignment:UITextAlignmentCenter + spellCheckingType:UITextSpellCheckingTypeYes]]; + + // Row 3. UITextField rejects focus + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor lightGrayColor] + secureTextEntry:NO + placeHolder:@"This control reject focus" + keyboardType:UIKeyboardTypeDefault + borderStyle:UITextBorderStyleLine + textAlignment:UITextAlignmentCenter + spellCheckingType:UITextSpellCheckingTypeNo]]; + + // Row 4. URL keyboard and no border + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor lightGrayColor] + secureTextEntry:NO + placeHolder:@"type in URL" + keyboardType:UIKeyboardTypeURL + borderStyle:UITextBorderStyleNone + textAlignment:UITextAlignmentLeft + spellCheckingType:UITextSpellCheckingTypeNo]]; + + // Row 5. Name and Phone and using "UITextBorderStyleBezel" style border which is + // treated as line + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor lightGrayColor] + secureTextEntry:NO + placeHolder:@"type in your Name and Phone" + keyboardType:UIKeyboardTypeNamePhonePad + borderStyle:UITextBorderStyleNone + textAlignment:UITextBorderStyleBezel + spellCheckingType:UITextSpellCheckingTypeNo]]; + + // Row 6. Email address + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor lightGrayColor] + secureTextEntry:NO + placeHolder:@"type in your email address" + keyboardType:UIKeyboardTypeEmailAddress + borderStyle:UITextBorderStyleNone + textAlignment:UITextBorderStyleLine + spellCheckingType:UITextSpellCheckingTypeNo]]; + + // Row 7. Decimal + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor lightGrayColor] + secureTextEntry:NO + placeHolder:@"Decimal" + keyboardType:UIKeyboardTypeDecimalPad + borderStyle:UITextBorderStyleNone + textAlignment:UITextBorderStyleLine + spellCheckingType:UITextSpellCheckingTypeNo]]; + + // Row 8. Name or Phone number + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor lightGrayColor] + secureTextEntry:NO + placeHolder:@"type in name or Phone Number" + keyboardType:UIKeyboardTypeNamePhonePad + borderStyle:UITextBorderStyleNone + textAlignment:UITextBorderStyleLine + spellCheckingType:UITextSpellCheckingTypeNo]]; + + // Row 9. Decimal + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor lightGrayColor] + secureTextEntry:NO + placeHolder:@"Phone Number" + keyboardType:UIKeyboardTypePhonePad + borderStyle:UITextBorderStyleNone + textAlignment:UITextBorderStyleLine + spellCheckingType:UITextSpellCheckingTypeNo]]; + + // Row 10. Enter to dismiss keyboard + [_textFields addObject:[self _createTextFieldWithColor:[UIColor blackColor] + background:[UIColor lightGrayColor] + secureTextEntry:NO + placeHolder:@"Press enter to dismiss keyboard" + keyboardType:UIKeyboardTypeNamePhonePad + borderStyle:UIKeyboardTypePhonePad + textAlignment:UITextBorderStyleLine + spellCheckingType:UITextSpellCheckingTypeNo]]; + [self tableView].allowsSelection = NO; } - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { - return 4; + return [_textFields count]; } - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath { - return 50; + return 60; +} + +// Asks the delegate if editing should begin in the specified text field. +- (BOOL)_textFieldshouldBeginEditing:(UITextField*)textField { + if (textField == _textFields[3]) { + return NO; + } + return YES; +} + +- (BOOL)_textFieldshouldEndEditing:(UITextField*)textField { + return YES; +} + +- (BOOL)_textFieldshouldReturn:(UITextField*)textField { + return YES; } - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { @@ -43,77 +199,7 @@ - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSI cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MenuCell"]; } - if (indexPath.row == 0) { - // plain text field - CGRect frame = CGRectMake(c_originX, c_originY, c_width, c_height); - UITextField* textField = [[UITextField alloc] initWithFrame:frame]; - - textField.borderStyle = UITextBorderStyleBezel; - textField.textColor = [UIColor blackColor]; - textField.font = [UIFont systemFontOfSize:17.0]; - textField.placeholder = @"placeholder text"; - textField.backgroundColor = [UIColor whiteColor]; - textField.autocorrectionType = UITextAutocorrectionTypeNo; - textField.keyboardType = UIKeyboardTypeDefault; - textField.returnKeyType = UIReturnKeyDone; - textField.clearButtonMode = UITextFieldViewModeWhileEditing; - - [cell addSubview:textField]; - - } else if (indexPath.row == 1) { - // rounded text field - CGRect frame = CGRectMake(c_originX, c_originY, c_width, c_height); - UITextField* textField = [[UITextField alloc] initWithFrame:frame]; - - textField.borderStyle = UITextBorderStyleRoundedRect; - textField.textColor = [UIColor blackColor]; - textField.font = [UIFont systemFontOfSize:17.0]; - textField.placeholder = @"placeholder text"; - textField.backgroundColor = [UIColor whiteColor]; - textField.autocorrectionType = UITextAutocorrectionTypeNo; - textField.keyboardType = UIKeyboardTypeDefault; - textField.returnKeyType = UIReturnKeyDone; - textField.clearButtonMode = UITextFieldViewModeWhileEditing; - - [cell addSubview:textField]; - - } else if (indexPath.row == 2) { - // secure text field - - CGRect frame = CGRectMake(c_originX, c_originY, c_width, c_height); - UITextField* textField = [[UITextField alloc] initWithFrame:frame]; - - textField.borderStyle = UITextBorderStyleBezel; - textField.textColor = [UIColor blackColor]; - textField.font = [UIFont systemFontOfSize:17.0]; - textField.placeholder = @"password text"; - textField.backgroundColor = [UIColor whiteColor]; - textField.autocorrectionType = UITextAutocorrectionTypeNo; - textField.keyboardType = UIKeyboardTypeDefault; - textField.returnKeyType = UIReturnKeyDone; - textField.clearButtonMode = UITextFieldViewModeWhileEditing; - textField.secureTextEntry = TRUE; - - [cell addSubview:textField]; - - } else if (indexPath.row == 3) { - // text field with background image - - CGRect frame = CGRectMake(c_originX, c_originY, c_width, c_height); - UITextField* textField = [[UITextField alloc] initWithFrame:frame]; - - textField.background = [UIImage imageNamed:@"tf_bgimage.jpg"]; - textField.textColor = [UIColor blackColor]; - textField.font = [UIFont systemFontOfSize:17.0]; - textField.placeholder = @"placeholder text"; - textField.autocorrectionType = UITextAutocorrectionTypeNo; - textField.keyboardType = UIKeyboardTypeDefault; - textField.returnKeyType = UIReturnKeyDone; - textField.clearButtonMode = UITextFieldViewModeWhileEditing; - - [cell addSubview:textField]; - } - + [cell addSubview:[_textFields objectAtIndex:indexPath.row]]; return cell; } diff --git a/samples/WOCCatalog/WOCCatalog/XamlViewController.m b/samples/WOCCatalog/WOCCatalog/XamlViewController.m index c3bb2f01b1..7a004d85ca 100644 --- a/samples/WOCCatalog/WOCCatalog/XamlViewController.m +++ b/samples/WOCCatalog/WOCCatalog/XamlViewController.m @@ -110,6 +110,7 @@ - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSI checkBox.content = [WFPropertyValue createString:@"Check"]; UIView* checkBoxView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, cell.frame.size.height)]; [checkBoxView setNativeElement:checkBox]; + checkBoxView.layer.contentsGravity = kCAGravityLeft; cell.textLabel.text = @"Check Box"; cell.accessoryView = checkBoxView; } else if (indexPath.row == 3) { From fbdff4fd7300b56b3a57018fa249fdde68810231 Mon Sep 17 00:00:00 2001 From: John Frens Date: Thu, 21 Apr 2016 15:35:13 -0700 Subject: [PATCH 04/31] 7150362: Fixes #434, implements arc4random_uniform --- Frameworks/CoreFoundationAdditions/CFMisc.mm | 27 ++++++++++++++++---- build/Foundation/dll/Foundation.def | 1 + include/StarboardAdditionalDefines.h | 1 + 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Frameworks/CoreFoundationAdditions/CFMisc.mm b/Frameworks/CoreFoundationAdditions/CFMisc.mm index b39fa40268..a3d9133a5a 100644 --- a/Frameworks/CoreFoundationAdditions/CFMisc.mm +++ b/Frameworks/CoreFoundationAdditions/CFMisc.mm @@ -25,9 +25,8 @@ #import -#include - #include +#include #include "LoggingNative.h" static const wchar_t* TAG = L"CFMisc"; @@ -48,12 +47,30 @@ static ComPtr bufferStatics(GetBufferStatics()); UINT32 randResult = 0; - if (!SUCCEEDED(bufferStatics->GenerateRandomNumber(&randResult))) { - TraceVerbose(TAG, L"Unable to get random number!"); - } + FAIL_FAST_IF(!SUCCEEDED(bufferStatics->GenerateRandomNumber(&randResult))); return randResult; } +extern "C" uint32_t arc4random_uniform(uint32_t upperbound) { + if (upperbound == 0) { + TraceError(TAG, L"arc4random_uniform: Invalid upper bound"); + FAIL_FAST(); + } + + static ComPtr bufferStatics(GetBufferStatics()); + + UINT32 randResult = 0; + UINT32 highestMultipleOfUpperBound = ULONG_MAX - (ULONG_MAX % upperbound); + + // Constrict the result so it is < upperbound. In order to get a uniform result distribution, we generate a new random number + // when the result of GenerateRandomNumber falls within the range [highestMultipleOfUpperBound, ULONG_MAX] + do { + FAIL_FAST_IF(!SUCCEEDED(bufferStatics->GenerateRandomNumber(&randResult))); + } while (randResult >= highestMultipleOfUpperBound); + + return randResult % upperbound; +} + extern "C" int sysctlbyname(const char* name, void* out, size_t* outSize, const void*, size_t) { if (strcmp(name, "hw.machine") == 0) { const int required = 8; diff --git a/build/Foundation/dll/Foundation.def b/build/Foundation/dll/Foundation.def index 1476bbcfaa..352275a41e 100644 --- a/build/Foundation/dll/Foundation.def +++ b/build/Foundation/dll/Foundation.def @@ -406,6 +406,7 @@ LIBRARY Foundation OSSwapInt32 OSSwapLittleToHostInt32 arc4random + arc4random_uniform kCFAllocatorDefault DATA kCFBooleanFalse DATA kCFBooleanTrue DATA diff --git a/include/StarboardAdditionalDefines.h b/include/StarboardAdditionalDefines.h index 2555abf5f1..c1fb5e1fec 100644 --- a/include/StarboardAdditionalDefines.h +++ b/include/StarboardAdditionalDefines.h @@ -28,6 +28,7 @@ extern "C" { #endif uint arc4random(void); +uint arc4random_uniform(uint upper_bound); unsigned random(void); #ifdef __cplusplus From 4626285f6c68f01dedada307d52992a712a695d9 Mon Sep 17 00:00:00 2001 From: Artem Simonov Date: Wed, 27 Apr 2016 07:47:57 -0700 Subject: [PATCH 05/31] Fix the wrong STUB_ macros being used. --- include/Foundation/NSCache.h | 2 +- include/Foundation/NSUndoManager.h | 30 +++++++++++++++--------------- include/QuartzCore/CAEmitterCell.h | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/Foundation/NSCache.h b/include/Foundation/NSCache.h index 50716a64b5..6c89e10817 100644 --- a/include/Foundation/NSCache.h +++ b/include/Foundation/NSCache.h @@ -23,7 +23,7 @@ FOUNDATION_EXPORT_CLASS @interface NSCache : NSObject -@property (copy) NSString* name STUB_METHOD; +@property (copy) NSString* name STUB_PROPERTY; - (ObjectType)objectForKey:(KeyType)key STUB_METHOD; - (void)setObject:(ObjectType)obj forKey:(KeyType)key STUB_METHOD; - (void)setObject:(ObjectType)obj forKey:(KeyType)key cost:(NSUInteger)num STUB_METHOD; diff --git a/include/Foundation/NSUndoManager.h b/include/Foundation/NSUndoManager.h index 9714e79a77..cd005aaf7a 100644 --- a/include/Foundation/NSUndoManager.h +++ b/include/Foundation/NSUndoManager.h @@ -38,32 +38,32 @@ FOUNDATION_EXPORT_CLASS @interface NSUndoManager : NSObject - (void)registerUndoWithTarget:(id)target selector:(SEL)aSelector object:(id)anObject STUB_METHOD; - (id)prepareWithInvocationTarget:(id)target STUB_METHOD; -@property (readonly) BOOL canUndo STUB_METHOD; -@property (readonly) BOOL canRedo STUB_METHOD; +@property (readonly) BOOL canUndo STUB_PROPERTY; +@property (readonly) BOOL canRedo STUB_PROPERTY; - (void)undo STUB_METHOD; - (void)undoNestedGroup STUB_METHOD; - (void)redo STUB_METHOD; -@property NSUInteger levelsOfUndo STUB_METHOD; +@property NSUInteger levelsOfUndo STUB_PROPERTY; - (void)beginUndoGrouping STUB_METHOD; - (void)endUndoGrouping STUB_METHOD; -@property BOOL groupsByEvent STUB_METHOD; -@property (readonly) NSInteger groupingLevel STUB_METHOD; +@property BOOL groupsByEvent STUB_PROPERTY; +@property (readonly) NSInteger groupingLevel STUB_PROPERTY; - (void)disableUndoRegistration STUB_METHOD; - (void)enableUndoRegistration STUB_METHOD; -@property (readonly, getter=isUndoRegistrationEnabled) BOOL undoRegistrationEnabled STUB_METHOD; -@property (readonly, getter=isUndoing) BOOL undoing STUB_METHOD; -@property (readonly, getter=isRedoing) BOOL redoing STUB_METHOD; +@property (readonly, getter=isUndoRegistrationEnabled) BOOL undoRegistrationEnabled STUB_PROPERTY; +@property (readonly, getter=isUndoing) BOOL undoing STUB_PROPERTY; +@property (readonly, getter=isRedoing) BOOL redoing STUB_PROPERTY; - (void)removeAllActions STUB_METHOD; - (void)removeAllActionsWithTarget:(id)target STUB_METHOD; -@property (readonly, copy) NSString* undoActionName STUB_METHOD; -@property (readonly, copy) NSString* redoActionName STUB_METHOD; +@property (readonly, copy) NSString* undoActionName STUB_PROPERTY; +@property (readonly, copy) NSString* redoActionName STUB_PROPERTY; - (void)setActionName:(NSString*)actionName STUB_METHOD; -@property (readonly, copy) NSString* undoMenuItemTitle STUB_METHOD; -@property (readonly, copy) NSString* redoMenuItemTitle STUB_METHOD; +@property (readonly, copy) NSString* undoMenuItemTitle STUB_PROPERTY; +@property (readonly, copy) NSString* redoMenuItemTitle STUB_PROPERTY; - (NSString*)undoMenuTitleForUndoActionName:(NSString*)actionName STUB_METHOD; - (NSString*)redoMenuTitleForUndoActionName:(NSString*)actionName STUB_METHOD; -@property (copy) NSArray* runLoopModes STUB_METHOD; +@property (copy) NSArray* runLoopModes STUB_PROPERTY; - (void)setActionIsDiscardable:(BOOL)discardable STUB_METHOD; -@property (readonly) BOOL undoActionIsDiscardable STUB_METHOD; -@property (readonly) BOOL redoActionIsDiscardable STUB_METHOD; +@property (readonly) BOOL undoActionIsDiscardable STUB_PROPERTY; +@property (readonly) BOOL redoActionIsDiscardable STUB_PROPERTY; @end diff --git a/include/QuartzCore/CAEmitterCell.h b/include/QuartzCore/CAEmitterCell.h index 460952342a..abda125c3b 100644 --- a/include/QuartzCore/CAEmitterCell.h +++ b/include/QuartzCore/CAEmitterCell.h @@ -61,8 +61,8 @@ CA_EXPORT_CLASS @property CGFloat xAcceleration STUB_PROPERTY; @property CGFloat yAcceleration STUB_PROPERTY; @property CGFloat zAcceleration STUB_PROPERTY; -+ (id)defaultValueForKey:(NSString*)key STUB_PROPERTY; -- (BOOL)shouldArchiveValueForKey:(NSString*)key STUB_PROPERTY; ++ (id)defaultValueForKey:(NSString*)key STUB_METHOD; +- (BOOL)shouldArchiveValueForKey:(NSString*)key STUB_METHOD; // CAMediaTiming @property BOOL autoreverses; From 0d15a8b56a26f541c2d7e0ef0ecf9de458865adf Mon Sep 17 00:00:00 2001 From: Artem Simonov Date: Wed, 27 Apr 2016 08:02:14 -0700 Subject: [PATCH 06/31] Fix @status typo in UITextField.mm --- Frameworks/UIKit/UITextField.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Frameworks/UIKit/UITextField.mm b/Frameworks/UIKit/UITextField.mm index 597cf25ebb..21bb823317 100644 --- a/Frameworks/UIKit/UITextField.mm +++ b/Frameworks/UIKit/UITextField.mm @@ -710,7 +710,7 @@ - (UIKeyboardType)keyboardType { } /** - @Status Stub. + @Status Stub */ - (void)setReturnKeyType:(UIReturnKeyType)type { UNIMPLEMENTED(); From 83785439d6638e09aff261fa8053624ca12cd3ab Mon Sep 17 00:00:00 2001 From: amit agarwal Date: Tue, 26 Apr 2016 23:06:00 -0700 Subject: [PATCH 07/31] Suppressing warnings for auto generated files --- build/Foundation/lib/FoundationLib.vcxproj | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build/Foundation/lib/FoundationLib.vcxproj b/build/Foundation/lib/FoundationLib.vcxproj index 3402c17ea8..4663d076e9 100644 --- a/build/Foundation/lib/FoundationLib.vcxproj +++ b/build/Foundation/lib/FoundationLib.vcxproj @@ -210,8 +210,12 @@ - - + + -Wno-incompatible-pointer-types-discards-qualifiers -Wno-deprecated-declarations %(AdditionalOptions) + + + -Wno-implicit-function-declaration %(AdditionalOptions) + From 3f35d5bc3d673d6d85a7b6ff8b2854036d1af778 Mon Sep 17 00:00:00 2001 From: Jeyaram Jeyaraj Date: Tue, 26 Apr 2016 17:49:09 -0700 Subject: [PATCH 08/31] Adding missing annotations. --- Frameworks/CoreFoundationAdditions/CFUUID.mm | 15 +++++++++++++++ Frameworks/CoreText/CTRun.mm | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Frameworks/CoreFoundationAdditions/CFUUID.mm b/Frameworks/CoreFoundationAdditions/CFUUID.mm index bd71997cca..6c98171a2f 100644 --- a/Frameworks/CoreFoundationAdditions/CFUUID.mm +++ b/Frameworks/CoreFoundationAdditions/CFUUID.mm @@ -33,14 +33,23 @@ CFUUIDRef CFUUIDCreate(CFAllocatorRef allocator) { return (CFUUIDRef)[[NSUUID alloc] init]; } +/** + @Status Interoperable +*/ CFUUIDRef CFUUIDCreateFromString(CFAllocatorRef allocator, CFStringRef string) { return (CFUUIDRef)[[NSUUID alloc] initWithUUIDString:(NSString*)string]; } +/** + @Status Interoperable +*/ CFUUIDRef CFUUIDCreateFromUUIDBytes(CFAllocatorRef allocator, CFUUIDBytes bytes) { return (CFUUIDRef)[[NSUUID alloc] initWithUUIDBytes:reinterpret_cast(&bytes)]; } +/** + @Status Interoperable +*/ CFUUIDRef CFUUIDCreateWithBytes(CFAllocatorRef allocator, uint8_t byte0, uint8_t byte1, @@ -63,6 +72,9 @@ CFUUIDRef CFUUIDCreateWithBytes(CFAllocatorRef allocator, return CFUUIDCreateFromUUIDBytes(allocator, bytes); } +/** + @Status Interoperable +*/ CFUUIDRef CFUUIDGetConstantUUIDWithBytes(CFAllocatorRef allocator, uint8_t byte0, uint8_t byte1, @@ -90,6 +102,9 @@ CFUUIDRef CFUUIDGetConstantUUIDWithBytes(CFAllocatorRef allocator, return (CFUUIDRef)constantUUIDs[bytes]; } +/** + @Status Interoperable +*/ CFUUIDBytes CFUUIDGetUUIDBytes(CFUUIDRef self) { CFUUIDBytes bytes; [(NSUUID*)self getUUIDBytes:reinterpret_cast(&bytes)]; diff --git a/Frameworks/CoreText/CTRun.mm b/Frameworks/CoreText/CTRun.mm index dcf9b2c0c7..b0b27d2e85 100644 --- a/Frameworks/CoreText/CTRun.mm +++ b/Frameworks/CoreText/CTRun.mm @@ -59,7 +59,7 @@ CFIndex CTRunGetGlyphCount(CTRunRef run) { } /** - @Status Stub +@Status Interoperable */ CFDictionaryRef CTRunGetAttributes(CTRunRef run) { if (run == nil) { From d755f15cbe55132138c3b875942078b6dbeed6d4 Mon Sep 17 00:00:00 2001 From: pengzh Date: Wed, 27 Apr 2016 02:17:15 +0800 Subject: [PATCH 09/31] Fix warning for delaysContentTouches prperties in UIScrollView --- Frameworks/UIKit/UIScrollView.mm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Frameworks/UIKit/UIScrollView.mm b/Frameworks/UIKit/UIScrollView.mm index ca42fb3fb1..50372a1f21 100644 --- a/Frameworks/UIKit/UIScrollView.mm +++ b/Frameworks/UIKit/UIScrollView.mm @@ -362,7 +362,7 @@ - (instancetype)initWithCoder:(NSCoder*)coder { - (instancetype)initWithFrame:(CGRect)pos { [super initWithFrame:pos]; [self setClipsToBounds:1]; - [self setDelaysContentTouches:1]; + _delaysContentTouches = TRUE; commonInit(self); commonPostInit(self); @@ -432,6 +432,7 @@ - (void)setAlwaysBounceHorizontal:(BOOL)enable { - (BOOL)alwaysBounceHorizontal { return _alwaysBounceHorizontal; } + /** @Status Stub */ @@ -440,6 +441,13 @@ - (void)setDelaysContentTouches:(BOOL)delay { _delaysContentTouches = delay; } +/** + @Status Interoperable +*/ +- (BOOL)delayContentTouches { + return _delaysContentTouches; +} + /** @Status Interoperable */ From 488aa58d1308603f9deada053808fb101b1a86d7 Mon Sep 17 00:00:00 2001 From: jackgao Date: Tue, 26 Apr 2016 09:00:01 +0800 Subject: [PATCH 10/31] Remove STUB_PROPERTY for tintColor property in UIToolbar, UIBarButtonItem and UISegmentedControl classes. --- Frameworks/UIKit/UIBarButtonItem.mm | 8 +++----- Frameworks/UIKit/UISegmentedControl.mm | 7 +++---- Frameworks/UIKit/UIToolbar.mm | 7 +++---- include/UIKit/UIBarButtonItem.h | 2 +- include/UIKit/UISegmentedControl.h | 2 +- include/UIKit/UIToolbar.h | 2 +- 6 files changed, 12 insertions(+), 16 deletions(-) diff --git a/Frameworks/UIKit/UIBarButtonItem.mm b/Frameworks/UIKit/UIBarButtonItem.mm index ce6d284513..ada1086a54 100644 --- a/Frameworks/UIKit/UIBarButtonItem.mm +++ b/Frameworks/UIKit/UIBarButtonItem.mm @@ -511,20 +511,18 @@ - (void)setTitleTextAttributes:(NSDictionary*)attributes forState:(UIControlStat } /** - @Status Stub + @Status Caveat + @Notes May not be fully implemented */ - (void)setTintColor:(UIColor*)tintColor { - UNIMPLEMENTED(); - [_buttonView setTintColor:tintColor]; [_customView setTintColor:tintColor]; } /** - @Status Stub + @Status Interoperable */ - (UIColor*)tintColor { - UNIMPLEMENTED(); return [[self _view] tintColor]; } diff --git a/Frameworks/UIKit/UISegmentedControl.mm b/Frameworks/UIKit/UISegmentedControl.mm index 12d1820823..6f80223c94 100644 --- a/Frameworks/UIKit/UISegmentedControl.mm +++ b/Frameworks/UIKit/UISegmentedControl.mm @@ -513,10 +513,10 @@ - (unsigned)numberOfSegments { } /** - @Status Stub + @Status Caveat + @Notes May not be fully implemented */ - (void)setTintColor:(UIColor*)uiColor { - UNIMPLEMENTED(); _tintColor = uiColor; if (isOSTarget(@"7.0")) { @@ -525,10 +525,9 @@ - (void)setTintColor:(UIColor*)uiColor { } /** - @Status Stub + @Status Interoperable */ - (id)tintColor { - UNIMPLEMENTED(); return _tintColor; } diff --git a/Frameworks/UIKit/UIToolbar.mm b/Frameworks/UIKit/UIToolbar.mm index 38bbd4dbf0..098155fe57 100644 --- a/Frameworks/UIKit/UIToolbar.mm +++ b/Frameworks/UIKit/UIToolbar.mm @@ -175,10 +175,10 @@ static void setBackground(UIToolbar* self, UIColor* color) { } /** - @Status Stub + @Status Caveat + @Notes May not be fully implemented */ - (void)setTintColor:(id)color { - UNIMPLEMENTED(); _tintColor = color; if (!isOSTarget(@"7.0")) { @@ -199,10 +199,9 @@ - (void)setTintColor:(id)color { } /** - @Status Stub + @Status Interoperable */ - (UIColor*)tintColor { - UNIMPLEMENTED(); return _tintColor; } diff --git a/include/UIKit/UIBarButtonItem.h b/include/UIKit/UIBarButtonItem.h index 5d6362e3c8..640dc48aae 100644 --- a/include/UIKit/UIBarButtonItem.h +++ b/include/UIKit/UIBarButtonItem.h @@ -88,7 +88,7 @@ UIKIT_EXPORT_CLASS @property (nonatomic, retain) UIView* customView; @property (nonatomic, assign) id target; @property (nonatomic) SEL action; -@property (nonatomic, retain) UIColor* tintColor STUB_PROPERTY; +@property (nonatomic, retain) UIColor* tintColor; @property (nonatomic, copy) NSSet* possibleTitles; // ---------------------------------------------------------------------------------------------------------- diff --git a/include/UIKit/UISegmentedControl.h b/include/UIKit/UISegmentedControl.h index 60f9cef152..bd69e22c74 100644 --- a/include/UIKit/UISegmentedControl.h +++ b/include/UIKit/UISegmentedControl.h @@ -46,7 +46,7 @@ UIKIT_EXPORT_CLASS @interface UISegmentedControl : UIControl @property (nonatomic) UISegmentedControlStyle segmentedControlStyle STUB_PROPERTY; -@property (nonatomic, retain) UIColor* tintColor STUB_PROPERTY; +@property (nonatomic, retain) UIColor* tintColor; @property (nonatomic, assign, readonly) NSUInteger numberOfSegments; @property (nonatomic, assign) NSInteger selectedSegmentIndex; @property (nonatomic, getter=isMomentary) BOOL momentary; diff --git a/include/UIKit/UIToolbar.h b/include/UIKit/UIToolbar.h index a0d83c2c64..8e6d23f809 100644 --- a/include/UIKit/UIToolbar.h +++ b/include/UIKit/UIToolbar.h @@ -47,7 +47,7 @@ UIKIT_EXPORT_CLASS - (void)setBackgroundImage:(UIImage*)backgroundImage forToolbarPosition:(UIToolbarPosition)topOrBottom barMetrics:(UIBarMetrics)barMetrics; @property (nonatomic) UIBarStyle barStyle; -@property (nonatomic, retain) UIColor* tintColor STUB_PROPERTY; +@property (nonatomic, retain) UIColor* tintColor; @property (nonatomic, retain) UIColor* barTintColor STUB_PROPERTY; @property (nonatomic, copy) NSArray* items; @property (nonatomic, assign, getter=isTranslucent) BOOL translucent STUB_PROPERTY; From 1243567d0af9c2005189c2f766fb1f27b98262d4 Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Wed, 27 Apr 2016 11:54:00 -0700 Subject: [PATCH 11/31] Fix woccatalog app - picked wrong hash from git reflog earlier when apply changes. --- samples/WOCCatalog/WOCCatalog/TextFieldsViewController.m | 7 ++++--- samples/WOCCatalog/WOCCatalog/XamlViewController.m | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.m b/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.m index 4bfd52d59b..fb03e1b3b0 100644 --- a/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.m +++ b/samples/WOCCatalog/WOCCatalog/TextFieldsViewController.m @@ -22,6 +22,7 @@ static const CGFloat c_height = 40; @implementation TextFieldsViewController { +@private NSMutableArray* _textFields; } @@ -178,18 +179,18 @@ - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPat } // Asks the delegate if editing should begin in the specified text field. -- (BOOL)_textFieldshouldBeginEditing:(UITextField*)textField { +- (BOOL)textFieldShouldBeginEditing:(UITextField*)textField { if (textField == _textFields[3]) { return NO; } return YES; } -- (BOOL)_textFieldshouldEndEditing:(UITextField*)textField { +- (BOOL)textFieldShouldEndEditing:(UITextField*)textField { return YES; } -- (BOOL)_textFieldshouldReturn:(UITextField*)textField { +- (BOOL)textFieldShouldReturn:(UITextField*)textField { return YES; } diff --git a/samples/WOCCatalog/WOCCatalog/XamlViewController.m b/samples/WOCCatalog/WOCCatalog/XamlViewController.m index 7a004d85ca..c3bb2f01b1 100644 --- a/samples/WOCCatalog/WOCCatalog/XamlViewController.m +++ b/samples/WOCCatalog/WOCCatalog/XamlViewController.m @@ -110,7 +110,6 @@ - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSI checkBox.content = [WFPropertyValue createString:@"Check"]; UIView* checkBoxView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, cell.frame.size.height)]; [checkBoxView setNativeElement:checkBox]; - checkBoxView.layer.contentsGravity = kCAGravityLeft; cell.textLabel.text = @"Check Box"; cell.accessoryView = checkBoxView; } else if (indexPath.row == 3) { From 934f9c237d825c189e811223f8f9d62f46bb623f Mon Sep 17 00:00:00 2001 From: pengzh Date: Thu, 21 Apr 2016 07:08:42 +0800 Subject: [PATCH 12/31] Implement encode/decode function for CGVector/UIEdgeInsets/UIOffset/CGAffineTransform --- Frameworks/CoreGraphics/CGGeometry.mm | 9 --- Frameworks/UIKit/NSCoder+UIKitAdditions.mm | 70 ++++++++++-------- build/CoreGraphics/dll/CoreGraphics.def | 1 - include/CoreGraphics/CGGeometry.h | 9 ++- include/UIKit/UIGeometry.h | 16 ++-- .../UIKit/NSCoder+UIKitAdditionsTest.mm | 73 +++++++++++++++++++ 6 files changed, 130 insertions(+), 48 deletions(-) diff --git a/Frameworks/CoreGraphics/CGGeometry.mm b/Frameworks/CoreGraphics/CGGeometry.mm index 3bcb641121..2fe6e32e95 100644 --- a/Frameworks/CoreGraphics/CGGeometry.mm +++ b/Frameworks/CoreGraphics/CGGeometry.mm @@ -86,15 +86,6 @@ bool CGRectMakeWithDictionaryRepresentation(CFDictionaryRef dict, CGRect* rect) return StubReturn(); } -/** - @Status Stub - @Notes -*/ -CGVector CGVectorMake(CGFloat dx, CGFloat dy) { - UNIMPLEMENTED(); - return StubReturn(); -} - /** @Status Stub @Notes diff --git a/Frameworks/UIKit/NSCoder+UIKitAdditions.mm b/Frameworks/UIKit/NSCoder+UIKitAdditions.mm index d9781088b3..3a64c72735 100644 --- a/Frameworks/UIKit/NSCoder+UIKitAdditions.mm +++ b/Frameworks/UIKit/NSCoder+UIKitAdditions.mm @@ -144,35 +144,31 @@ - (void)encodeCGSize:(CGSize)size forKey:(NSString*)aKey { } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)encodeCGVector:(CGVector)vector forKey:(NSString*)key STUB_METHOD { - UNIMPLEMENTED(); +- (void)encodeCGVector:(CGVector)vector forKey:(NSString*)key { + [self encodeObject:[NSValue valueWithBytes:&vector objCType:@encode(CGVector)] forKey:key]; } /** - @Status Stub - @Notes + @Status Interoperable */ - (void)encodeUIEdgeInsets:(UIEdgeInsets)insets forKey:(NSString*)key { - UNIMPLEMENTED(); + [self encodeObject:[NSValue valueWithBytes:&insets objCType:@encode(UIEdgeInsets)] forKey:key]; } /** - @Status Stub - @Notes + @Status Interoperable */ - (void)encodeUIOffset:(UIOffset)offset forKey:(NSString*)key { - UNIMPLEMENTED(); + [self encodeObject:[NSValue valueWithBytes:&offset objCType:@encode(UIOffset)] forKey:key]; } /** - @Status Stub - @Notes + @Status Interoperable */ - (void)encodeCGAffineTransform:(CGAffineTransform)transform forKey:(NSString*)key { - UNIMPLEMENTED(); + [self encodeObject:[NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)] forKey:key]; } @end @@ -221,38 +217,54 @@ - (CGSize)decodeCGSizeForKey:(NSString*)key { } /** - @Status Stub - @Notes + @Status Interoperable */ - (CGVector)decodeCGVectorForKey:(NSString*)key { - UNIMPLEMENTED(); - return StubReturn(); + CGVector ret = CGVectorMake(0, 0); + id value = [self decodeObjectForKey:key]; + + if (value != nil) { + [value getValue:&ret]; + } + return ret; } /** - @Status Stub - @Notes + @Status Interoperable */ - (UIEdgeInsets)decodeUIEdgeInsetsForKey:(NSString*)key { - UNIMPLEMENTED(); - return StubReturn(); + UIEdgeInsets ret = UIEdgeInsetsMake(0, 0, 0, 0); + id value = [self decodeObjectForKey:key]; + + if (value != nil) { + [value getValue:&ret]; + } + return ret; } /** - @Status Stub - @Notes + @Status Interoperable */ - (UIOffset)decodeUIOffsetForKey:(NSString*)key { - UNIMPLEMENTED(); - return StubReturn(); + UIOffset ret = UIOffsetMake(0, 0); + id value = [self decodeObjectForKey:key]; + + if (value != nil) { + [value getValue:&ret]; + } + return ret; } /** - @Status Stub - @Notes + @Status Interoperable */ - (CGAffineTransform)decodeCGAffineTransformForKey:(NSString*)key { - UNIMPLEMENTED(); - return StubReturn(); + CGAffineTransform ret = CGAffineTransformMake(0, 0, 0, 0, 0, 0); + id value = [self decodeObjectForKey:key]; + + if (value != nil) { + [value getValue:&ret]; + } + return ret; } @end \ No newline at end of file diff --git a/build/CoreGraphics/dll/CoreGraphics.def b/build/CoreGraphics/dll/CoreGraphics.def index 7c8e15d983..36571acfd2 100644 --- a/build/CoreGraphics/dll/CoreGraphics.def +++ b/build/CoreGraphics/dll/CoreGraphics.def @@ -299,7 +299,6 @@ LIBRARY CoreGraphics CGPointMakeWithDictionaryRepresentation CGSizeMakeWithDictionaryRepresentation CGRectMakeWithDictionaryRepresentation - CGVectorMake CGRectDivide CGRectIntegral CGRectIntersection diff --git a/include/CoreGraphics/CGGeometry.h b/include/CoreGraphics/CGGeometry.h index 9e1eb89edf..3539fa3aed 100644 --- a/include/CoreGraphics/CGGeometry.h +++ b/include/CoreGraphics/CGGeometry.h @@ -68,6 +68,14 @@ static inline CGSize CGSizeMake(CGFloat x, CGFloat y) { return result; } +/** +@Status Interoperable +*/ +static inline CGVector CGVectorMake(CGFloat dx, CGFloat dy) { + CGVector result = { dx, dy }; + return result; +} + /** @Status Interoperable */ @@ -222,5 +230,4 @@ COREGRAPHICS_EXPORT CFDictionaryRef CGRectCreateDictionaryRepresentation(CGRect) COREGRAPHICS_EXPORT bool CGPointMakeWithDictionaryRepresentation(CFDictionaryRef dict, CGPoint* point) STUB_METHOD; COREGRAPHICS_EXPORT bool CGSizeMakeWithDictionaryRepresentation(CFDictionaryRef dict, CGSize* size) STUB_METHOD; COREGRAPHICS_EXPORT bool CGRectMakeWithDictionaryRepresentation(CFDictionaryRef dict, CGRect* rect) STUB_METHOD; -COREGRAPHICS_EXPORT CGVector CGVectorMake(CGFloat dx, CGFloat dy) STUB_METHOD; COREGRAPHICS_EXPORT void CGRectDivide(CGRect rect, CGRect* slice, CGRect* remainder, CGFloat amount, CGRectEdge edge) STUB_METHOD; diff --git a/include/UIKit/UIGeometry.h b/include/UIKit/UIGeometry.h index 5b736c3df5..0df4ed97a2 100644 --- a/include/UIKit/UIGeometry.h +++ b/include/UIKit/UIGeometry.h @@ -104,17 +104,17 @@ UIKIT_EXPORT CGSize CGSizeFromString(NSString* string); - (void)encodeCGSize:(CGSize)size forKey:(NSString*)key; - (void)encodeCGPoint:(CGPoint)point forKey:(NSString*)key; - (void)encodeCGRect:(CGRect)rect forKey:(NSString*)key; -- (void)encodeCGVector:(CGVector)vector forKey:(NSString*)key STUB_METHOD; -- (void)encodeCGAffineTransform:(CGAffineTransform)transform forKey:(NSString*)key STUB_METHOD; -- (void)encodeUIEdgeInsets:(UIEdgeInsets)insets forKey:(NSString*)key STUB_METHOD; -- (void)encodeUIOffset:(UIOffset)offset forKey:(NSString*)key STUB_METHOD; +- (void)encodeCGVector:(CGVector)vector forKey:(NSString*)key; +- (void)encodeCGAffineTransform:(CGAffineTransform)transform forKey:(NSString*)key; +- (void)encodeUIEdgeInsets:(UIEdgeInsets)insets forKey:(NSString*)key; +- (void)encodeUIOffset:(UIOffset)offset forKey:(NSString*)key; - (CGSize)decodeCGSizeForKey:(NSString*)key; - (CGPoint)decodeCGPointForKey:(NSString*)key; - (CGRect)decodeCGRectForKey:(NSString*)key; -- (CGVector)decodeCGVectorForKey:(NSString*)key STUB_METHOD; -- (CGAffineTransform)decodeCGAffineTransformForKey:(NSString*)key STUB_METHOD; -- (UIEdgeInsets)decodeUIEdgeInsetsForKey:(NSString*)key STUB_METHOD; -- (UIOffset)decodeUIOffsetForKey:(NSString*)key STUB_METHOD; +- (CGVector)decodeCGVectorForKey:(NSString*)key; +- (CGAffineTransform)decodeCGAffineTransformForKey:(NSString*)key; +- (UIEdgeInsets)decodeUIEdgeInsetsForKey:(NSString*)key; +- (UIOffset)decodeUIOffsetForKey:(NSString*)key; @end diff --git a/tests/unittests/UIKit/NSCoder+UIKitAdditionsTest.mm b/tests/unittests/UIKit/NSCoder+UIKitAdditionsTest.mm index da3e067916..c5627a5c13 100644 --- a/tests/unittests/UIKit/NSCoder+UIKitAdditionsTest.mm +++ b/tests/unittests/UIKit/NSCoder+UIKitAdditionsTest.mm @@ -31,9 +31,12 @@ CGSize size = CGSizeMake(10, 18); [archiver encodeCGSize:size forKey:@"CGSize"]; [archiver finishEncoding]; + [archiver release]; NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; CGSize newSize = [unarchiver decodeCGSizeForKey:@"CGSize"]; + [unarchiver finishDecoding]; + [unarchiver release]; EXPECT_TRUE(CGSizeEqualToSize(newSize, size)); } @@ -44,9 +47,12 @@ CGPoint point = CGPointMake(10, 18); [archiver encodeCGPoint:point forKey:@"CGPoint"]; [archiver finishEncoding]; + [archiver release]; NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; CGPoint newPoint = [unarchiver decodeCGPointForKey:@"CGPoint"]; + [unarchiver finishDecoding]; + [unarchiver release]; EXPECT_TRUE(CGPointEqualToPoint(newPoint, point)); } @@ -57,9 +63,76 @@ CGRect rect = CGRectMake(10, 18, 5, 5); [archiver encodeCGRect:rect forKey:@"CGRect"]; [archiver finishEncoding]; + [archiver release]; NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; CGRect newRect = [unarchiver decodeCGRectForKey:@"CGRect"]; + [unarchiver finishDecoding]; + [unarchiver release]; EXPECT_TRUE(CGRectEqualToRect(newRect, rect)); +} + +TEST(NSCoder_UIKit, encodeCGVector) { + NSMutableData* data = [[[NSMutableData alloc] init] autorelease]; + NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + CGVector vector = CGVectorMake(10, 18); + [archiver encodeCGVector:vector forKey:@"CGVector"]; + [archiver finishEncoding]; + [archiver release]; + + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + CGVector newVector = [unarchiver decodeCGVectorForKey:@"CGVector"]; + [unarchiver finishDecoding]; + [unarchiver release]; + + EXPECT_TRUE((vector.dx == newVector.dx) && (vector.dy == newVector.dy)); +} + +TEST(NSCoder_UIKit, encodeUIEdgeInsets) { + NSMutableData* data = [[[NSMutableData alloc] init] autorelease]; + NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + UIEdgeInsets edgeInsets = UIEdgeInsetsMake(10, 18, 5, 5); + [archiver encodeUIEdgeInsets:edgeInsets forKey:@"UIEdgeInsets"]; + [archiver finishEncoding]; + [archiver release]; + + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + UIEdgeInsets newEdgeInsets = [unarchiver decodeUIEdgeInsetsForKey:@"UIEdgeInsets"]; + [unarchiver finishDecoding]; + [unarchiver release]; + + EXPECT_TRUE(UIEdgeInsetsEqualToEdgeInsets(edgeInsets, newEdgeInsets)); +} + +TEST(NSCoder_UIKit, encodeUIOffset) { + NSMutableData* data = [[[NSMutableData alloc] init] autorelease]; + NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + UIOffset offset = UIOffsetMake(10, 18); + [archiver encodeUIOffset:offset forKey:@"UIOffset"]; + [archiver finishEncoding]; + [archiver release]; + + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + UIOffset newOffset = [unarchiver decodeUIOffsetForKey:@"UIOffset"]; + [unarchiver finishDecoding]; + [unarchiver release]; + + EXPECT_TRUE(UIOffsetEqualToOffset(offset, newOffset)); +} + +TEST(NSCoder_UIKit, encodeCGAffineTransform) { + NSMutableData* data = [[[NSMutableData alloc] init] autorelease]; + NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + CGAffineTransform transform = CGAffineTransformMake(10, 18, 17, 15, 3, 2); + [archiver encodeCGAffineTransform:transform forKey:@"CGAffineTransform"]; + [archiver finishEncoding]; + [archiver release]; + + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + CGAffineTransform newTransform = [unarchiver decodeCGAffineTransformForKey:@"CGAffineTransform"]; + [unarchiver finishDecoding]; + [unarchiver release]; + + EXPECT_TRUE(CGAffineTransformEqualToTransform(transform, newTransform)); } \ No newline at end of file From 673287cf884429bd1903f453c9850a2aa31080a5 Mon Sep 17 00:00:00 2001 From: John Frens Date: Wed, 27 Apr 2016 14:13:52 -0700 Subject: [PATCH 13/31] 7286029: Fixes #451, Implements NSArray description --- Frameworks/Foundation/NSArray.mm | 14 ++++++++++++-- tests/unittests/Foundation/NSArrayTests.mm | 11 +++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Frameworks/Foundation/NSArray.mm b/Frameworks/Foundation/NSArray.mm index 4cbb60a357..d109b38319 100644 --- a/Frameworks/Foundation/NSArray.mm +++ b/Frameworks/Foundation/NSArray.mm @@ -824,8 +824,18 @@ - (void)encodeWithCoder:(NSCoder*)coder { @Status Interoperable */ - (NSString*)description { - UNIMPLEMENTED(); - return [super description]; + NSMutableString* s = [NSMutableString string]; + [s appendString:@"("]; + for (id val in self) { + [s appendFormat:@"%@, ", val]; + } + + if ([self count] > 0) { + [s deleteCharactersInRange:{[s length] - 2, 2}]; + } + + [s appendString:@")"]; + return s; } /** diff --git a/tests/unittests/Foundation/NSArrayTests.mm b/tests/unittests/Foundation/NSArrayTests.mm index 14f6f2b23b..aad2e41a25 100644 --- a/tests/unittests/Foundation/NSArrayTests.mm +++ b/tests/unittests/Foundation/NSArrayTests.mm @@ -223,4 +223,15 @@ - (void)verifyAndResetFlags:(unsigned int)expectedCalls { ASSERT_OBJCEQ(testArray, expectedArray); +} + +TEST(NSArray, Description) { + NSArray* testArray = @[ @1, @2, @3 ]; + ASSERT_OBJCEQ(@"(1, 2, 3)", [testArray description]); + + NSArray* testArray2 = [[NSArray new] autorelease]; + ASSERT_OBJCEQ(@"()", [testArray2 description]); + + NSArray* testArray3 = @[ @1 ]; + ASSERT_OBJCEQ(@"(1)", [testArray3 description]); } \ No newline at end of file From 94fc35cb534deab4022c7ef8c9bea60fb737f016 Mon Sep 17 00:00:00 2001 From: Jeyaram Jeyaraj Date: Wed, 27 Apr 2016 17:59:04 -0700 Subject: [PATCH 14/31] Implementation of NSFileHandle. Supports the following: - Files - Reading and writing to streams - Null device Reviewed by: Raj Seshasankaran ; Dustin Howett (duhowett@microsoft.com); Ben Viglietta ; Jared Henderson --- Frameworks/Foundation/NSFileHandle.mm | 379 +++++++++++------- .../Foundation/_NSFileHandleNullDevice.mm | 97 +++++ Frameworks/Starboard/PlatformSupport.cpp | 44 +- Frameworks/include/Platform/EbrPlatform.h | 9 +- Frameworks/include/_NSFileHandleNullDevice.h | 21 + build/Foundation/lib/FoundationLib.vcxproj | 1 + build/Starboard/dll/Starboard.def | 3 + .../Foundation/Foundation.UnitTests.vcxproj | 8 + include/Foundation/NSFileHandle.h | 53 +-- .../Foundation/NSFileHandleTestFile.txt | 1 + .../unittests/Foundation/NSFileHandleTests.mm | 329 +++++++++++++++ 11 files changed, 762 insertions(+), 183 deletions(-) create mode 100644 Frameworks/Foundation/_NSFileHandleNullDevice.mm create mode 100644 Frameworks/include/_NSFileHandleNullDevice.h create mode 100644 tests/unittests/Foundation/NSFileHandleTestFile.txt create mode 100644 tests/unittests/Foundation/NSFileHandleTests.mm diff --git a/Frameworks/Foundation/NSFileHandle.mm b/Frameworks/Foundation/NSFileHandle.mm index 7425a16106..dd527b9c8a 100644 --- a/Frameworks/Foundation/NSFileHandle.mm +++ b/Frameworks/Foundation/NSFileHandle.mm @@ -14,129 +14,171 @@ // //****************************************************************************** -#import #import +#import +#import #import +#import <_NSFileHandleNullDevice.h> +#import + +#import +#import NSString* const NSFileHandleNotificationFileHandleItem = @"NSFileHandleNotificationFileHandleItem"; NSString* const NSFileHandleNotificationDataItem = @"NSFileHandleNotificationDataItem"; NSString* const NSFileHandleOperationException = @"NSFileHandleOperationException"; NSString* const NSFileHandleNotificationMonitorModes = @"NSFileHandleNotificationMonitorModes"; -@implementation NSFileHandle -/** - @Status Stub - @Notes -*/ -+ (instancetype)fileHandleForReadingAtPath:(NSString*)path { - UNIMPLEMENTED(); - return StubReturn(); +typedef NS_ENUM(NSUInteger, _NSFileOpenMode) { _NSFileOpenModeRead, _NSFileOpenModeWrite, _NSFileOpenModeUpdate }; + +@implementation NSFileHandle { + BOOL _closeOnDealloc; + int _fileDescriptor; } /** - @Status Stub - @Notes + @Status Interoperable */ -+ (instancetype)fileHandleForReadingFromURL:(NSURL*)url error:(NSError* _Nullable*)error { - UNIMPLEMENTED(); - return StubReturn(); +- (instancetype)initWithFileDescriptor:(int)fileDescriptor closeOnDealloc:(BOOL)flag { + if (self = [super init]) { + _fileDescriptor = fileDescriptor; + _closeOnDealloc = flag; + } + + return self; } /** - @Status Stub - @Notes + @Status Interoperable */ -+ (instancetype)fileHandleForWritingAtPath:(NSString*)path { - UNIMPLEMENTED(); - return StubReturn(); +- (instancetype)initWithFileDescriptor:(int)fileDescriptor { + return [self initWithFileDescriptor:fileDescriptor closeOnDealloc:NO]; } -/** - @Status Stub - @Notes -*/ -+ (instancetype)fileHandleForWritingToURL:(NSURL*)url error:(NSError* _Nullable*)error { - UNIMPLEMENTED(); - return StubReturn(); +- (instancetype)_initWithFileAtPath:(NSString*)file openType:(_NSFileOpenMode)type { + if (file == nil) { + [self release]; + return nil; + } + if (self = [self initWithFileDescriptor:-1 closeOnDealloc:YES]) { + _fileDescriptor = [self _openFile:file openType:type]; + + if (_fileDescriptor == -1) { + TraceError(L"NSFileHandle", L"Unable to open file, errno:%d", errno); + [self release]; + return nil; + } + + if (type == _NSFileOpenModeUpdate) { + [self seekToFileOffset:0]; + } + } + + return self; } -/** - @Status Stub - @Notes -*/ -+ (instancetype)fileHandleForUpdatingAtPath:(NSString*)path { - UNIMPLEMENTED(); - return StubReturn(); +- (int)_openFile:(NSString*)file openType:(_NSFileOpenMode)type { + switch (type) { + case _NSFileOpenModeRead: + return EbrOpenWithPermission((char*)([file UTF8String]), O_RDONLY | _O_BINARY, _SH_DENYWR, _S_IREAD); + case _NSFileOpenModeWrite: + return EbrOpenWithPermission((char*)([file UTF8String]), _O_WRONLY | _O_BINARY | _O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE); + case _NSFileOpenModeUpdate: + return EbrOpenWithPermission((char*)([file UTF8String]), + O_RDWR | _O_CREAT | O_APPEND | _O_BINARY, + _SH_DENYNO, + _S_IREAD | _S_IWRITE); + default: + break; + } + return -1; } /** - @Status Stub - @Notes -*/ -+ (instancetype)fileHandleForUpdatingURL:(NSURL*)url error:(NSError* _Nullable*)error { - UNIMPLEMENTED(); - return StubReturn(); + @Status Caveat + @Notes NSFileHandle only supports file URLs. + */ ++ (instancetype)fileHandleForReadingFromURL:(NSURL*)url error:(NSError* _Nullable*)error { + return [NSFileHandle _fileHandleForURl:url error:error openType:_NSFileOpenModeRead]; } /** - @Status Stub - @Notes + @Status Interoperable */ -+ (NSFileHandle*)fileHandleWithStandardError { - UNIMPLEMENTED(); - return StubReturn(); ++ (instancetype)fileHandleForReadingAtPath:(NSString*)file { + return [[[self alloc] _initWithFileAtPath:file openType:_NSFileOpenModeRead] autorelease]; } /** - @Status Stub - @Notes -*/ -+ (NSFileHandle*)fileHandleWithStandardInput { - UNIMPLEMENTED(); - return StubReturn(); + @Status Caveat + @Notes NSFileHandle only supports file URLs. + */ ++ (instancetype)fileHandleForWritingToURL:(NSURL*)url error:(NSError* _Nullable*)error { + return [NSFileHandle _fileHandleForURl:url error:error openType:_NSFileOpenModeWrite]; } /** - @Status Stub - @Notes + @Status Interoperable */ -+ (NSFileHandle*)fileHandleWithStandardOutput { - UNIMPLEMENTED(); - return StubReturn(); ++ (instancetype)fileHandleForWritingAtPath:(NSString*)file { + return [[[self alloc] _initWithFileAtPath:file openType:_NSFileOpenModeWrite] autorelease]; } /** - @Status Stub - @Notes -*/ -+ (NSFileHandle*)fileHandleWithNullDevice { - UNIMPLEMENTED(); - return StubReturn(); + @Status Caveat + @Notes NSFileHandle only supports file URLs. + */ ++ (instancetype)fileHandleForUpdatingURL:(NSURL*)url error:(NSError* _Nullable*)error { + return [NSFileHandle _fileHandleForURl:url error:error openType:_NSFileOpenModeUpdate]; } -/** - @Status Stub - @Notes -*/ -- (instancetype)initWithFileDescriptor:(int)fileDescriptor { - UNIMPLEMENTED(); - return StubReturn(); ++ (instancetype)_fileHandleForURl:(NSURL*)url error:(NSError* _Nullable*)error openType:(_NSFileOpenMode)type { + if (url == nil) { + return nil; + } + + if (![url isFileURL]) { + UNIMPLEMENTED_WITH_MSG("NSFileHandle only supports file URLs."); + return nil; + } + + NSFileHandle* ret = nil; + switch (type) { + case _NSFileOpenModeRead: + ret = [NSFileHandle fileHandleForReadingAtPath:[url path]]; + break; + case _NSFileOpenModeWrite: + ret = [NSFileHandle fileHandleForWritingAtPath:[url path]]; + break; + case _NSFileOpenModeUpdate: + ret = [NSFileHandle fileHandleForUpdatingAtPath:[url path]]; + break; + default: + break; + } + + if (ret == nil) { + if (error) { + *error = [NSError errorWithDomain:NSFileHandleOperationException code:errno userInfo:nil]; + } + return nil; + } + + return ret; } /** - @Status Stub - @Notes + @Status Interoperable */ -- (instancetype)initWithFileDescriptor:(int)fileDescriptor closeOnDealloc:(BOOL)flag { - UNIMPLEMENTED(); - return StubReturn(); ++ (instancetype)fileHandleForUpdatingAtPath:(NSString*)file { + return [[[self alloc] _initWithFileAtPath:file openType:_NSFileOpenModeUpdate] autorelease]; } /** @Status Stub @Notes */ -- (NSData*)readDataToEndOfFile { ++ (NSFileHandle*)fileHandleWithStandardError { UNIMPLEMENTED(); return StubReturn(); } @@ -145,7 +187,7 @@ - (NSData*)readDataToEndOfFile { @Status Stub @Notes */ -- (NSData*)readDataOfLength:(NSUInteger)length { ++ (NSFileHandle*)fileHandleWithStandardInput { UNIMPLEMENTED(); return StubReturn(); } @@ -154,139 +196,170 @@ - (NSData*)readDataOfLength:(NSUInteger)length { @Status Stub @Notes */ -- (void)writeData:(NSData*)data { ++ (NSFileHandle*)fileHandleWithStandardOutput { UNIMPLEMENTED(); + return StubReturn(); } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)acceptConnectionInBackgroundAndNotify { - UNIMPLEMENTED(); ++ (NSFileHandle*)fileHandleWithNullDevice { + return [[_NSFileHandleNullDevice new] autorelease]; } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)acceptConnectionInBackgroundAndNotifyForModes:(NSArray*)modes { - UNIMPLEMENTED(); +- (void)closeFile { + if (_fileDescriptor >= 0) { + EbrClose(_fileDescriptor); + _fileDescriptor = -1; + } } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)readInBackgroundAndNotify { - UNIMPLEMENTED(); +- (void)seekToFileOffset:(unsigned long long)offset { + if (EbrLseek(_fileDescriptor, offset, SEEK_SET) == -1) { + [NSException raise:NSFileHandleOperationException format:@"Unable to seek to offset %llu.", offset]; + } } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)readInBackgroundAndNotifyForModes:(NSArray*)modes { - UNIMPLEMENTED(); +- (void)truncateFileAtOffset:(unsigned long long)size { + if (EbrTruncate64(_fileDescriptor, size) != 0) { + [NSException raise:NSFileHandleOperationException format:@"Unable to truncate to size %llu.", size]; + } } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)readToEndOfFileInBackgroundAndNotify { - UNIMPLEMENTED(); -} +- (unsigned long long)seekToEndOfFile { + unsigned long long newPos = EbrLseek(_fileDescriptor, 0, SEEK_END); + if (newPos == -1) { + [NSException raise:NSFileHandleOperationException format:@"Unable to seek to end of file."]; + } -/** - @Status Stub - @Notes -*/ -- (void)readToEndOfFileInBackgroundAndNotifyForModes:(NSArray*)modes { - UNIMPLEMENTED(); + return newPos; } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)waitForDataInBackgroundAndNotify { - UNIMPLEMENTED(); +- (unsigned long long)offsetInFile { + return EbrLseek(_fileDescriptor, 0, SEEK_CUR); } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)waitForDataInBackgroundAndNotifyForModes:(NSArray*)modes { - UNIMPLEMENTED(); +- (NSData*)availableData { + return [self readDataToEndOfFile]; } -/** - @Status Stub - @Notes -*/ -- (unsigned long long)seekToEndOfFile { - UNIMPLEMENTED(); - return StubReturn(); +- (int)_readIntoData:(NSMutableData*)data atOffSet:(NSUInteger)offset length:(NSUInteger)len { + int bytesRead = 0; + + // check if we need more space. + if (([data length] - offset) < len) { + // grow the mutable data + [data increaseLengthBy:(len - [data length] + offset)]; + } + + while (bytesRead < len) { + int readByteSize = EbrRead(_fileDescriptor, ((char*)[data mutableBytes] + offset) + bytesRead, len - bytesRead); + if (readByteSize == 0) { + // early eof + break; + } + if (readByteSize < 0) { + [NSException raise:NSFileHandleOperationException format:@"Unable to read the required length of %u. errno:%d", len, errno]; + } + + bytesRead += readByteSize; + } + + // set the new length + data.length = (offset + bytesRead); + return bytesRead; } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)seekToFileOffset:(unsigned long long)offset { - UNIMPLEMENTED(); +- (NSData*)readDataOfLength:(NSUInteger)len { + NSMutableData* resultData = [NSMutableData dataWithLength:len]; + + int readLen = [self _readIntoData:resultData atOffSet:0 length:len]; + if (readLen == 0) { + return [NSData data]; + } + return [[resultData copy] autorelease]; } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)closeFile { - UNIMPLEMENTED(); +- (NSData*)readDataToEndOfFile { + NSMutableData* resultData = [NSMutableData dataWithLength:(1024 * 128)]; + int readLen = -1; + int offset = 0; + while ((readLen = [self _readIntoData:resultData atOffSet:offset length:1024 * 128]) > 0) { + offset += readLen; + } + + if (offset == 0) { + return [NSData data]; + } + + return [[resultData copy] autorelease]; } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)synchronizeFile { - UNIMPLEMENTED(); -} +- (void)writeData:(NSData*)data { + char* bytes = (char*)([data bytes]); + unsigned long bytesLen = [data length]; -/** - @Status Stub - @Notes -*/ -- (void)truncateFileAtOffset:(unsigned long long)offset { - UNIMPLEMENTED(); + while (bytesLen > 0) { + int writtenLen = EbrWrite(_fileDescriptor, bytes, bytesLen); + + if (writtenLen < 0) { + [NSException raise:NSFileHandleOperationException format:@"Unable to write data. errno:", bytesLen]; + } + bytesLen = bytesLen - writtenLen; + } } /** - @Status Stub - @Notes + @Status Interoperable */ -+ (BOOL)supportsSecureCoding { - UNIMPLEMENTED(); - return StubReturn(); +- (int)fileDescriptor { + return _fileDescriptor; } /** - @Status Stub - @Notes + @Status Interoperable */ -- (id)initWithCoder:(NSCoder*)decoder { - UNIMPLEMENTED(); - return StubReturn(); +- (void)synchronizeFile { + if (EbrFflush(EbrFileFromFd(_fileDescriptor)) != 0) { + [NSException raise:NSFileHandleOperationException format:@"Unable to synchronize file."]; + } } /** - @Status Stub - @Notes + @Status Interoperable */ -- (void)encodeWithCoder:(NSCoder*)coder { - UNIMPLEMENTED(); +- (void)dealloc { + if (_closeOnDealloc) { + [self closeFile]; + } + [super dealloc]; } - -@end \ No newline at end of file +@end diff --git a/Frameworks/Foundation/_NSFileHandleNullDevice.mm b/Frameworks/Foundation/_NSFileHandleNullDevice.mm new file mode 100644 index 0000000000..3a553f0f5d --- /dev/null +++ b/Frameworks/Foundation/_NSFileHandleNullDevice.mm @@ -0,0 +1,97 @@ +//****************************************************************************** +// +// Copyright (c) 2016 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** +#import <_NSFileHandleNullDevice.h> +#import + +@implementation _NSFileHandleNullDevice + +/** + @Status Interoperable +*/ +- (NSData*)availableData { + return [NSData data]; +} + +/** + @Status Interoperable +*/ +- (void)seekToFileOffset:(unsigned long long)offset { + // no-op +} + +/** + @Status Interoperable +*/ +- (void)truncateFileAtOffset:(unsigned long long)size { + // no-op +} + +/** + @Status Interoperable +*/ +- (unsigned long long)offsetInFile { + return 0; +} + +/** + @Status Interoperable +*/ +- (unsigned long long)seekToEndOfFile { + return 0; +} + +/** + @Status Interoperable +*/ +- (int)fileDescriptor { + return -1; +} + +/** + @Status Interoperable +*/ +- (void)synchronizeFile { + // no-op +} + +/** + @Status Interoperable +*/ +- (NSData*)readDataOfLength:(NSUInteger)len { + return [NSData data]; +} + +/** + @Status Interoperable +*/ +- (NSData*)readDataToEndOfFile { + return [NSData data]; +} + +/** + @Status Interoperable +*/ +- (void)writeData:(NSData*)data { + // no-op +} + +/** + @Status Interoperable +*/ +- (void)closeFile { + // no-op +} +@end \ No newline at end of file diff --git a/Frameworks/Starboard/PlatformSupport.cpp b/Frameworks/Starboard/PlatformSupport.cpp index 32f4249e17..f38cc213a5 100644 --- a/Frameworks/Starboard/PlatformSupport.cpp +++ b/Frameworks/Starboard/PlatformSupport.cpp @@ -111,6 +111,11 @@ int EbrFile::Seek(long offset, int origin) { return -1; } +int EbrFile::Seek64(__int64 offset, int origin) { + assert(0); + return -1; +} + size_t EbrFile::Tell() { assert(0); return 0; @@ -195,7 +200,7 @@ int EbrFile::Write(const void* src, size_t count) { return 0; } -int EbrFile::Lseek(off_t pos, int whence) { +int EbrFile::Lseek(__int64 pos, int whence) { assert(0); return 0; } @@ -205,6 +210,11 @@ int EbrFile::Truncate(off_t size) { return 0; } +int EbrFile::Truncate64(__int64 size) { + assert(0); + return 0; +} + int EbrFile::Dup() { assert(0); return -1; @@ -255,6 +265,7 @@ class EbrIOFile : public EbrFile { virtual size_t Read(void* dest, size_t elem, size_t count); virtual size_t Write(void* dest, size_t elem, size_t count); virtual int Seek(long offset, int origin); + virtual int Seek64(__int64 offset, int origin); virtual size_t Tell(); virtual int Eof(); virtual int Putc(int c); @@ -273,8 +284,9 @@ class EbrIOFile : public EbrFile { virtual int Stat(struct stat* ret); virtual int Read(void* dest, size_t count); virtual int Write(const void* src, size_t count); - virtual int Lseek(off_t pos, int whence); + virtual int Lseek(__int64 pos, int whence); virtual int Truncate(off_t size); + virtual int Truncate64(__int64 size); virtual int Dup(); }; @@ -469,19 +481,25 @@ EbrFile* EbrFopen(const char* filename, const char* mode) { } // IO funcs + int EbrOpen(const char* file, int mode, int share) { + return EbrOpenWithPermission(file, mode, share, 0); +} + +int EbrOpenWithPermission(const char* file, int mode, int share, int pmode) { if (strcmp(file, "/dev/urandom") == 0) { EbrFileDevRandom* ret = new EbrFileDevRandom(); EbrFile* addedFile = EbrAllocFile(ret); return addedFile->idx; } + bool stop = false; if (stop) { return -1; } int ret = -1; - _sopen_s(&ret, CPathMapper(file), mode, share, 0); + _sopen_s(&ret, CPathMapper(file), mode, share, pmode); if (ret == -1) { return -1; } @@ -542,6 +560,14 @@ int EbrFseek(EbrFile* fp, long offset, int origin) { return fp->Seek(offset, origin); } +int EbrIOFile::Seek64(__int64 offset, int origin) { + return _fseeki64(fp, offset, origin); +} + +int EbrFseek64(EbrFile* fp, __int64 offset, int origin) { + return fp->Seek64(offset, origin); +} + size_t EbrIOFile::Tell() { return ftell(fp); } @@ -727,11 +753,11 @@ int EbrWrite(int fd, const void* src, size_t count) { return _openFiles[fd]->Write(src, count); } -int EbrIOFile::Lseek(off_t pos, int whence) { +int EbrIOFile::Lseek(__int64 pos, int whence) { return _lseeki64(filefd, pos, whence); } -int EbrLseek(int fd, off_t pos, int whence) { +int EbrLseek(int fd, __int64 pos, int whence) { return _openFiles[fd]->Lseek(pos, whence); } @@ -743,6 +769,14 @@ int EbrTruncate(int fd, off_t size) { return _openFiles[fd]->Truncate(size); } +int EbrIOFile::Truncate64(__int64 size) { + return _chsize_s(filefd, size); +} + +int EbrTruncate64(int fd, __int64 size) { + return _openFiles[fd]->Truncate64(size); +} + typedef struct { int fd; int size; diff --git a/Frameworks/include/Platform/EbrPlatform.h b/Frameworks/include/Platform/EbrPlatform.h index cd74a603e4..69e80a30f5 100644 --- a/Frameworks/include/Platform/EbrPlatform.h +++ b/Frameworks/include/Platform/EbrPlatform.h @@ -42,6 +42,7 @@ class SB_EXPORT_CLASS EbrFile { virtual size_t Read(void* dest, size_t elem, size_t count); virtual size_t Write(void* dest, size_t elem, size_t count); virtual int Seek(long offset, int origin); + virtual int Seek64(__int64 offset, int origin); virtual size_t Tell(); virtual int Eof(); virtual int Putc(int c); @@ -60,8 +61,9 @@ class SB_EXPORT_CLASS EbrFile { virtual int Stat(struct stat* ret); virtual int Read(void* dest, size_t count); virtual int Write(const void* src, size_t count); - virtual int Lseek(off_t pos, int whence); + virtual int Lseek(__int64 pos, int whence); virtual int Truncate(off_t size); + virtual int Truncate64(__int64 size); virtual int Dup(); virtual void* Mmap(void* addr, size_t size, uint32_t prot, uint32_t flags, uint32_t offset); @@ -82,6 +84,7 @@ SB_EXPORT int EbrFclose(EbrFile* file); SB_EXPORT size_t EbrFread(void* dest, size_t elem, size_t count, EbrFile* file); SB_EXPORT size_t EbrFwrite(void* dest, size_t elem, size_t count, EbrFile* file); SB_EXPORT int EbrFseek(EbrFile* fp, long offset, int origin); +SB_EXPORT int EbrFseek64(EbrFile* fp, __int64 offset, int origin); SB_EXPORT size_t EbrFtell(EbrFile* fp); SB_EXPORT int EbrFeof(EbrFile* fp); SB_EXPORT int EbrStat(const char* filename, struct stat* ret); @@ -102,13 +105,15 @@ SB_EXPORT int EbrFsetpos(EbrFile* fp, __int64* pos); SB_EXPORT int EbrFgetpos(EbrFile* fp, __int64* pos); SB_EXPORT int EbrOpen(const char* file, int mode, int share); +SB_EXPORT int EbrOpenWithPermission(const char* file, int mode, int share, int pmode); SB_EXPORT int EbrClose(int fd); SB_EXPORT int EbrFd2Host(int fd); SB_EXPORT int EbrFstat(int fd, struct stat* ret); SB_EXPORT int EbrRead(int fd, void* dest, size_t count); SB_EXPORT int EbrWrite(int fd, const void* src, size_t count); -SB_EXPORT int EbrLseek(int fd, off_t pos, int whence); +SB_EXPORT int EbrLseek(int fd, __int64 pos, int whence); SB_EXPORT int EbrTruncate(int fd, off_t size); +SB_EXPORT int EbrTruncate64(int fd, __int64 size); SB_EXPORT int EbrDup(int fd); SB_EXPORT bool EbrRename(const char* path1, const char* path2); diff --git a/Frameworks/include/_NSFileHandleNullDevice.h b/Frameworks/include/_NSFileHandleNullDevice.h new file mode 100644 index 0000000000..a0b8ea0e41 --- /dev/null +++ b/Frameworks/include/_NSFileHandleNullDevice.h @@ -0,0 +1,21 @@ +//****************************************************************************** +// +// Copyright (c) 2016 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** +#pragma once + +#import + +@interface _NSFileHandleNullDevice : NSFileHandle +@end \ No newline at end of file diff --git a/build/Foundation/lib/FoundationLib.vcxproj b/build/Foundation/lib/FoundationLib.vcxproj index 4663d076e9..d6223aa536 100644 --- a/build/Foundation/lib/FoundationLib.vcxproj +++ b/build/Foundation/lib/FoundationLib.vcxproj @@ -51,6 +51,7 @@ + diff --git a/build/Starboard/dll/Starboard.def b/build/Starboard/dll/Starboard.def index e1137fceae..f381cf7e0d 100644 --- a/build/Starboard/dll/Starboard.def +++ b/build/Starboard/dll/Starboard.def @@ -137,6 +137,7 @@ LIBRARY Starboard EbrFread EbrFwrite EbrFseek + EbrFseek64 EbrFtell EbrFeof EbrStat @@ -156,6 +157,7 @@ LIBRARY Starboard EbrFsetpos EbrFgetpos EbrOpen + EbrOpenWithPermission EbrClose EbrFd2Host EbrFstat @@ -163,6 +165,7 @@ LIBRARY Starboard EbrWrite EbrLseek EbrTruncate + EbrTruncate64 EbrDup EbrRename EbrUnlink diff --git a/build/Tests/UnitTests/Foundation/Foundation.UnitTests.vcxproj b/build/Tests/UnitTests/Foundation/Foundation.UnitTests.vcxproj index 7709cd46c8..ffb4fb0cb0 100644 --- a/build/Tests/UnitTests/Foundation/Foundation.UnitTests.vcxproj +++ b/build/Tests/UnitTests/Foundation/Foundation.UnitTests.vcxproj @@ -282,6 +282,7 @@ + @@ -322,6 +323,13 @@ true Text + + + + true + true + Text + diff --git a/include/Foundation/NSFileHandle.h b/include/Foundation/NSFileHandle.h index ac1e424212..bf0b253cfd 100644 --- a/include/Foundation/NSFileHandle.h +++ b/include/Foundation/NSFileHandle.h @@ -34,26 +34,33 @@ FOUNDATION_EXPORT NSString* const NSFileHandleReadCompletionNotification; FOUNDATION_EXPORT NSString* const NSFileHandleReadToEndOfFileCompletionNotification; FOUNDATION_EXPORT_CLASS -@interface NSFileHandle : NSObject -+ (instancetype)fileHandleForReadingAtPath:(NSString*)path STUB_METHOD; -+ (instancetype)fileHandleForReadingFromURL:(NSURL*)url error:(NSError* _Nullable*)error STUB_METHOD; -+ (instancetype)fileHandleForWritingAtPath:(NSString*)path STUB_METHOD; -+ (instancetype)fileHandleForWritingToURL:(NSURL*)url error:(NSError* _Nullable*)error STUB_METHOD; -+ (instancetype)fileHandleForUpdatingAtPath:(NSString*)path STUB_METHOD; -+ (instancetype)fileHandleForUpdatingURL:(NSURL*)url error:(NSError* _Nullable*)error STUB_METHOD; +@interface NSFileHandle : NSObject + +@property (readonly) int fileDescriptor; +@property (readonly, copy) NSData* availableData; +@property (copy, nonnull) void (^readabilityHandler)(NSFileHandle*) STUB_PROPERTY; +@property (copy, nonnull) void (^writeabilityHandler)(NSFileHandle*) STUB_PROPERTY; +@property (readonly) unsigned long long offsetInFile; + ++ (instancetype)fileHandleForReadingAtPath:(NSString*)path; ++ (instancetype)fileHandleForReadingFromURL:(NSURL*)url error:(NSError* _Nullable*)error; ++ (instancetype)fileHandleForWritingAtPath:(NSString*)path; ++ (instancetype)fileHandleForWritingToURL:(NSURL*)url error:(NSError* _Nullable*)error; ++ (instancetype)fileHandleForUpdatingAtPath:(NSString*)path; ++ (instancetype)fileHandleForUpdatingURL:(NSURL*)url error:(NSError* _Nullable*)error; + + (NSFileHandle*)fileHandleWithStandardError STUB_METHOD; + (NSFileHandle*)fileHandleWithStandardInput STUB_METHOD; + (NSFileHandle*)fileHandleWithStandardOutput STUB_METHOD; -+ (NSFileHandle*)fileHandleWithNullDevice STUB_METHOD; -- (instancetype)initWithFileDescriptor:(int)fileDescriptor STUB_METHOD; -- (instancetype)initWithFileDescriptor:(int)fileDescriptor closeOnDealloc:(BOOL)flag STUB_METHOD; -@property (readonly) int fileDescriptor STUB_PROPERTY; -@property (readonly, copy) NSData* availableData STUB_PROPERTY; -- (NSData*)readDataToEndOfFile STUB_METHOD; -- (NSData*)readDataOfLength:(NSUInteger)length STUB_METHOD; -- (void)writeData:(NSData*)data STUB_METHOD; -@property (copy, nonnull) void (^readabilityHandler)(NSFileHandle*) STUB_PROPERTY; -@property (copy, nonnull) void (^writeabilityHandler)(NSFileHandle*) STUB_PROPERTY; ++ (NSFileHandle*)fileHandleWithNullDevice; + +- (instancetype)initWithFileDescriptor:(int)fileDescriptor; +- (instancetype)initWithFileDescriptor:(int)fileDescriptor closeOnDealloc:(BOOL)flag; + +- (NSData*)readDataToEndOfFile; +- (NSData*)readDataOfLength:(NSUInteger)length; +- (void)writeData:(NSData*)data; + - (void)acceptConnectionInBackgroundAndNotify STUB_METHOD; - (void)acceptConnectionInBackgroundAndNotifyForModes:(NSArray*)modes STUB_METHOD; - (void)readInBackgroundAndNotify STUB_METHOD; @@ -62,10 +69,10 @@ FOUNDATION_EXPORT_CLASS - (void)readToEndOfFileInBackgroundAndNotifyForModes:(NSArray*)modes STUB_METHOD; - (void)waitForDataInBackgroundAndNotify STUB_METHOD; - (void)waitForDataInBackgroundAndNotifyForModes:(NSArray*)modes STUB_METHOD; -@property (readonly) unsigned long long offsetInFile STUB_PROPERTY; -- (unsigned long long)seekToEndOfFile STUB_METHOD; -- (void)seekToFileOffset:(unsigned long long)offset STUB_METHOD; -- (void)closeFile STUB_METHOD; -- (void)synchronizeFile STUB_METHOD; -- (void)truncateFileAtOffset:(unsigned long long)offset STUB_METHOD; + +- (unsigned long long)seekToEndOfFile; +- (void)seekToFileOffset:(unsigned long long)offset; +- (void)closeFile; +- (void)synchronizeFile; +- (void)truncateFileAtOffset:(unsigned long long)offset; @end diff --git a/tests/unittests/Foundation/NSFileHandleTestFile.txt b/tests/unittests/Foundation/NSFileHandleTestFile.txt new file mode 100644 index 0000000000..9764144a4f --- /dev/null +++ b/tests/unittests/Foundation/NSFileHandleTestFile.txt @@ -0,0 +1 @@ +The Quick Brown Fox. \ No newline at end of file diff --git a/tests/unittests/Foundation/NSFileHandleTests.mm b/tests/unittests/Foundation/NSFileHandleTests.mm new file mode 100644 index 0000000000..5f9b321f86 --- /dev/null +++ b/tests/unittests/Foundation/NSFileHandleTests.mm @@ -0,0 +1,329 @@ +//****************************************************************************** +// +// Copyright (c) 2016 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#import "Starboard.h" +#import +#import + +#import + +NSString* getPathToFile(char const* filePath) { + char fullPath[_MAX_PATH]; + int len = GetModuleFileNameA(NULL, fullPath, _MAX_PATH); + char* ptrToLastEntry = strrchr(fullPath, '\\'); + int lengthOfLastEntry = strlen(ptrToLastEntry); + strncpy_s(ptrToLastEntry, _MAX_PATH - (len - lengthOfLastEntry), filePath, strlen(filePath) + 1); + + return [NSString stringWithFormat:@"%s", fullPath]; +} + +void createFileWithContentAndVerify(char const* filePath, NSString* content) { + NSString* fullPath = getPathToFile(filePath); + NSFileHandle* fh = [NSFileHandle fileHandleForWritingAtPath:fullPath]; + ASSERT_TRUE(fh != nil); + + if (content) { + NSData* data = [content dataUsingEncoding:NSUTF8StringEncoding]; + [fh writeData:data]; + } + + [fh closeFile]; + + // verify file exists. + ASSERT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:fullPath]); +} + +void deleteFile(char const* filePath) { + NSError* error; + ASSERT_TRUE_MSG([[NSFileManager defaultManager] removeItemAtPath:getPathToFile(filePath) error:&error], + "FAILED:Unable to delete the test file."); + ASSERT_OBJCEQ(error, nil); +} + +TEST(NSFileHandle, Init) { + ASSERT_TRUE_MSG([[[NSFileHandle alloc] init] autorelease] != nil, "FAILED: alloc/init failed."); +} + +TEST(NSFileHandle, ReadFile) { + NSString* content = @"The Quick Brown Fox."; + char const* fileName = "\\NSFileHandleTestFile.txt"; + createFileWithContentAndVerify(fileName, content); + + NSString* fullPath = getPathToFile(fileName); + NSFileHandle* fh = [NSFileHandle fileHandleForReadingAtPath:fullPath]; + ASSERT_TRUE(fh != nil); + + NSData* fileData = [fh readDataToEndOfFile]; + ASSERT_TRUE_MSG(fileData != nil, "FAILED: reading the entire file failed."); + + NSString* str = [[[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding] autorelease]; + ASSERT_OBJCEQ_MSG(str, content, "FAILED: Unable to read the file content."); + + [fh closeFile]; + + deleteFile(fileName); +} + +TEST(NSFileHandle, UpdateAndSeeks) { + char const* fileName = "\\FileToDeleteUpdate.txt"; + createFileWithContentAndVerify(fileName, @"0001"); + NSString* fullPath = getPathToFile(fileName); + NSFileHandle* fh = [NSFileHandle fileHandleForUpdatingAtPath:fullPath]; + ASSERT_TRUE(fh != nil); + + unsigned long long cursor = [fh seekToEndOfFile]; + + ASSERT_GT(cursor, 0); + + NSString* testStr = @"teststring"; + NSData* data = [testStr dataUsingEncoding:NSUTF8StringEncoding]; + + [fh writeData:data]; + + ASSERT_GT([fh offsetInFile], cursor); + + [fh closeFile]; + + deleteFile(fileName); +} + +TEST(NSFileHandle, Offsets) { + char const* fileName = "\\FileToDeleteOffsets.txt"; + createFileWithContentAndVerify(fileName, @"Hello World, Hello Hello Hello Hello."); + + NSFileHandle* fh = [NSFileHandle fileHandleForReadingAtPath:getPathToFile(fileName)]; + ASSERT_TRUE(fh != nil); + + ASSERT_EQ([fh offsetInFile], 0); + + // find the full offset + unsigned long long endCursor = [fh seekToEndOfFile]; + [fh seekToFileOffset:0]; + + [fh seekToFileOffset:5]; + + ASSERT_EQ([fh offsetInFile], 5); + + ASSERT_GT(endCursor, [fh offsetInFile]); + + [fh seekToFileOffset:(endCursor - 5)]; + ASSERT_EQ([fh offsetInFile], (endCursor - 5)); + + [fh closeFile]; + deleteFile(fileName); +} + +TEST(NSFileHandle, WriteToNonExistentFileAndRead) { + char const* fileName = "\\FileToDelete.txt"; + NSString* testStr = @"testString"; + createFileWithContentAndVerify(fileName, testStr); + + NSFileHandle* fh = [NSFileHandle fileHandleForReadingAtPath:getPathToFile(fileName)]; + ASSERT_TRUE(fh != nil); + + NSData* fileData = [fh readDataToEndOfFile]; + ASSERT_TRUE_MSG(fileData != nil, "FAILED: reading the entire file failed."); + + NSString* str = [[[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding] autorelease]; + ASSERT_OBJCEQ_MSG(str, testStr, "FAILED: Unable to read the file content."); + + [fh closeFile]; + + // Delete the file + deleteFile(fileName); +} + +TEST(NSFileHandle, TruncateFileAtOffset) { + char const* fileName = "\\FileToDeleteTruncateFileAtOffset.txt"; + NSString* testString = @"testString001"; + NSString* content = @" Hello."; + createFileWithContentAndVerify(fileName, testString); + + NSFileHandle* fh = [NSFileHandle fileHandleForUpdatingAtPath:getPathToFile(fileName)]; + ASSERT_TRUE(fh != nil); + + unsigned long long endCursor = [fh seekToEndOfFile]; + + NSData* data = [content dataUsingEncoding:NSUTF8StringEncoding]; + [fh writeData:data]; + + [fh closeFile]; + + // Verify Update did happen. + fh = [NSFileHandle fileHandleForReadingAtPath:getPathToFile(fileName)]; + NSData* fileData = [fh readDataToEndOfFile]; + ASSERT_TRUE_MSG(fileData != nil, "FAILED: reading the entire file failed."); + + NSString* str = [[[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding] autorelease]; + NSString* finalData = [NSString stringWithFormat:@"%@%@", testString, content]; + ASSERT_OBJCEQ_MSG(str, finalData, "FAILED: Unable to read the file content."); + + [fh closeFile]; + + // Truncate to the original file bytes + + fh = [NSFileHandle fileHandleForUpdatingAtPath:getPathToFile(fileName)]; + [fh truncateFileAtOffset:endCursor]; + [fh closeFile]; + + // Verify turncation. + + fh = [NSFileHandle fileHandleForReadingAtPath:getPathToFile(fileName)]; + fileData = [fh readDataToEndOfFile]; + ASSERT_TRUE_MSG(fileData != nil, "FAILED: reading the entire file failed."); + + str = [[[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding] autorelease]; + ASSERT_OBJCEQ_MSG(str, testString, "FAILED: Unable to read the file content."); + + [fh closeFile]; + + // Delete the file + deleteFile(fileName); +} + +TEST(NSFileHandle, FileHandleWithNullDevice) { + NSFileHandle* fh = [NSFileHandle fileHandleWithNullDevice]; + ASSERT_TRUE(fh != nil); + + // no-op + [fh writeData:nil]; + ASSERT_EQ([fh seekToEndOfFile], 0); + ASSERT_EQ([fh offsetInFile], 0); + ASSERT_EQ([fh fileDescriptor], -1); + + NSData* data = [NSData data]; + + ASSERT_OBJCEQ(data, [fh readDataOfLength:1000]); + ASSERT_OBJCEQ(data, [fh readDataToEndOfFile]); + ASSERT_OBJCEQ(data, [fh availableData]); + + [fh closeFile]; +} + +TEST(NSFileHandle, ReadDataOfLength) { + NSString* content = @"The Quick Brown Fox."; + char const* fileName = "\\NSFileHandleTestFile.txt"; + createFileWithContentAndVerify(fileName, content); + + NSString* fullPath = getPathToFile(fileName); + NSFileHandle* fh = [NSFileHandle fileHandleForReadingAtPath:fullPath]; + ASSERT_TRUE(fh != nil); + + NSData* fileData = [fh readDataOfLength:9]; + ASSERT_TRUE(fileData != nil); + + NSString* str = [[[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding] autorelease]; + ASSERT_OBJCEQ_MSG(str, @"The Quick", "FAILED: Unable to read the file content."); + + // Try to read more than the max bytes. + fileData = [fh readDataOfLength:30]; + ASSERT_TRUE_MSG(fileData != nil, "FAILED: reading the file failed."); + + str = [[[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding] autorelease]; + ASSERT_OBJCEQ_MSG(str, @" Brown Fox.", "FAILED: Unable to read the file content."); + + // Try to read again. + fileData = [fh readDataOfLength:30000]; + ASSERT_TRUE_MSG(fileData != nil, "FAILED: reading the file failed."); + ASSERT_OBJCEQ(fileData, [NSData data]); + + [fh closeFile]; + deleteFile(fileName); +} + +TEST(NSFileHandle, UpdatingURL) { + char const* fileName = "\\FileToDeleteUpdateUrl.txt"; + createFileWithContentAndVerify(fileName, @"0001"); + NSString* fullPath = getPathToFile(fileName); + NSError* error; + NSFileHandle* fh = [NSFileHandle fileHandleForUpdatingURL:[NSURL fileURLWithPath:fullPath] error:&error]; + ASSERT_TRUE(fh != nil); + + unsigned long long cursor = [fh seekToEndOfFile]; + + ASSERT_GT(cursor, 0); + + NSString* testStr = @"teststring"; + NSData* data = [testStr dataUsingEncoding:NSUTF8StringEncoding]; + + [fh writeData:data]; + + ASSERT_GT([fh offsetInFile], cursor); + + [fh closeFile]; + + deleteFile(fileName); +} + +TEST(NSFileHandle, ReadingFromURL) { + NSString* content = @"The Quick Brown Fox."; + char const* fileName = "\\NSFileHandleTestFile.txt"; + createFileWithContentAndVerify(fileName, content); + + NSString* fullPath = getPathToFile(fileName); + NSError* error; + NSFileHandle* fh = [NSFileHandle fileHandleForReadingFromURL:[NSURL fileURLWithPath:fullPath] error:&error]; + ASSERT_TRUE(fh != nil); + + NSData* fileData = [fh readDataToEndOfFile]; + ASSERT_TRUE_MSG(fileData != nil, "FAILED: reading the entire file failed."); + + NSString* str = [[[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding] autorelease]; + ASSERT_OBJCEQ_MSG(str, @"The Quick Brown Fox.", "FAILED: Unable to read the file content."); + + [fh closeFile]; + deleteFile(fileName); +} + +TEST(NSFileHandle, WritingAtPath) { + char const* fileName = "\\FileToDeleteWritingAtPath.txt"; + NSString* testStr = @"The Brown Fox.!"; + + NSString* fullPath = getPathToFile(fileName); + NSError* error; + NSFileHandle* fh = [NSFileHandle fileHandleForWritingToURL:[NSURL fileURLWithPath:fullPath] error:&error]; + ASSERT_TRUE(fh != nil); + + NSData* data = [testStr dataUsingEncoding:NSUTF8StringEncoding]; + [fh writeData:data]; + + [fh closeFile]; + + // verify file exists. + ASSERT_TRUE([[NSFileManager defaultManager] fileExistsAtPath:fullPath]); + + fh = [NSFileHandle fileHandleForReadingAtPath:getPathToFile(fileName)]; + ASSERT_TRUE(fh != nil); + + NSData* fileData = [fh readDataToEndOfFile]; + ASSERT_TRUE_MSG(fileData != nil, "FAILED: reading the entire file failed."); + + NSString* str = [[[NSString alloc] initWithData:fileData encoding:NSUTF8StringEncoding] autorelease]; + ASSERT_OBJCEQ_MSG(str, testStr, "FAILED: Unable to read the file content."); + + [fh closeFile]; + + // Delete the file + deleteFile(fileName); +} + +TEST(NSFileHandle, ReadingNonExistentFile) { + NSString* fullPath = getPathToFile("\\nonexisting.txt"); + NSError* error; + NSFileHandle* fh = [NSFileHandle fileHandleForReadingFromURL:[NSURL fileURLWithPath:fullPath] error:&error]; + ASSERT_TRUE(fh == nil); + ASSERT_TRUE(error != nil); +} From ebfb21024564849a16ca8f28be5d9eded634958c Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Thu, 28 Apr 2016 11:37:19 -0700 Subject: [PATCH 15/31] fix two warnings caused by recent check-in --- Frameworks/UIKit/UITextField.mm | 6 +++--- Frameworks/UIKit/XamlUtilities.h | 2 +- include/UIKit/UITextField.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Frameworks/UIKit/UITextField.mm b/Frameworks/UIKit/UITextField.mm index 21bb823317..af070a6dff 100644 --- a/Frameworks/UIKit/UITextField.mm +++ b/Frameworks/UIKit/UITextField.mm @@ -186,12 +186,12 @@ - (NSDictionary*)defaultTextAttributes { } /** - @Status Stub + @Status Caveat + @Notes fonts can be set, but will be ignored for rendering, instead default font will be used. */ - (void)setFont:(UIFont*)font { _font = font; - UNIMPLEMENTED(); - // TODO: need map UIFont with fontFamily/FontSize/FontWeight/FontStyle on target + // TODO 7374333: need map UIFont with fontFamily/FontSize/FontWeight/FontStyle on target } /** diff --git a/Frameworks/UIKit/XamlUtilities.h b/Frameworks/UIKit/XamlUtilities.h index abb56ddefb..f24280583e 100644 --- a/Frameworks/UIKit/XamlUtilities.h +++ b/Frameworks/UIKit/XamlUtilities.h @@ -17,7 +17,7 @@ #import #import -@interface XamlUtilities +@interface XamlUtilities : NSObject // convert UIColor to Color on windows + (WUColor*)convertUIColorToWUColor:(UIColor*)uiColor; diff --git a/include/UIKit/UITextField.h b/include/UIKit/UITextField.h index 0a04c4a0af..a71e2eaa0d 100644 --- a/include/UIKit/UITextField.h +++ b/include/UIKit/UITextField.h @@ -71,7 +71,7 @@ UIKIT_EXPORT_CLASS @property (nonatomic, copy) NSString* placeholder; @property (nonatomic, copy) NSAttributedString* attributedPlaceholder STUB_PROPERTY; @property (nonatomic, copy) NSDictionary* defaultTextAttributes STUB_PROPERTY; -@property (nonatomic, strong) UIFont* font STUB_PROPERTY; +@property (nonatomic, strong) UIFont* font; @property (nonatomic, strong) UIColor* textColor; @property (nonatomic) NSTextAlignment textAlignment; @property (nonatomic, copy) NSDictionary* typingAttributes STUB_PROPERTY; From b2897794187522c468d5057f1a707d17ab8304de Mon Sep 17 00:00:00 2001 From: jackgao Date: Thu, 28 Apr 2016 08:25:51 +0800 Subject: [PATCH 16/31] Implement alertAction and alertBody properties in UILocalNotification class --- Frameworks/UIKit/UILocalNotification.mm | 12 ++++-------- include/UIKit/UILocalNotification.h | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/Frameworks/UIKit/UILocalNotification.mm b/Frameworks/UIKit/UILocalNotification.mm index d9070a776f..8f48cd51f4 100644 --- a/Frameworks/UIKit/UILocalNotification.mm +++ b/Frameworks/UIKit/UILocalNotification.mm @@ -56,10 +56,9 @@ - (void)setFireDate:(NSDate*)fireDate { } /** - @Status Stub + @Status Interoperable */ - (void)setAlertBody:(NSString*)alertBody { - UNIMPLEMENTED(); _alertBody.attach([alertBody copy]); } @@ -88,10 +87,9 @@ - (void)setApplicationIconBadgeNumber:(NSInteger)badgeNumber { } /** - @Status Stub + @Status Interoperable */ - (void)setAlertAction:(NSString*)alertAction { - UNIMPLEMENTED(); _alertAction.attach([alertAction copy]); } @@ -128,10 +126,9 @@ - (NSDate*)fireDate { } /** - @Status Stub + @Status Interoperable */ - (NSString*)alertBody { - UNIMPLEMENTED(); return [[_alertBody copy] autorelease]; } @@ -160,10 +157,9 @@ - (NSInteger) applicationIconBadgeNumber { } /** - @Status Stub + @Status Interoperable */ - (NSString*)alertAction { - UNIMPLEMENTED(); return [[_alertAction copy] autorelease]; } diff --git a/include/UIKit/UILocalNotification.h b/include/UIKit/UILocalNotification.h index b4464ece17..cf46e1b496 100644 --- a/include/UIKit/UILocalNotification.h +++ b/include/UIKit/UILocalNotification.h @@ -28,11 +28,11 @@ UIKIT_EXPORT_CLASS @interface UILocalNotification : NSObject @property (nonatomic, copy) NSDate* fireDate STUB_PROPERTY; -@property (nonatomic, copy) NSString* alertBody STUB_PROPERTY; +@property (nonatomic, copy) NSString* alertBody; @property (nonatomic, copy) NSTimeZone* timeZone STUB_PROPERTY; @property (nonatomic, copy) NSString* soundName STUB_PROPERTY; @property (nonatomic) NSInteger applicationIconBadgeNumber STUB_PROPERTY; -@property (nonatomic, copy) NSString* alertAction STUB_PROPERTY; +@property (nonatomic, copy) NSString* alertAction; @property (nonatomic) NSCalendarUnit repeatInterval STUB_PROPERTY; @property (nonatomic, copy) NSDictionary* userInfo STUB_PROPERTY; @property (nonatomic, copy) NSString* category STUB_PROPERTY; From 5e24018e5374bb9781a31335675cada478248257 Mon Sep 17 00:00:00 2001 From: Muktesh Khole Date: Thu, 28 Apr 2016 17:19:30 -0700 Subject: [PATCH 17/31] Create module cache in intermediate directory instead of project directory --- msvc/sbclang.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msvc/sbclang.props b/msvc/sbclang.props index 88f75dd6c0..5258909cfe 100644 --- a/msvc/sbclang.props +++ b/msvc/sbclang.props @@ -37,7 +37,7 @@ $(IntDir) false false - $(ProjectDir)ModuleCache + $(IntDir)ModuleCache Disabled MultiThreadedDLL $(TLogLocation)clang.read.1.tlog From fe033f21733de45e93d06dd62048a3a3db708cf3 Mon Sep 17 00:00:00 2001 From: Muktesh Khole Date: Thu, 28 Apr 2016 14:40:05 -0700 Subject: [PATCH 18/31] Added dependencies for the new support library (RTObjCInterop) for projections. --- Frameworks/AVFoundation/AVAudioPlayer.mm | 6 ++--- Frameworks/Foundation/NSData.mm | 4 ++-- .../Foundation/NSURLProtocol_WinHTTP.mm | 4 ++-- .../StarboardXaml/CompositorInterface.mm | 2 +- .../SCNetworkReachability.mm | 2 +- .../Starboard/Starboard.UnitTests.vcxproj | 8 +++---- .../UnitTests/UIKit/UIKit.UnitTests.vcxproj | 8 +++---- build/UIKit/dll/UIKit.vcxproj | 8 +++---- .../Universal Windows/ARM/ObjCUWP.dll | 4 ++-- .../Universal Windows/ARM/ObjCUWP.lib | 4 ++-- .../Universal Windows/ARM/ObjCUWP.pdb | 4 ++-- .../Universal Windows/ARM/RTObjCInterop.dll | 3 +++ .../Universal Windows/ARM/RTObjCInterop.lib | 3 +++ .../Universal Windows/ARM/RTObjCInterop.pdb | 3 +++ .../Universal Windows/x86/ObjCUWP.dll | 4 ++-- .../Universal Windows/x86/ObjCUWP.lib | 4 ++-- .../Universal Windows/x86/ObjCUWP.pdb | 4 ++-- .../Universal Windows/x86/RTObjCInterop.dll | 3 +++ .../Universal Windows/x86/RTObjCInterop.lib | 3 +++ .../Universal Windows/x86/RTObjCInterop.pdb | 3 +++ .../Universal Windows/UWP/InteropBase.h | 23 ++++++++++++++----- msvc/sbclang.props | 2 +- 22 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 deps/prebuilt/Universal Windows/ARM/RTObjCInterop.dll create mode 100644 deps/prebuilt/Universal Windows/ARM/RTObjCInterop.lib create mode 100644 deps/prebuilt/Universal Windows/ARM/RTObjCInterop.pdb create mode 100644 deps/prebuilt/Universal Windows/x86/RTObjCInterop.dll create mode 100644 deps/prebuilt/Universal Windows/x86/RTObjCInterop.lib create mode 100644 deps/prebuilt/Universal Windows/x86/RTObjCInterop.pdb diff --git a/Frameworks/AVFoundation/AVAudioPlayer.mm b/Frameworks/AVFoundation/AVAudioPlayer.mm index 9bcf1ed405..78eccbb578 100644 --- a/Frameworks/AVFoundation/AVAudioPlayer.mm +++ b/Frameworks/AVFoundation/AVAudioPlayer.mm @@ -25,10 +25,10 @@ #include -#import +#include #import #import -#import +#include #import "AssertARCEnabled.h" // 100 nanoseconds per tick @@ -184,7 +184,7 @@ - (instancetype)initWithData:(NSData *)data fileTypeHint:(NSString*)utiString er // TODO: subclassed IAsyncOperations don't get generated correctly in ObjCUWP yet, when that happens it'll // open up StoreAsync. - IDataWriter* writer = (__bridge IDataWriter*)[rw internalObject]; + IDataWriter* writer = (IDataWriter*)[rw comObj].Get(); ComPtr> comp; writer->WriteBuffer(buffer.Get()); writer->StoreAsync(&comp); diff --git a/Frameworks/Foundation/NSData.mm b/Frameworks/Foundation/NSData.mm index 196080ff72..02e15b1991 100644 --- a/Frameworks/Foundation/NSData.mm +++ b/Frameworks/Foundation/NSData.mm @@ -25,13 +25,13 @@ #import "Foundation/NSValue.h" #import #import -#import +#include #import "ErrorHandling.h" #import "RawBuffer.h" #import #import #import -#import +#include #import #import #import diff --git a/Frameworks/Foundation/NSURLProtocol_WinHTTP.mm b/Frameworks/Foundation/NSURLProtocol_WinHTTP.mm index 11913aca78..de5dcab415 100644 --- a/Frameworks/Foundation/NSURLProtocol_WinHTTP.mm +++ b/Frameworks/Foundation/NSURLProtocol_WinHTTP.mm @@ -17,7 +17,7 @@ #import #import -#import +#include #import #import #import @@ -25,7 +25,7 @@ #import #import #import -#import +#include #import #import "Starboard/SmartTypes.h" diff --git a/Frameworks/StarboardXaml/CompositorInterface.mm b/Frameworks/StarboardXaml/CompositorInterface.mm index 203856614c..7de02e056d 100644 --- a/Frameworks/StarboardXaml/CompositorInterface.mm +++ b/Frameworks/StarboardXaml/CompositorInterface.mm @@ -1725,7 +1725,7 @@ void DecrementCounter(const char* name) override { } DisplayTexture* CreateDisplayTextureForElement(id xamlElement) override { - GenericControlXaml* genericControlTexture = new GenericControlXaml((IUnknown*)[(RTObject*)xamlElement internalObject]); + GenericControlXaml* genericControlTexture = new GenericControlXaml([(RTObject*)xamlElement comObj].Get()); return genericControlTexture; } diff --git a/Frameworks/SystemConfiguration/SCNetworkReachability.mm b/Frameworks/SystemConfiguration/SCNetworkReachability.mm index 521a89f0dd..7e64223bdc 100644 --- a/Frameworks/SystemConfiguration/SCNetworkReachability.mm +++ b/Frameworks/SystemConfiguration/SCNetworkReachability.mm @@ -134,7 +134,7 @@ + (void)_testAllReachabilityObjects { + (void)_checkGlobalReachability { WNCConnectionProfile* internetConnectionProfile = [WNCNetworkInformation getInternetConnectionProfile]; - if ([internetConnectionProfile internalObject] != nil && + if (internetConnectionProfile && [internetConnectionProfile getNetworkConnectivityLevel] == WNCNetworkConnectivityLevelInternetAccess) { SCNetworkReachabilityFlags newFlags = kSCNetworkReachabilityFlagsReachable; diff --git a/build/Tests/UnitTests/Starboard/Starboard.UnitTests.vcxproj b/build/Tests/UnitTests/Starboard/Starboard.UnitTests.vcxproj index 51af8b7f16..3478e63d83 100644 --- a/build/Tests/UnitTests/Starboard/Starboard.UnitTests.vcxproj +++ b/build/Tests/UnitTests/Starboard/Starboard.UnitTests.vcxproj @@ -132,7 +132,7 @@ Console true - ObjCUWP.lib;mincore.lib;%(AdditionalDependencies) + RTObjCInterop.lib;ObjCUWP.lib;mincore.lib;%(AdditionalDependencies) false @@ -154,7 +154,7 @@ Console true - ObjCUWP.lib;mincore.lib;%(AdditionalDependencies) + RTObjCInterop.lib;ObjCUWP.lib;mincore.lib;%(AdditionalDependencies) false @@ -180,7 +180,7 @@ true true true - ObjCUWP.lib;mincore.lib;%(AdditionalDependencies) + RTObjCInterop.lib;ObjCUWP.lib;mincore.lib;%(AdditionalDependencies) false @@ -206,7 +206,7 @@ true true true - ObjCUWP.lib;mincore.lib;%(AdditionalDependencies) + RTObjCInterop.lib;ObjCUWP.lib;mincore.lib;%(AdditionalDependencies) false diff --git a/build/Tests/UnitTests/UIKit/UIKit.UnitTests.vcxproj b/build/Tests/UnitTests/UIKit/UIKit.UnitTests.vcxproj index cad630eb61..fa85212ffc 100644 --- a/build/Tests/UnitTests/UIKit/UIKit.UnitTests.vcxproj +++ b/build/Tests/UnitTests/UIKit/UIKit.UnitTests.vcxproj @@ -146,7 +146,7 @@ Console true - mincore.lib;freetype.lib;libxml2.lib;Windowscodecs.lib;ObjCUWP.lib;libdispatch.lib;%(AdditionalDependencies) + RTObjCInterop.lib;mincore.lib;freetype.lib;libxml2.lib;Windowscodecs.lib;ObjCUWP.lib;libdispatch.lib;%(AdditionalDependencies) false @@ -169,7 +169,7 @@ Console true - mincore.lib;freetype.lib;libxml2.lib;Windowscodecs.lib;ObjCUWP.lib;libdispatch.lib;%(AdditionalDependencies) + RTObjCInterop.lib;mincore.lib;freetype.lib;libxml2.lib;Windowscodecs.lib;ObjCUWP.lib;libdispatch.lib;%(AdditionalDependencies) false @@ -196,7 +196,7 @@ true true true - mincore.lib;freetype.lib;libxml2.lib;Windowscodecs.lib;ObjCUWP.lib;libdispatch.lib;%(AdditionalDependencies) + RTObjCInterop.lib;mincore.lib;freetype.lib;libxml2.lib;Windowscodecs.lib;ObjCUWP.lib;libdispatch.lib;%(AdditionalDependencies) false @@ -223,7 +223,7 @@ true true true - mincore.lib;freetype.lib;libxml2.lib;Windowscodecs.lib;ObjCUWP.lib;libdispatch.lib;%(AdditionalDependencies) + RTObjCInterop.lib;mincore.lib;freetype.lib;libxml2.lib;Windowscodecs.lib;ObjCUWP.lib;libdispatch.lib;%(AdditionalDependencies) false diff --git a/build/UIKit/dll/UIKit.vcxproj b/build/UIKit/dll/UIKit.vcxproj index ab04f0188a..c890c2e76f 100644 --- a/build/UIKit/dll/UIKit.vcxproj +++ b/build/UIKit/dll/UIKit.vcxproj @@ -70,7 +70,7 @@ UIKit.def - freetype.lib;objcuwp.lib;libdispatch.lib;Windowscodecs.lib;libxml2.lib;%(AdditionalDependencies) + RTObjCInterop.lib;freetype.lib;objcuwp.lib;libdispatch.lib;Windowscodecs.lib;libxml2.lib;%(AdditionalDependencies) $(StarboardBasePath)\deps\prebuilt\include;$(StarboardBasePath)\Frameworks\include @@ -83,7 +83,7 @@ UIKit.def - freetype.lib;objcuwp.lib;libdispatch.lib;Windowscodecs.lib;libxml2.lib;%(AdditionalDependencies) + RTObjCInterop.lib;freetype.lib;objcuwp.lib;libdispatch.lib;Windowscodecs.lib;libxml2.lib;%(AdditionalDependencies) $(StarboardBasePath)\deps\prebuilt\include;$(StarboardBasePath)\Frameworks\include @@ -96,7 +96,7 @@ UIKit.def - freetype.lib;objcuwp.lib;libdispatch.lib;Windowscodecs.lib;libxml2.lib;%(AdditionalDependencies) + RTObjCInterop.lib;freetype.lib;objcuwp.lib;libdispatch.lib;Windowscodecs.lib;libxml2.lib;%(AdditionalDependencies) $(StarboardBasePath)\deps\prebuilt\include;$(StarboardBasePath)\Frameworks\include @@ -109,7 +109,7 @@ UIKit.def - freetype.lib;objcuwp.lib;libdispatch.lib;Windowscodecs.lib;libxml2.lib;%(AdditionalDependencies) + RTObjCInterop.lib;freetype.lib;objcuwp.lib;libdispatch.lib;Windowscodecs.lib;libxml2.lib;%(AdditionalDependencies) $(StarboardBasePath)\deps\prebuilt\include;$(StarboardBasePath)\Frameworks\include diff --git a/deps/prebuilt/Universal Windows/ARM/ObjCUWP.dll b/deps/prebuilt/Universal Windows/ARM/ObjCUWP.dll index 87233a14b5..7069623c8c 100644 --- a/deps/prebuilt/Universal Windows/ARM/ObjCUWP.dll +++ b/deps/prebuilt/Universal Windows/ARM/ObjCUWP.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9587df5fafffe996678953f539095015f96a6aa4c21ef6fdc17ce0ef453eb230 -size 34056704 +oid sha256:b63e85d7b4d62b49ad0d5a665e5f7f59f3769b3199b373becdd065e6282f8730 +size 34962944 diff --git a/deps/prebuilt/Universal Windows/ARM/ObjCUWP.lib b/deps/prebuilt/Universal Windows/ARM/ObjCUWP.lib index 695dab2148..edb5843bb2 100644 --- a/deps/prebuilt/Universal Windows/ARM/ObjCUWP.lib +++ b/deps/prebuilt/Universal Windows/ARM/ObjCUWP.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0c5c041e2f3fd0e8fdb1c984acbcae0bfd50ddb572f19cc9afa3e8492bf08d1 -size 1409006 +oid sha256:5fba28c92161cadf720b5d9de0d30b97e60a8816356aedaf8daec336ba21d541 +size 1408370 diff --git a/deps/prebuilt/Universal Windows/ARM/ObjCUWP.pdb b/deps/prebuilt/Universal Windows/ARM/ObjCUWP.pdb index d2a52b7bd1..c54e85b094 100644 --- a/deps/prebuilt/Universal Windows/ARM/ObjCUWP.pdb +++ b/deps/prebuilt/Universal Windows/ARM/ObjCUWP.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:41a5c9fee13c6db13835acbf56821df9cfcab5cae8dcd86656c491b5ed678a6f -size 109850624 +oid sha256:b4ce7cb6019ef504d6ecab0553c3b254df5a1ddef88662f3132d0e98b118061e +size 134877184 diff --git a/deps/prebuilt/Universal Windows/ARM/RTObjCInterop.dll b/deps/prebuilt/Universal Windows/ARM/RTObjCInterop.dll new file mode 100644 index 0000000000..b4fdd13205 --- /dev/null +++ b/deps/prebuilt/Universal Windows/ARM/RTObjCInterop.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1239251a652a96f0417ab57ea68c5facdfdf82b6c335770e7b466d55c4e2ddec +size 164864 diff --git a/deps/prebuilt/Universal Windows/ARM/RTObjCInterop.lib b/deps/prebuilt/Universal Windows/ARM/RTObjCInterop.lib new file mode 100644 index 0000000000..5ae9837184 --- /dev/null +++ b/deps/prebuilt/Universal Windows/ARM/RTObjCInterop.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16de0dd3e12ac085d873db792806deaf06f9ad154d10277505c31a85e0b052eb +size 9038 diff --git a/deps/prebuilt/Universal Windows/ARM/RTObjCInterop.pdb b/deps/prebuilt/Universal Windows/ARM/RTObjCInterop.pdb new file mode 100644 index 0000000000..bbb227672e --- /dev/null +++ b/deps/prebuilt/Universal Windows/ARM/RTObjCInterop.pdb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b31ecbab5328c2b758f980157dca368191eb916edc71d1d47e2efee9708bbc3a +size 1036288 diff --git a/deps/prebuilt/Universal Windows/x86/ObjCUWP.dll b/deps/prebuilt/Universal Windows/x86/ObjCUWP.dll index 34cfe0b55d..5a7a659a34 100644 --- a/deps/prebuilt/Universal Windows/x86/ObjCUWP.dll +++ b/deps/prebuilt/Universal Windows/x86/ObjCUWP.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a1db0a71ef008e8ff782578d88169fa55f037325548b8971cd4f4d6832237d6 -size 32504320 +oid sha256:237033b01edf77b94cde05383c73e0f0eef0f17f08ffdf3006068ac9ae460d6e +size 33174016 diff --git a/deps/prebuilt/Universal Windows/x86/ObjCUWP.lib b/deps/prebuilt/Universal Windows/x86/ObjCUWP.lib index 2ef782135d..9271046f1b 100644 --- a/deps/prebuilt/Universal Windows/x86/ObjCUWP.lib +++ b/deps/prebuilt/Universal Windows/x86/ObjCUWP.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49fb96e40c2dd994687d1b76c036328cae37d76da3bf71a09754d1a803ed22b4 -size 1428944 +oid sha256:7e883c3648601525b6211e90f059ebf5be8066029f556c38b416561fd0970f08 +size 1428294 diff --git a/deps/prebuilt/Universal Windows/x86/ObjCUWP.pdb b/deps/prebuilt/Universal Windows/x86/ObjCUWP.pdb index af9d36212e..5d99e5a172 100644 --- a/deps/prebuilt/Universal Windows/x86/ObjCUWP.pdb +++ b/deps/prebuilt/Universal Windows/x86/ObjCUWP.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c2b16bd41102267ea8529fd512b34ac133976a07d8384069ca0701fbc5c85662 -size 127258624 +oid sha256:1d5a36f9fb2ef48a186fdb9cca240d92564e617c1832477957c594b7d3bccfd8 +size 152219648 diff --git a/deps/prebuilt/Universal Windows/x86/RTObjCInterop.dll b/deps/prebuilt/Universal Windows/x86/RTObjCInterop.dll new file mode 100644 index 0000000000..17ada76653 --- /dev/null +++ b/deps/prebuilt/Universal Windows/x86/RTObjCInterop.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09fd482f08e7c927d6f676026b84413b435a5741997654fc394953c6e80201a3 +size 162304 diff --git a/deps/prebuilt/Universal Windows/x86/RTObjCInterop.lib b/deps/prebuilt/Universal Windows/x86/RTObjCInterop.lib new file mode 100644 index 0000000000..25db1443c2 --- /dev/null +++ b/deps/prebuilt/Universal Windows/x86/RTObjCInterop.lib @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50bf105bf80a9e4b8647658ad830d6b6b57c5ef6576a232caa20a72085194f37 +size 9186 diff --git a/deps/prebuilt/Universal Windows/x86/RTObjCInterop.pdb b/deps/prebuilt/Universal Windows/x86/RTObjCInterop.pdb new file mode 100644 index 0000000000..aa7dbf3f54 --- /dev/null +++ b/deps/prebuilt/Universal Windows/x86/RTObjCInterop.pdb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86a217e669b8a815729252a2c3d5c498ef8c8082583cec8aaebc8d28dd8142e7 +size 1036288 diff --git a/include/Platform/Universal Windows/UWP/InteropBase.h b/include/Platform/Universal Windows/UWP/InteropBase.h index 2852f676eb..557b9351c9 100644 --- a/include/Platform/Universal Windows/UWP/InteropBase.h +++ b/include/Platform/Universal Windows/UWP/InteropBase.h @@ -16,6 +16,12 @@ #pragma once +#if defined(__cplusplus) +#include +#include +#include +#endif /*__cpluplus*/ + #include #include #include @@ -27,18 +33,21 @@ #define ACTIVATOR __attribute((ns_returns_retained)) #ifdef __cplusplus -class IInspectable; #define WINRT_EXPORT_FN extern "C" WINRT_EXPORT #else -struct IInspectable; -typedef struct IInspectable IInspectable; #define WINRT_EXPORT_FN WINRT_EXPORT #endif -WINRT_EXPORT_FN +WINRT_EXPORT @interface RTObject : NSObject -- (id)internalObject; -- (void)setComObj:(IInspectable*)obj; + +// Even with the #ifdefs we will not violate ODR, because of dynamic ivars provided by ObjectiveC modern runtime. +#if defined(__cplusplus) +@property (nonatomic) Microsoft::WRL::ComPtr comObj; + +// For composable objects, this is the original interface. +@property (nonatomic) Microsoft::WRL::ComPtr innerInterface; +#endif /*__cplusplus*/ @end // Does a safe cast of rtObject into a derived projected class type. Throws if it is an invalid cast. @@ -71,6 +80,7 @@ typedef struct _GUID { #endif #endif +WINRT_EXPORT @interface WFGUID : NSObject @property unsigned long Data1; @property unsigned short Data2; @@ -81,6 +91,7 @@ typedef struct _GUID { - initWithGUID:(const GUID)guid; @end +WINRT_EXPORT @interface RTKeyValuePair : RTObject @property (readonly) id Key; @property (readonly) id Value; diff --git a/msvc/sbclang.props b/msvc/sbclang.props index 5258909cfe..b75f121cfc 100644 --- a/msvc/sbclang.props +++ b/msvc/sbclang.props @@ -48,7 +48,7 @@ - Accelerate.lib;Accounts.lib;AddressBook.lib;AddressBookUI.lib;AdSupport.lib;AssetsLibrary.lib;AudioToolbox.lib;AudioUnit.lib;AVFoundation.lib;AVKit.lib;CFNetwork.lib;CloudKit.lib;Contacts.lib;CoreAudio.lib;CoreAudioKit.lib;CoreBluetooth.lib;CoreData.lib;CoreGraphics.lib;CoreImage.lib;CoreLocation.lib;CoreMedia.lib;CoreMIDI.lib;CoreMotion.lib;CoreTelephony.lib;CoreText.lib;CoreVideo.lib;EventKit.lib;EventKitUI.lib;Foundation.lib;GameController.lib;GameKit.lib;GameplayKit.lib;GLKit.lib;HealthKit.lib;HomeKit.lib;iAd.lib;ImageIO.lib;LocalAuthentication.lib;MapKit.lib;MediaAccessibility.lib;MediaPlayer.lib;MessageUI.lib;Metal.lib;MobileCoreServices.lib;OpenAL.lib;OpenGLES.lib;QuartzCore.lib;QuickLook.lib;Security.lib;Social.lib;Starboard.lib;StoreKit.lib;SystemConfiguration.lib;Twitter.lib;UIKit.lib;WebKit.lib;libdispatch.lib;objcuwp.lib + Accelerate.lib;Accounts.lib;AddressBook.lib;AddressBookUI.lib;AdSupport.lib;AssetsLibrary.lib;AudioToolbox.lib;AudioUnit.lib;AVFoundation.lib;AVKit.lib;CFNetwork.lib;CloudKit.lib;Contacts.lib;CoreAudio.lib;CoreAudioKit.lib;CoreBluetooth.lib;CoreData.lib;CoreGraphics.lib;CoreImage.lib;CoreLocation.lib;CoreMedia.lib;CoreMIDI.lib;CoreMotion.lib;CoreTelephony.lib;CoreText.lib;CoreVideo.lib;EventKit.lib;EventKitUI.lib;Foundation.lib;GameController.lib;GameKit.lib;GameplayKit.lib;GLKit.lib;HealthKit.lib;HomeKit.lib;iAd.lib;ImageIO.lib;LocalAuthentication.lib;MapKit.lib;MediaAccessibility.lib;MediaPlayer.lib;MessageUI.lib;Metal.lib;MobileCoreServices.lib;OpenAL.lib;OpenGLES.lib;QuartzCore.lib;QuickLook.lib;Security.lib;Social.lib;Starboard.lib;StoreKit.lib;SystemConfiguration.lib;Twitter.lib;UIKit.lib;WebKit.lib;libdispatch.lib;objcuwp.lib;RTObjCInterop.lib true libobjc2.lib true From f2bf60d13637d599384fb006a595e16d1779a5e0 Mon Sep 17 00:00:00 2001 From: pengzh Date: Tue, 26 Apr 2016 05:21:34 +0800 Subject: [PATCH 19/31] Fix bug 7201302. WOCCatalog: Accelerate sliders have very slow reponse to touch --- Frameworks/UIKit/UISlider.mm | 33 ++- .../WOCCatalog/AccelerateViewController.m | 251 ++++++++---------- 2 files changed, 132 insertions(+), 152 deletions(-) diff --git a/Frameworks/UIKit/UISlider.mm b/Frameworks/UIKit/UISlider.mm index 03bce108d4..d9f1bcb08b 100644 --- a/Frameworks/UIKit/UISlider.mm +++ b/Frameworks/UIKit/UISlider.mm @@ -28,6 +28,7 @@ @implementation UISlider { idretaintype(UIImage) _sliderLeft, _sliderRight, _dot, _dotHighlighted; idretaintype(UIImageView) _sliderLeftView, _sliderRightView, _sliderThumbView; float _value, _max, _min, _trackVal; + BOOL _continuous; } static void sizeViews(UISlider* self, bool animated) { CGRect bounds, thumbSize; @@ -114,6 +115,7 @@ static void initInternal(UISlider* self) { [panGesture setDelegate:(id)self]; [panGesture _setDragSlack:0.0f]; [self->_sliderThumbView addGestureRecognizer:(id)panGesture]; + [self setContinuous:TRUE]; sizeViews(self, false); } @@ -213,7 +215,18 @@ - (void)setValue:(float)value animated:(BOOL)animated { sizeViews(self, animated ? true : false); } -- (void)setContinuous { +/** + @Status Interoperable +*/ +- (void)setContinuous:(BOOL)continous { + _continuous = continous; +} + +/** + @Status Interoperable +*/ +- (BOOL)isContinuous { + return _continuous; } /** @@ -279,21 +292,25 @@ - (void)_didPan:(UIPanGestureRecognizer*)gesture { [gesture setTranslation:CGPointMake(0, 0) inView:self]; CGRect bounds; + bounds = [self bounds]; + + _trackVal = _value + (amt.x / bounds.size.width) * (_max - _min); + [self setValue:_trackVal]; if (state == UIGestureRecognizerStateEnded) { [_sliderThumbView setHighlighted:FALSE]; + [self sendActionsForControlEvents:UIControlEventValueChanged]; + [self sendActionsForControlEvents:UIControlEventTouchUpInside]; } else if (state == UIGestureRecognizerStateBegan) { - _trackVal = _value; if ([_sliderThumbView highlightedImage] != nil) { [_sliderThumbView setHighlighted:TRUE]; } + if (self.isContinuous == YES) { + [self sendActionsForControlEvents:UIControlEventValueChanged]; + } + } else if ((self.isContinuous == YES) && (state == UIGestureRecognizerStateChanged)) { + [self sendActionsForControlEvents:UIControlEventValueChanged]; } - - bounds = [self bounds]; - - _trackVal += (amt.x / bounds.size.width) * (_max - _min); - [self setValue:_trackVal]; - [self sendActionsForControlEvents:UIControlEventValueChanged]; } /** diff --git a/samples/WOCCatalog/WOCCatalog/AccelerateViewController.m b/samples/WOCCatalog/WOCCatalog/AccelerateViewController.m index f241446331..60e89c6074 100644 --- a/samples/WOCCatalog/WOCCatalog/AccelerateViewController.m +++ b/samples/WOCCatalog/WOCCatalog/AccelerateViewController.m @@ -3,17 +3,17 @@ // Copyright (c) 2016 Intel Corporation. All rights reserved. // // Copyright (c) 2013 Ryan Nystrom (http://whoisryannystrom.com) -// +// // Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. -// +// // Copyright (c) 2015 Microsoft Corporation. All rights reserved. // // This code is licensed under the MIT License (MIT). @@ -47,7 +47,7 @@ @implementation AccelerateViewController { UISlider* _blueSlider; UISlider* _convolveSlider; UILabel* _rLabel; - UILabel* _gLabel; + UILabel* _gLabel; UILabel* _bLabel; UILabel* _boxLabel; } @@ -59,54 +59,56 @@ - (void)viewDidLoad { _valueGreen = 100; _valueBlue = 100; _convolveSize = 1; - + _redSlider = [[UISlider alloc] initWithFrame:CGRectMake(5.0, 12.0, 180.0, 8.0)]; _redSlider.backgroundColor = [UIColor clearColor]; _redSlider.minimumValue = 0.0; _redSlider.maximumValue = 200.0; _redSlider.continuous = YES; _redSlider.value = 100.0; - + _greenSlider = [[UISlider alloc] initWithFrame:CGRectMake(5.0, 12.0, 180.0, 8.0)]; _greenSlider.backgroundColor = [UIColor clearColor]; _greenSlider.minimumValue = 0.0; _greenSlider.maximumValue = 200.0; _greenSlider.continuous = YES; _greenSlider.value = 100.0; - + _blueSlider = [[UISlider alloc] initWithFrame:CGRectMake(5.0, 12.0, 180.0, 8.0)]; _blueSlider.backgroundColor = [UIColor clearColor]; _blueSlider.minimumValue = 0.0; _blueSlider.maximumValue = 200.0; _blueSlider.continuous = YES; _blueSlider.value = 100.0; - + _convolveSlider = [[UISlider alloc] initWithFrame:CGRectMake(5.0, 12.0, 180.0, 8.0)]; _convolveSlider.backgroundColor = [UIColor clearColor]; _convolveSlider.minimumValue = 1.0; _convolveSlider.maximumValue = 99.0; _convolveSlider.continuous = YES; _convolveSlider.value = 1.0; - + [_redSlider addTarget:self action:@selector(redChanged:) forControlEvents:UIControlEventValueChanged]; + [_redSlider setContinuous:NO]; [_greenSlider addTarget:self action:@selector(greenChanged:) forControlEvents:UIControlEventValueChanged]; + [_greenSlider setContinuous:NO]; [_blueSlider addTarget:self action:@selector(blueChanged:) forControlEvents:UIControlEventValueChanged]; + [_blueSlider setContinuous:NO]; [_convolveSlider addTarget:self action:@selector(convolveChanged:) forControlEvents:UIControlEventValueChanged]; - + [_convolveSlider setContinuous:NO]; + _rLabel = [[UILabel alloc] init]; _gLabel = [[UILabel alloc] init]; _bLabel = [[UILabel alloc] init]; _boxLabel = [[UILabel alloc] init]; - + _img = [UIImage imageNamed:[NSString stringWithFormat:@"photo%d.jpg", _accelerateImageNumber]]; } - - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { return 8; } - - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath { CGRect screenRect = [[UIScreen mainScreen] bounds]; @@ -117,14 +119,13 @@ - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPat return 40; } - - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"MenuCell"]; if (nil == cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MenuCell"]; } - + if (indexPath.row == 0) { // Title cell @@ -133,15 +134,14 @@ - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSI } else if (indexPath.row == 1) { // Image display box - [_imv removeFromSuperview]; UIImage* transformImg = [self transformImage:_img]; _imv = [[UIImageView alloc] initWithFrame:CGRectMake(3, 2, cell.bounds.size.width - 6.0f, cell.bounds.size.height - 4.0f)]; _imv.image = transformImg; - + [_imv setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; [cell addSubview:_imv]; - cell.selectionStyle = UITableViewCellSelectionStyleNone; + } else if (indexPath.row == 2) { // Red controls @@ -173,305 +173,268 @@ - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSI [_gLabel removeFromSuperview]; [_bLabel removeFromSuperview]; [_boxLabel removeFromSuperview]; - + _rLabel.text = [NSString stringWithFormat:@"R: %d%%", _valueRed]; _gLabel.text = [NSString stringWithFormat:@"G: %d%%", _valueGreen]; _bLabel.text = [NSString stringWithFormat:@"B: %d%%", _valueBlue]; _boxLabel.text = [NSString stringWithFormat:@"Kernel Size: %d", _convolveSize]; - + _rLabel.frame = CGRectMake(17.0f, 5.0f, 100.0f, cell.bounds.size.height - 5.0f); _gLabel.frame = CGRectMake(92.0f, 5.0f, 100.0f, cell.bounds.size.height - 5.0f); _bLabel.frame = CGRectMake(167.0f, 5.0f, 100.0f, cell.bounds.size.height - 5.0f); _boxLabel.frame = CGRectMake(242.0f, 5.0f, 200.0f, cell.bounds.size.height - 5.0f); - + [_rLabel setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; [_gLabel setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; [_bLabel setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; [_boxLabel setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; - + [cell addSubview:_rLabel]; [cell addSubview:_gLabel]; [cell addSubview:_bLabel]; [cell addSubview:_boxLabel]; - + } else if (indexPath.row == 7) { // Select Image - UIButton* imageChange = [UIButton buttonWithType:UIButtonTypeRoundedRect]; + UIButton* imageChange = [UIButton buttonWithType:UIButtonTypeRoundedRect]; imageChange.frame = CGRectMake(10.0f, 5.0f, 120.0f, cell.bounds.size.height - 15.0f); imageChange.layer.cornerRadius = 5.0f; imageChange.backgroundColor = [UIColor lightGrayColor]; [imageChange setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [imageChange setTitle:@"Select Image" forState:UIControlStateNormal]; - + [cell addSubview:imageChange]; - + [imageChange addTarget:self action:@selector(imageChangePress) forControlEvents:UIControlEventTouchUpInside]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } - + return cell; } - --(void) redChanged:(UISlider*)slider { - int oldValue = _valueRed; - _valueRed = (int) slider.value; - - if (oldValue != _valueRed) { - _indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]]; - [self.tableView reloadRowsAtIndexPaths:_indexPathArray withRowAnimation:UITableViewRowAnimationNone]; - - _indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:6 inSection:0]]; - [self.tableView reloadRowsAtIndexPaths:_indexPathArray withRowAnimation:UITableViewRowAnimationNone]; +- (void)redChanged:(UISlider*)slider { + if (_valueRed != slider.value) { + _valueRed = slider.value; + _rLabel.text = [NSString stringWithFormat:@"R: %d%%", _valueRed]; + [self changeImageCell]; } } - --(void) blueChanged:(UISlider*)slider { - int oldValue = _valueBlue; - _valueBlue = (int) slider.value; - - if (oldValue != _valueBlue) { - _indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]]; - [self.tableView reloadRowsAtIndexPaths:_indexPathArray withRowAnimation:UITableViewRowAnimationNone]; - - _indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:6 inSection:0]]; - [self.tableView reloadRowsAtIndexPaths:_indexPathArray withRowAnimation:UITableViewRowAnimationNone]; +- (void)blueChanged:(UISlider*)slider { + if (_valueBlue != slider.value) { + _valueBlue = slider.value; + _bLabel.text = [NSString stringWithFormat:@"R: %d%%", _valueBlue]; + [self changeImageCell]; } } - --(void) greenChanged:(UISlider*)slider { - int oldValue = _valueGreen; - _valueGreen = (int) slider.value; - - if (oldValue != _valueGreen) { - _indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]]; - [self.tableView reloadRowsAtIndexPaths:_indexPathArray withRowAnimation:UITableViewRowAnimationNone]; - - _indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:6 inSection:0]]; - [self.tableView reloadRowsAtIndexPaths:_indexPathArray withRowAnimation:UITableViewRowAnimationNone]; +- (void)greenChanged:(UISlider*)slider { + if (_valueGreen != slider.value) { + _valueGreen = slider.value; + _gLabel.text = [NSString stringWithFormat:@"R: %d%%", _valueGreen]; + [self changeImageCell]; } } - --(void) convolveChanged:(UISlider*)slider { +- (void)convolveChanged:(UISlider*)slider { int oldValue = _convolveSize; - _convolveSize = (int) slider.value; + _convolveSize = (int)slider.value; _convolveSize += (_convolveSize % 2) - 1; - + if (oldValue != _convolveSize) { - _indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]]; - [self.tableView reloadRowsAtIndexPaths:_indexPathArray withRowAnimation:UITableViewRowAnimationNone]; - - _indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:6 inSection:0]]; - [self.tableView reloadRowsAtIndexPaths:_indexPathArray withRowAnimation:UITableViewRowAnimationNone]; + _boxLabel.text = [NSString stringWithFormat:@"Kernel Size: %d", _convolveSize]; + [self changeImageCell]; } } - --(void) imageChangePress { +- (void)imageChangePress { PhotoSelectorController* photoView = [[PhotoSelectorController alloc] init]; photoView.delegate = self; [self.navigationController pushViewController:photoView animated:NO]; } - --(void) imageFromController:(UIImage*)image { +- (void)imageFromController:(UIImage*)image { _img = image; _indexPathArray = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]]; [self.tableView reloadRowsAtIndexPaths:_indexPathArray withRowAnimation:UITableViewRowAnimationNone]; } +- (void)changeImageCell { + UIImage* transformImg = [self transformImage:_img]; + [_imv setImage:transformImg]; +} --(UIImage*)transformImage:(UIImage*)image { +- (UIImage*)transformImage:(UIImage*)image { CGImageRef _img = image.CGImage; vImage_Buffer inBuffer, midBuffer, outBuffer; vImage_Error error; void *pixelBuffer, *midPixelBuffer; - - //create vImage_Buffer with data from CGImageRef + + // create vImage_Buffer with data from CGImageRef CGDataProviderRef inProvider = CGImageGetDataProvider(_img); CFDataRef inBitmapData = CGDataProviderCopyData(inProvider); - + inBuffer.width = CGImageGetWidth(_img); inBuffer.height = CGImageGetHeight(_img); inBuffer.rowBytes = CGImageGetBytesPerRow(_img); - + inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData); - - //create vImage_Buffer for output + + // create vImage_Buffer for output midPixelBuffer = malloc(CGImageGetBytesPerRow(_img) * CGImageGetHeight(_img)); pixelBuffer = malloc(CGImageGetBytesPerRow(_img) * CGImageGetHeight(_img)); - - if(midPixelBuffer == NULL) + + if (midPixelBuffer == NULL) NSLog(@"No midpixelbuffer"); - if(pixelBuffer == NULL) + if (pixelBuffer == NULL) NSLog(@"No pixelbuffer"); - + midBuffer.data = midPixelBuffer; midBuffer.width = CGImageGetWidth(_img); midBuffer.height = CGImageGetHeight(_img); midBuffer.rowBytes = CGImageGetBytesPerRow(_img); - + outBuffer.data = pixelBuffer; outBuffer.width = CGImageGetWidth(_img); outBuffer.height = CGImageGetHeight(_img); outBuffer.rowBytes = CGImageGetBytesPerRow(_img); - + int16_t A[] = { _valueRed, 0, 0, 0, 0, _valueGreen, 0, 0, 0, 0, _valueBlue, 0, 0, 0, 0, 0}; - + error = vImageMatrixMultiply_ARGB8888(&inBuffer, &midBuffer, A, meanDivisor, NULL, NULL, 0); - + if (error) { NSLog(@"error from matrix multiply %ld", error); } - + Pixel_8888 background; background[0] = 0; background[1] = 0; background[2] = 0; background[3] = 0; - - //perform convolution + + // perform convolution error = vImageBoxConvolve_ARGB8888(&midBuffer, &outBuffer, NULL, 0, 0, _convolveSize, _convolveSize, background, kvImageEdgeExtend); - + if (error) { NSLog(@"error from convolution %ld", error); } - - //create CGImageRef from vImage_Buffer output + + // create CGImageRef from vImage_Buffer output CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - - CGContextRef ctx = CGBitmapContextCreate(outBuffer.data, - outBuffer.width, - outBuffer.height, - 8, - outBuffer.rowBytes, - colorSpace, - (CGBitmapInfo)kCGImageAlphaNoneSkipLast); - - CGImageRef imageRef = CGBitmapContextCreateImage (ctx); - + + CGContextRef ctx = CGBitmapContextCreate( + outBuffer.data, outBuffer.width, outBuffer.height, 8, outBuffer.rowBytes, colorSpace, (CGBitmapInfo)kCGImageAlphaNoneSkipLast); + + CGImageRef imageRef = CGBitmapContextCreateImage(ctx); + UIImage* returnImage = [UIImage imageWithCGImage:imageRef]; - - //clean up + + // clean up CGContextRelease(ctx); CGColorSpaceRelease(colorSpace); free(midPixelBuffer); free(pixelBuffer); CFRelease(inBitmapData); CGImageRelease(imageRef); - - return returnImage; + + return returnImage; } @end - @interface SelectorLayout : UICollectionViewFlowLayout @end - @implementation SelectorLayout - (instancetype)init { - if (self = [super init]) { self.itemSize = CGSizeMake(140, 140); self.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10); self.minimumInteritemSpacing = 5.0f; self.minimumLineSpacing = 10.0f; - + [self setScrollDirection:UICollectionViewScrollDirectionVertical]; } - + return self; } @end - @implementation SelectorCell - (instancetype)initWithFrame:(CGRect)frame { - if (self = [super initWithFrame:frame]) { - self.imageView = [[UIImageView alloc] initWithFrame:CGRectInset(CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)), 5, 5)]; - + self.imageView = + [[UIImageView alloc] initWithFrame:CGRectInset(CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)), 5, 5)]; + self.imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; self.imageView.layer.masksToBounds = YES; self.imageView.layer.contentsGravity = kCAGravityResizeAspectFill; [self.contentView addSubview:self.imageView]; - + self.backgroundColor = [UIColor whiteColor]; } - + return self; } - - (void)setImage:(UIImage*)image { self.imageView.image = image; } @end - -@implementation PhotoSelectorController { +@implementation PhotoSelectorController { NSArray* images; } @synthesize delegate = _delegate; - (instancetype)init { - if (self = [super init]) { self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:[[SelectorLayout alloc] init]]; [self.collectionView setDataSource:self]; [self.collectionView setDelegate:self]; [self.collectionView registerClass:[SelectorCell class] forCellWithReuseIdentifier:@"photoCell"]; - + images = [NSArray arrayWithObjects:[[UIImage imageNamed:@"photo1.jpg"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal], - [UIImage imageNamed:@"photo2.jpg"], - [UIImage imageNamed:@"photo3.jpg"], - [UIImage imageNamed:@"photo4.jpg"], - [UIImage imageNamed:@"photo5.jpg"], - [UIImage imageNamed:@"photo6.jpg"], - [UIImage imageNamed:@"photo7.gif"], - [UIImage imageNamed:@"photo8.tif"], - nil]; + [UIImage imageNamed:@"photo2.jpg"], + [UIImage imageNamed:@"photo3.jpg"], + [UIImage imageNamed:@"photo4.jpg"], + [UIImage imageNamed:@"photo5.jpg"], + [UIImage imageNamed:@"photo6.jpg"], + [UIImage imageNamed:@"photo7.gif"], + [UIImage imageNamed:@"photo8.tif"], + nil]; } - + return self; } - - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)collectionView { return 1; } - - (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section { return [images count]; } - - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath { SelectorCell* pc = [collectionView dequeueReusableCellWithReuseIdentifier:@"photoCell" forIndexPath:indexPath]; [pc setImage:[images objectAtIndex:indexPath.item]]; - + return pc; } - - (void)collectionView:(UICollectionView*)collectionView didSelectItemAtIndexPath:(NSIndexPath*)indexPath { - if ([_delegate respondsToSelector:@selector(imageFromController:)]) { [_delegate imageFromController:[images objectAtIndex:indexPath.item]]; } - + [self.navigationController popViewControllerAnimated:NO]; } @end \ No newline at end of file From a9448a5bdc3a17e23c35bf647b4e058334801c12 Mon Sep 17 00:00:00 2001 From: John Frens Date: Thu, 28 Apr 2016 17:47:35 -0700 Subject: [PATCH 20/31] 7367523: FIx Unit Test break, add _WINOBJC_DO_NOT_USE_NSLOG --- Frameworks/Foundation/NSLog.mm | 1 - Frameworks/UIKit/UICollectionView.mm | 93 ++++++++++--------- Frameworks/UIKit/UICollectionViewData.mm | 9 +- .../UIKit/UICollectionViewFlowLayout.mm | 3 +- Frameworks/UIKit/UIGridLayoutSection.mm | 3 +- .../Accelerate/Accelerate.UnitTests.vcxproj | 1 + .../Accounts/Accounts.UnitTests.vcxproj | 1 + .../AudioToolbox.UnitTests.vcxproj | 1 + .../ClangModules.UnitTests.vcxproj | 1 + .../CoreImage/CoreImage.UnitTests.vcxproj | 1 + .../CoreLocation.UnitTests.vcxproj | 1 + .../CoreText/CoreText.UnitTests.vcxproj | 1 + .../Foundation/Foundation.UnitTests.vcxproj | 1 + .../UnitTests/GLKit/GLKit.UnitTests.vcxproj | 1 + .../ImageIO/ImageIO.UnitTests.vcxproj | 1 + .../MobileCoreServices.UnitTests.vcxproj | 1 + .../Security/Security.UnitTests.vcxproj | 1 + .../Starboard/Starboard.UnitTests.vcxproj | 1 + .../UnitTests/UIKit/UIKit.UnitTests.vcxproj | 1 + .../WOCStdLib/WOCStdLib.UnitTests.vcxproj | 1 + .../libDispatch/libDispatch.UnitTests.vcxproj | 1 + include/Foundation/NSObjCRuntime.h | 10 +- msvc/sdk-build.props | 1 + msvc/ut-build.props | 10 ++ tests/unittests/Foundation/NSLoggingTests.m | 2 +- tests/unittests/ImageIO/ImageIOTest.mm | 8 +- 26 files changed, 96 insertions(+), 60 deletions(-) create mode 100644 msvc/ut-build.props diff --git a/Frameworks/Foundation/NSLog.mm b/Frameworks/Foundation/NSLog.mm index a7effe7288..0ffefda708 100644 --- a/Frameworks/Foundation/NSLog.mm +++ b/Frameworks/Foundation/NSLog.mm @@ -13,7 +13,6 @@ // THE SOFTWARE. // //****************************************************************************** - #import "Starboard.h" #import "LoggingNative.h" #import diff --git a/Frameworks/UIKit/UICollectionView.mm b/Frameworks/UIKit/UICollectionView.mm index fdfcacfa11..06caa03913 100644 --- a/Frameworks/UIKit/UICollectionView.mm +++ b/Frameworks/UIKit/UICollectionView.mm @@ -29,6 +29,7 @@ #import "UICollectionViewItemKey.h" #import "NSLogging.h" #import "AssertARCEnabled.h" +#import "ErrorHandling.h" static const wchar_t* TAG = L"UICollectionView"; static CGFloat UIAnimationDragCoefficient = 1.f; @@ -491,8 +492,8 @@ - (void)scrollViewDidScrollToTop:(UIScrollView*)scrollView { @Status Interoperable */ - (void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSString*)identifier { - NSParameterAssert(cellClass); - NSParameterAssert(identifier); + THROW_HR_IF_NULL(E_INVALIDARG, cellClass); + THROW_HR_IF_NULL(E_INVALIDARG, identifier); _cellClassDict[identifier] = cellClass; } @@ -500,9 +501,9 @@ - (void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSString*)ide @Status Interoperable */ - (void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString*)elementKind withReuseIdentifier:(NSString*)identifier { - NSParameterAssert(viewClass); - NSParameterAssert(elementKind); - NSParameterAssert(identifier); + THROW_HR_IF_NULL(E_INVALIDARG, viewClass); + THROW_HR_IF_NULL(E_INVALIDARG, elementKind); + THROW_HR_IF_NULL(E_INVALIDARG, identifier); NSString* kindAndIdentifier = [NSString stringWithFormat:@"%@/%@", elementKind, identifier]; _supplementaryViewClassDict[kindAndIdentifier] = viewClass; } @@ -513,8 +514,8 @@ - (void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString*)ele - (void)registerNib:(UINib*)nib forCellWithReuseIdentifier:(NSString*)identifier { NSArray* topLevelObjects = [nib instantiateWithOwner:nil options:nil]; #pragma unused(topLevelObjects) - NSAssert(topLevelObjects.count == 1 && [topLevelObjects[0] isKindOfClass:UICollectionViewCell.class], - @"must contain exactly 1 top level object which is a UICollectionViewCell"); + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, topLevelObjects.count == 1 && [topLevelObjects[0] isKindOfClass:UICollectionViewCell.class], + "must contain exactly 1 top level object which is a UICollectionViewCell"); _cellNibDict[identifier] = nib; } @@ -525,8 +526,8 @@ - (void)registerNib:(UINib*)nib forCellWithReuseIdentifier:(NSString*)identifier - (void)registerNib:(UINib*)nib forSupplementaryViewOfKind:(NSString*)kind withReuseIdentifier:(NSString*)identifier { NSArray* topLevelObjects = [nib instantiateWithOwner:nil options:nil]; #pragma unused(topLevelObjects) - NSAssert(topLevelObjects.count == 1 && [topLevelObjects[0] isKindOfClass:UICollectionReusableView.class], - @"must contain exactly 1 top level object which is a UICollectionReusableView"); + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, topLevelObjects.count == 1 && [topLevelObjects[0] isKindOfClass:UICollectionReusableView.class], + "must contain exactly 1 top level object which is a UICollectionReusableView"); NSString* kindAndIdentifier = [NSString stringWithFormat:@"%@/%@", kind, identifier]; _supplementaryViewNibDict[kindAndIdentifier] = nib; @@ -1783,7 +1784,7 @@ - (UICollectionReusableView*)createPreparedSupplementaryViewForElementOfKind:(NS // @steipete optimization - (void)queueReusableView:(UICollectionReusableView*)reusableView inQueue:(NSMutableDictionary*)queue withIdentifier:(NSString*)identifier { - NSParameterAssert(identifier.length > 0); + THROW_HR_IF_FALSE(E_INVALIDARG, identifier.length > 0); [reusableView removeFromSuperview]; [reusableView prepareForReuse]; @@ -2175,15 +2176,15 @@ - (void)endItemAnimations { NSMutableDictionary* operations = [[NSMutableDictionary alloc] init]; for (UICollectionViewUpdateItem* updateItem in sortedMutableReloadItems) { - NSAssert(updateItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], - @"attempt to reload item (%@) that doesn't exist (there are only %ld sections before update)", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, updateItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], + "attempt to reload item (%@) that doesn't exist (there are only %ld sections before update)", updateItem.indexPathBeforeUpdate, (long)[oldCollectionViewData numberOfSections]); if (updateItem.indexPathBeforeUpdate.item != NSNotFound) { - NSAssert(updateItem.indexPathBeforeUpdate.item < + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, updateItem.indexPathBeforeUpdate.item < [oldCollectionViewData numberOfItemsInSection:updateItem.indexPathBeforeUpdate.section], - @"attempt to reload item (%@) that doesn't exist (there are only %ld items in section %ld before update)", + "attempt to reload item (%@) that doesn't exist (there are only %ld items in section %ld before update)", updateItem.indexPathBeforeUpdate, (long)[oldCollectionViewData numberOfItemsInSection:updateItem.indexPathBeforeUpdate.section], (long)updateItem.indexPathBeforeUpdate.section); @@ -2200,36 +2201,36 @@ - (void)endItemAnimations { for (UICollectionViewUpdateItem* deleteItem in sortedDeletedMutableItems) { if ([deleteItem isSectionOperation]) { - NSAssert(deleteItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], - @"attempt to delete section (%ld) that doesn't exist (there are only %ld sections before update)", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, deleteItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], + "attempt to delete section (%ld) that doesn't exist (there are only %ld sections before update)", (long)deleteItem.indexPathBeforeUpdate.section, (long)[oldCollectionViewData numberOfSections]); for (UICollectionViewUpdateItem* moveItem in sortedMutableMoveItems) { if (moveItem.indexPathBeforeUpdate.section == deleteItem.indexPathBeforeUpdate.section) { if (moveItem.isSectionOperation) - NSAssert(NO, - @"attempt to delete and move from the same section %ld", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, NO, + "attempt to delete and move from the same section %ld", (long)deleteItem.indexPathBeforeUpdate.section); else - NSAssert(NO, @"attempt to delete and move from the same section (%@)", moveItem.indexPathBeforeUpdate); + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, NO, "attempt to delete and move from the same section (%@)", moveItem.indexPathBeforeUpdate); } } } else { - NSAssert(deleteItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], - @"attempt to delete item (%@) that doesn't exist (there are only %ld sections before update)", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, deleteItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], + "attempt to delete item (%@) that doesn't exist (there are only %ld sections before update)", deleteItem.indexPathBeforeUpdate, (long)[oldCollectionViewData numberOfSections]); - NSAssert(deleteItem.indexPathBeforeUpdate.item < + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, deleteItem.indexPathBeforeUpdate.item < [oldCollectionViewData numberOfItemsInSection:deleteItem.indexPathBeforeUpdate.section], - @"attempt to delete item (%@) that doesn't exist (there are only %ld items in section%ld before update)", + "attempt to delete item (%@) that doesn't exist (there are only %ld items in section%ld before update)", deleteItem.indexPathBeforeUpdate, (long)[oldCollectionViewData numberOfItemsInSection:deleteItem.indexPathBeforeUpdate.section], (long)deleteItem.indexPathBeforeUpdate.section); for (UICollectionViewUpdateItem* moveItem in sortedMutableMoveItems) { - NSAssert(![deleteItem.indexPathBeforeUpdate isEqual:moveItem.indexPathBeforeUpdate], - @"attempt to delete and move the same item (%@)", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, ![deleteItem.indexPathBeforeUpdate isEqual:moveItem.indexPathBeforeUpdate], + "attempt to delete and move the same item (%@)", deleteItem.indexPathBeforeUpdate); } @@ -2247,15 +2248,15 @@ - (void)endItemAnimations { BOOL sectionOperation = [insertItem isSectionOperation]; if (sectionOperation) { - NSAssert([indexPath section] < [_collectionViewData numberOfSections], - @"attempt to insert %ld but there are only %ld sections after update", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, [indexPath section] < [_collectionViewData numberOfSections], + "attempt to insert %ld but there are only %ld sections after update", (long)[indexPath section], (long)[_collectionViewData numberOfSections]); for (UICollectionViewUpdateItem* moveItem in sortedMutableMoveItems) { if ([moveItem.indexPathAfterUpdate isEqual:indexPath]) { if (moveItem.isSectionOperation) - NSAssert(NO, @"attempt to perform an insert and a move to the same section (%ld)", (long)indexPath.section); + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, NO, "attempt to perform an insert and a move to the same section (%ld)", (long)indexPath.section); } } @@ -2264,8 +2265,8 @@ - (void)endItemAnimations { UICollectionViewUpdateItem* nextInsertItem = sortedInsertMutableItems[j]; if (nextInsertItem.indexPathAfterUpdate.section == indexPath.section) { - NSAssert(nextInsertItem.indexPathAfterUpdate.item < [_collectionViewData numberOfItemsInSection:indexPath.section], - @"attempt to insert item %ld into section %ld, but there are only %ld items in section %ld after the update", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, nextInsertItem.indexPathAfterUpdate.item < [_collectionViewData numberOfItemsInSection:indexPath.section], + "attempt to insert item %ld into section %ld, but there are only %ld items in section %ld after the update", (long)nextInsertItem.indexPathAfterUpdate.item, (long)indexPath.section, (long)[_collectionViewData numberOfItemsInSection:indexPath.section], @@ -2275,8 +2276,8 @@ - (void)endItemAnimations { break; } } else { - NSAssert(indexPath.item < [_collectionViewData numberOfItemsInSection:indexPath.section], - @"attempt to insert item to (%@) but there are only %ld items in section %ld after update", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, indexPath.item < [_collectionViewData numberOfItemsInSection:indexPath.section], + "attempt to insert item to (%@) but there are only %ld items in section %ld after update", indexPath, (long)[_collectionViewData numberOfItemsInSection:indexPath.section], (long)indexPath.section); @@ -2290,33 +2291,33 @@ - (void)endItemAnimations { for (UICollectionViewUpdateItem* sortedItem in sortedMutableMoveItems) { if (sortedItem.isSectionOperation) { - NSAssert(sortedItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], - @"attempt to move section (%ld) that doesn't exist (%ld sections before update)", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, sortedItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], + "attempt to move section (%ld) that doesn't exist (%ld sections before update)", (long)sortedItem.indexPathBeforeUpdate.section, (long)[oldCollectionViewData numberOfSections]); - NSAssert(sortedItem.indexPathAfterUpdate.section < [_collectionViewData numberOfSections], - @"attempt to move section to %ld but there are only %ld sections after update", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, sortedItem.indexPathAfterUpdate.section < [_collectionViewData numberOfSections], + "attempt to move section to %ld but there are only %ld sections after update", (long)sortedItem.indexPathAfterUpdate.section, (long)[_collectionViewData numberOfSections]); } else { - NSAssert(sortedItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], - @"attempt to move item (%@) that doesn't exist (%ld sections before update)", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, sortedItem.indexPathBeforeUpdate.section < [oldCollectionViewData numberOfSections], + "attempt to move item (%@) that doesn't exist (%ld sections before update)", sortedItem, (long)[oldCollectionViewData numberOfSections]); - NSAssert(sortedItem.indexPathBeforeUpdate.item < + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, sortedItem.indexPathBeforeUpdate.item < [oldCollectionViewData numberOfItemsInSection:sortedItem.indexPathBeforeUpdate.section], - @"attempt to move item (%@) that doesn't exist (%ld items in section %ld before update)", + "attempt to move item (%@) that doesn't exist (%ld items in section %ld before update)", sortedItem, (long)[oldCollectionViewData numberOfItemsInSection:sortedItem.indexPathBeforeUpdate.section], (long)sortedItem.indexPathBeforeUpdate.section); - NSAssert(sortedItem.indexPathAfterUpdate.section < [_collectionViewData numberOfSections], - @"attempt to move item to (%@) but there are only %ld sections after update", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, sortedItem.indexPathAfterUpdate.section < [_collectionViewData numberOfSections], + "attempt to move item to (%@) but there are only %ld sections after update", sortedItem.indexPathAfterUpdate, (long)[_collectionViewData numberOfSections]); - NSAssert(sortedItem.indexPathAfterUpdate.item < + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, sortedItem.indexPathAfterUpdate.item < [_collectionViewData numberOfItemsInSection:sortedItem.indexPathAfterUpdate.section], - @"attempt to move item to (%@) but there are only %ld items in section %ld after update", + "attempt to move item to (%@) but there are only %ld items in section %ld after update", sortedItem, (long)[_collectionViewData numberOfItemsInSection:sortedItem.indexPathAfterUpdate.section], (long)sortedItem.indexPathAfterUpdate.section); @@ -2343,10 +2344,10 @@ - (void)endItemAnimations { NSInteger movedInCount = [operations[sectionKey][@"movedIn"] integerValue]; NSInteger movedOutCount = [operations[sectionKey][@"movedOut"] integerValue]; - NSAssert( + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, [oldCollectionViewData numberOfItemsInSection:section] + insertedCount - deletedCount + movedInCount - movedOutCount == [_collectionViewData numberOfItemsInSection:section], - @"invalid update in section %ld: number of items after update (%ld) should be equal to the number of items before update (%ld) " + "invalid update in section %ld: number of items after update (%ld) should be equal to the number of items before update (%ld) " "plus count of inserted items (%ld), minus count of deleted items (%ld), plus count of items moved in (%ld), minus count of " "items moved out (%ld)", (long)section, diff --git a/Frameworks/UIKit/UICollectionViewData.mm b/Frameworks/UIKit/UICollectionViewData.mm index 07ab2553fe..a6c2256479 100644 --- a/Frameworks/UIKit/UICollectionViewData.mm +++ b/Frameworks/UIKit/UICollectionViewData.mm @@ -24,6 +24,7 @@ #import "UICollectionViewLayoutAttributes+Internal.h" #include "IwMalloc.h" #import "AssertARCEnabled.h" +#import "ErrorHandling.h" @interface UICollectionViewData () { CGRect _validLayoutRect; @@ -148,8 +149,8 @@ - (NSInteger)numberOfItems { - (NSInteger)numberOfItemsBeforeSection:(NSInteger)section { [self validateItemCounts]; - NSAssert(section < _numSections, - @"request for number of items in section %ld when there are only %ld sections in the collection view", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, section < _numSections, + "request for number of items in section %ld when there are only %ld sections in the collection view", (long)section, (long)_numSections); @@ -191,8 +192,8 @@ - (CGRect)rectForItemAtIndexPath:(NSIndexPath*)indexPath { - (NSIndexPath*)indexPathForItemAtGlobalIndex:(NSInteger)index { [self validateItemCounts]; - NSAssert(index < _numItems, - @"request for index path for global index %ld when there are only %ld items in the collection view", + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, index < _numItems, + "request for index path for global index %ld when there are only %ld items in the collection view", (long)index, (long)_numItems); diff --git a/Frameworks/UIKit/UICollectionViewFlowLayout.mm b/Frameworks/UIKit/UICollectionViewFlowLayout.mm index eab7894d22..ef446657a8 100644 --- a/Frameworks/UIKit/UICollectionViewFlowLayout.mm +++ b/Frameworks/UIKit/UICollectionViewFlowLayout.mm @@ -27,6 +27,7 @@ #import "UIGridLayoutSection.h" #import "UICollectionViewLayout+Internal.h" #import "AssertARCEnabled.h" +#import "ErrorHandling.h" NSString* const UICollectionElementKindSectionHeader = @"UICollectionElementKindSectionHeader"; NSString* const UICollectionElementKindSectionFooter = @"UICollectionElementKindSectionFooter"; @@ -441,7 +442,7 @@ - (void)fetchItemsInfo { @Public No */ - (void)getSizingInfos { - NSAssert(_data.sections.count == 0, @"Grid layout is already populated?"); + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, _data.sections.count == 0, "Grid layout is already populated?"); auto flowDataSource = static_cast*>(self.collectionView.delegate); diff --git a/Frameworks/UIKit/UIGridLayoutSection.mm b/Frameworks/UIKit/UIGridLayoutSection.mm index 0f6da9c382..301381dd82 100644 --- a/Frameworks/UIKit/UIGridLayoutSection.mm +++ b/Frameworks/UIKit/UIGridLayoutSection.mm @@ -23,6 +23,7 @@ #import "UIGridLayoutItem.h" #import "UIGridLayoutRow.h" #import "UIGridLayoutInfo.h" +#import "ErrorHandling.h" @interface UIGridLayoutSection () { NSMutableArray* _items; @@ -75,7 +76,7 @@ - (void)invalidate { - (void)computeLayout { if (!_isValid) { - NSAssert(self.rows.count == 0, @"No rows shall be at this point."); + THROW_HR_IF_FALSE_MSG(E_UNEXPECTED, self.rows.count == 0, "No rows shall be at this point."); // iterate over all items, turning them into rows. CGSize sectionSize = CGSizeZero; diff --git a/build/Tests/UnitTests/Accelerate/Accelerate.UnitTests.vcxproj b/build/Tests/UnitTests/Accelerate/Accelerate.UnitTests.vcxproj index cc163beea9..0129a067c1 100644 --- a/build/Tests/UnitTests/Accelerate/Accelerate.UnitTests.vcxproj +++ b/build/Tests/UnitTests/Accelerate/Accelerate.UnitTests.vcxproj @@ -92,6 +92,7 @@ + diff --git a/build/Tests/UnitTests/Accounts/Accounts.UnitTests.vcxproj b/build/Tests/UnitTests/Accounts/Accounts.UnitTests.vcxproj index 8d6ba2566a..d9f7cad0e1 100644 --- a/build/Tests/UnitTests/Accounts/Accounts.UnitTests.vcxproj +++ b/build/Tests/UnitTests/Accounts/Accounts.UnitTests.vcxproj @@ -92,6 +92,7 @@ + diff --git a/build/Tests/UnitTests/AudioToolbox/AudioToolbox.UnitTests.vcxproj b/build/Tests/UnitTests/AudioToolbox/AudioToolbox.UnitTests.vcxproj index 0e6d060e9a..6105836213 100644 --- a/build/Tests/UnitTests/AudioToolbox/AudioToolbox.UnitTests.vcxproj +++ b/build/Tests/UnitTests/AudioToolbox/AudioToolbox.UnitTests.vcxproj @@ -92,6 +92,7 @@ + diff --git a/build/Tests/UnitTests/ClangModules/ClangModules.UnitTests.vcxproj b/build/Tests/UnitTests/ClangModules/ClangModules.UnitTests.vcxproj index b5f846f100..7551b6b834 100644 --- a/build/Tests/UnitTests/ClangModules/ClangModules.UnitTests.vcxproj +++ b/build/Tests/UnitTests/ClangModules/ClangModules.UnitTests.vcxproj @@ -86,6 +86,7 @@ + diff --git a/build/Tests/UnitTests/CoreImage/CoreImage.UnitTests.vcxproj b/build/Tests/UnitTests/CoreImage/CoreImage.UnitTests.vcxproj index c960eefdc3..0a77ddfb05 100644 --- a/build/Tests/UnitTests/CoreImage/CoreImage.UnitTests.vcxproj +++ b/build/Tests/UnitTests/CoreImage/CoreImage.UnitTests.vcxproj @@ -104,6 +104,7 @@ + diff --git a/build/Tests/UnitTests/CoreLocation/CoreLocation.UnitTests.vcxproj b/build/Tests/UnitTests/CoreLocation/CoreLocation.UnitTests.vcxproj index 4ddfb0b9a7..cce88b8457 100644 --- a/build/Tests/UnitTests/CoreLocation/CoreLocation.UnitTests.vcxproj +++ b/build/Tests/UnitTests/CoreLocation/CoreLocation.UnitTests.vcxproj @@ -92,6 +92,7 @@ + diff --git a/build/Tests/UnitTests/CoreText/CoreText.UnitTests.vcxproj b/build/Tests/UnitTests/CoreText/CoreText.UnitTests.vcxproj index ffe19d780e..6815c82a25 100644 --- a/build/Tests/UnitTests/CoreText/CoreText.UnitTests.vcxproj +++ b/build/Tests/UnitTests/CoreText/CoreText.UnitTests.vcxproj @@ -98,6 +98,7 @@ + diff --git a/build/Tests/UnitTests/Foundation/Foundation.UnitTests.vcxproj b/build/Tests/UnitTests/Foundation/Foundation.UnitTests.vcxproj index ffb4fb0cb0..ef3164267c 100644 --- a/build/Tests/UnitTests/Foundation/Foundation.UnitTests.vcxproj +++ b/build/Tests/UnitTests/Foundation/Foundation.UnitTests.vcxproj @@ -92,6 +92,7 @@ + diff --git a/build/Tests/UnitTests/GLKit/GLKit.UnitTests.vcxproj b/build/Tests/UnitTests/GLKit/GLKit.UnitTests.vcxproj index 91e824d8a9..85b7f57da6 100644 --- a/build/Tests/UnitTests/GLKit/GLKit.UnitTests.vcxproj +++ b/build/Tests/UnitTests/GLKit/GLKit.UnitTests.vcxproj @@ -107,6 +107,7 @@ + diff --git a/build/Tests/UnitTests/ImageIO/ImageIO.UnitTests.vcxproj b/build/Tests/UnitTests/ImageIO/ImageIO.UnitTests.vcxproj index c40d0d1e43..3534d553d1 100644 --- a/build/Tests/UnitTests/ImageIO/ImageIO.UnitTests.vcxproj +++ b/build/Tests/UnitTests/ImageIO/ImageIO.UnitTests.vcxproj @@ -98,6 +98,7 @@ + diff --git a/build/Tests/UnitTests/MobileCoreServices/MobileCoreServices.UnitTests.vcxproj b/build/Tests/UnitTests/MobileCoreServices/MobileCoreServices.UnitTests.vcxproj index bb3f5f9b1a..9d0b7e6875 100644 --- a/build/Tests/UnitTests/MobileCoreServices/MobileCoreServices.UnitTests.vcxproj +++ b/build/Tests/UnitTests/MobileCoreServices/MobileCoreServices.UnitTests.vcxproj @@ -92,6 +92,7 @@ + diff --git a/build/Tests/UnitTests/Security/Security.UnitTests.vcxproj b/build/Tests/UnitTests/Security/Security.UnitTests.vcxproj index 8c86af438a..f6b23038ad 100644 --- a/build/Tests/UnitTests/Security/Security.UnitTests.vcxproj +++ b/build/Tests/UnitTests/Security/Security.UnitTests.vcxproj @@ -92,6 +92,7 @@ + diff --git a/build/Tests/UnitTests/Starboard/Starboard.UnitTests.vcxproj b/build/Tests/UnitTests/Starboard/Starboard.UnitTests.vcxproj index 3478e63d83..199862c6b1 100644 --- a/build/Tests/UnitTests/Starboard/Starboard.UnitTests.vcxproj +++ b/build/Tests/UnitTests/Starboard/Starboard.UnitTests.vcxproj @@ -89,6 +89,7 @@ + diff --git a/build/Tests/UnitTests/UIKit/UIKit.UnitTests.vcxproj b/build/Tests/UnitTests/UIKit/UIKit.UnitTests.vcxproj index fa85212ffc..5276973956 100644 --- a/build/Tests/UnitTests/UIKit/UIKit.UnitTests.vcxproj +++ b/build/Tests/UnitTests/UIKit/UIKit.UnitTests.vcxproj @@ -104,6 +104,7 @@ + diff --git a/build/Tests/UnitTests/WOCStdLib/WOCStdLib.UnitTests.vcxproj b/build/Tests/UnitTests/WOCStdLib/WOCStdLib.UnitTests.vcxproj index 1f4565a5db..60ed301afb 100644 --- a/build/Tests/UnitTests/WOCStdLib/WOCStdLib.UnitTests.vcxproj +++ b/build/Tests/UnitTests/WOCStdLib/WOCStdLib.UnitTests.vcxproj @@ -89,6 +89,7 @@ + diff --git a/build/Tests/UnitTests/libDispatch/libDispatch.UnitTests.vcxproj b/build/Tests/UnitTests/libDispatch/libDispatch.UnitTests.vcxproj index 04118d8847..0ea69bd8da 100644 --- a/build/Tests/UnitTests/libDispatch/libDispatch.UnitTests.vcxproj +++ b/build/Tests/UnitTests/libDispatch/libDispatch.UnitTests.vcxproj @@ -92,6 +92,7 @@ + diff --git a/include/Foundation/NSObjCRuntime.h b/include/Foundation/NSObjCRuntime.h index f92b9fd647..b1001d3359 100644 --- a/include/Foundation/NSObjCRuntime.h +++ b/include/Foundation/NSObjCRuntime.h @@ -170,8 +170,14 @@ typedef double NSTimeInterval; #warning ABS is already defined, ABS(a) may not behave as expected. #endif -FOUNDATION_EXPORT void NSLog(NSString* format, ...); -FOUNDATION_EXPORT void NSLogv(NSString* format, va_list args); +#ifdef _WINOBJC_DO_NOT_USE_NSLOG +#define NSLOG_ANNOTATION __attribute__((unavailable("NSLog should not be used internally."))) +#else +#define NSLOG_ANNOTATION +#endif + +FOUNDATION_EXPORT void NSLog(NSString* format, ...) NSLOG_ANNOTATION; +FOUNDATION_EXPORT void NSLogv(NSString* format, va_list args) NSLOG_ANNOTATION; FOUNDATION_EXPORT const char* NSGetSizeAndAlignment(const char* type, NSUInteger* size, NSUInteger* alignment); diff --git a/msvc/sdk-build.props b/msvc/sdk-build.props index 38c31345f4..f99784049b 100644 --- a/msvc/sdk-build.props +++ b/msvc/sdk-build.props @@ -84,6 +84,7 @@ MultiThreadedDebugDLL true -Werror -Wno-microsoft %(AdditionalOptions) + _WINOBJC_DO_NOT_USE_NSLOG=;%(PreprocessorDefinitions) diff --git a/msvc/ut-build.props b/msvc/ut-build.props new file mode 100644 index 0000000000..5f4c7c84e4 --- /dev/null +++ b/msvc/ut-build.props @@ -0,0 +1,10 @@ + + + + + + _WINOBJC_DO_NOT_USE_NSLOG=;%(PreprocessorDefinitions) + + + + diff --git a/tests/unittests/Foundation/NSLoggingTests.m b/tests/unittests/Foundation/NSLoggingTests.m index 617364a4f5..b3a71fcb68 100644 --- a/tests/unittests/Foundation/NSLoggingTests.m +++ b/tests/unittests/Foundation/NSLoggingTests.m @@ -13,7 +13,7 @@ // THE SOFTWARE. // //****************************************************************************** - +#undef _WINOBJC_DO_NOT_USE_NSLOG #include #import #include "Starboard.h" diff --git a/tests/unittests/ImageIO/ImageIOTest.mm b/tests/unittests/ImageIO/ImageIOTest.mm index 40a80a9349..64893c0584 100644 --- a/tests/unittests/ImageIO/ImageIOTest.mm +++ b/tests/unittests/ImageIO/ImageIOTest.mm @@ -1328,7 +1328,7 @@ static CFURLRef getURLRefFromFilename(const wchar_t* filename) { ASSERT_TRUE_MSG(imageProperties != nil, "FAILED: ImageIOTest::CGImageSourceCopyPropertiesAtIndex returned nullptr"); // Print the properties due to high number of properties written, only checking a few properties - NSLog(@"TIFF Dictionary - [%@]", (NSDictionary*)imageProperties); + LOG_INFO("TIFF Dictionary - [%@]", (NSDictionary*)imageProperties); // Note that this XResolution was actually passed in as 100. This field aliases with DPIWidth. // As observed on iOS, for TIFF, DPIWidth takes precedence, while for JPEG, XResolution takes precedence. @@ -1420,7 +1420,7 @@ static CFURLRef getURLRefFromFilename(const wchar_t* filename) { ASSERT_TRUE_MSG(imageProperties != nil, "FAILED: ImageIOTest::CGImageSourceCopyPropertiesAtIndex returned nullptr"); // Print the properties due to high number of properties written, only checking a few properties - NSLog(@"JPEG Dictionary - [%@]", (NSDictionary*)imageProperties); + LOG_INFO("JPEG Dictionary - [%@]", (NSDictionary*)imageProperties); ASSERT_TRUE_MSG(CFDictionaryContainsKey(imageProperties, kCGImagePropertyJFIFDictionary), "FAILED: ImageIOTest::JFIF dictionary not found"); @@ -1488,7 +1488,7 @@ static CFURLRef getURLRefFromFilename(const wchar_t* filename) { ASSERT_TRUE_MSG(imageProperties != nil, "FAILED: ImageIOTest::CGImageSourceCopyPropertiesAtIndex returned nullptr"); // Print the properties due to high number of properties written, only checking a few properties - NSLog(@"GIF Dictionary - [%@]", (NSDictionary*)imageProperties); + LOG_INFO("GIF Dictionary - [%@]", (NSDictionary*)imageProperties); ASSERT_TRUE_MSG(CFDictionaryContainsKey(imageProperties, kCGImagePropertyGIFDictionary), "FAILED: ImageIOTest::GIF dictionary not found"); @@ -1547,7 +1547,7 @@ static CFURLRef getURLRefFromFilename(const wchar_t* filename) { ASSERT_TRUE_MSG(imageProperties != nil, "FAILED: ImageIOTest::CGImageSourceCopyPropertiesAtIndex returned nullptr"); // Print the properties due to high number of properties written, only checking a few properties - NSLog(@"PNG Dictionary - [%@]", (NSDictionary*)imageProperties); + LOG_INFO("PNG Dictionary - [%@]", (NSDictionary*)imageProperties); ASSERT_TRUE_MSG(CFDictionaryContainsKey(imageProperties, kCGImagePropertyPNGDictionary), "FAILED: ImageIOTest::PNG dictionary not found"); From 9bfe640e281cff09b9a112d6f1353daf898d2e9e Mon Sep 17 00:00:00 2001 From: John Frens Date: Mon, 25 Apr 2016 15:40:56 -0700 Subject: [PATCH 21/31] 7042029: Fix foundation annotations --- Frameworks/Foundation/NSBundle.mm | 18 ++--- Frameworks/Foundation/NSCalendar.mm | 31 +------- Frameworks/Foundation/NSDate.h | 2 - Frameworks/Foundation/NSDate.mm | 23 +----- Frameworks/Foundation/NSDateFormatter.mm | 9 ++- Frameworks/Foundation/NSDecimalNumber.mm | 4 +- Frameworks/Foundation/NSDictionary.mm | 3 +- Frameworks/Foundation/NSFileManager.mm | 41 +++-------- .../Foundation/NSMutableAttributedString.mm | 1 + Frameworks/Foundation/NSNumberFormatter.mm | 15 ---- Frameworks/Foundation/NSRunLoop.mm | 1 - Frameworks/Foundation/NSScanner.mm | 20 ----- Frameworks/Foundation/NSStream.mm | 32 -------- Frameworks/Foundation/NSString.mm | 7 +- Frameworks/Foundation/NSURL.mm | 3 +- Frameworks/Foundation/NSURLSession.mm | 6 +- Frameworks/Foundation/NSURLSessionTask.mm | 2 +- Frameworks/Foundation/NSUserDefaults.mm | 1 - Frameworks/Foundation/NSXMLParser.mm | 73 +------------------ include/Foundation/NSCalendar.h | 4 +- include/Foundation/NSNumberFormatter.h | 2 +- .../unittests/Foundation/NSDictionaryTests.mm | 10 +++ 22 files changed, 60 insertions(+), 248 deletions(-) diff --git a/Frameworks/Foundation/NSBundle.mm b/Frameworks/Foundation/NSBundle.mm index 34ed7265c5..94072f30ae 100644 --- a/Frameworks/Foundation/NSBundle.mm +++ b/Frameworks/Foundation/NSBundle.mm @@ -1159,14 +1159,14 @@ - (NSString*)resourcePath { */ - (NSString*)executablePath { UNIMPLEMENTED(); - return [_bundlePath stringByAppendingPathComponent:[NSString stringWithCString:g_globalExecutableName]]; + return StubReturn(); } /** - @Status Stub + @Status Caveat + @Notes Returns [en, Base, eng, English]; */ - (NSArray*)preferredLocalizations { - UNIMPLEMENTED(); if (_preferredLocalizations == nil) { _preferredLocalizations = [[NSMutableArray arrayWithObject:@"en"] retain]; [_preferredLocalizations addObject:@"Base"]; @@ -1186,10 +1186,10 @@ - (NSString*)pathForAuxiliaryExecutable:(NSString*)executable { } /** - @Status Stub + @Status Caveat + @Notes Adds only "en", "eng", and "English" */ + (NSArray*)preferredLocalizationsFromArray:(NSArray*)localizations { - UNIMPLEMENTED(); NSMutableArray* ret = [NSMutableArray array]; if ([localizations containsObject:@"en"]) { @@ -1206,10 +1206,10 @@ + (NSArray*)preferredLocalizationsFromArray:(NSArray*)localizations { } /** - @Status Stub + @Status Caveat + @Notes Adds only "en", "eng", and "English" */ + (NSArray*)preferredLocalizationsFromArray:(NSArray*)localizations forPreferences:(NSArray*)preferences { - UNIMPLEMENTED(); NSMutableArray* ret = [NSMutableArray array]; if ([localizations containsObject:@"en"]) { @@ -1267,10 +1267,10 @@ - (NSArray*)URLsForResourcesWithExtension:(NSString*)type subdirectory:(NSString } /** - @Status Stub + @Status Caveat + @Notes Ignores localization */ - (NSArray*)URLsForResourcesWithExtension:(NSString*)extension subdirectory:(NSString*)subpath localization:(NSString*)localizationName { - UNIMPLEMENTED(); return [self URLsForResourcesWithExtension:extension subdirectory:subpath]; } diff --git a/Frameworks/Foundation/NSCalendar.mm b/Frameworks/Foundation/NSCalendar.mm index ea8f0ff511..9a6db486f6 100644 --- a/Frameworks/Foundation/NSCalendar.mm +++ b/Frameworks/Foundation/NSCalendar.mm @@ -131,10 +131,9 @@ - (void)dealloc { } /** - @Status Stub + @Status Interoperable */ - (NSString*)calendarIdentifier { - UNIMPLEMENTED(); return _identifier; } @@ -410,11 +409,7 @@ - (NSDateComponents*)components:(NSUInteger)unitFlags fromDate:(NSDate*)fromDate */ - (BOOL)rangeOfUnit:(NSCalendarUnit)unit startDate:(NSDate* _Nullable*)datep interval:(NSTimeInterval*)timep forDate:(NSDate*)date { UNIMPLEMENTED(); - // HACK: implement me! - if (datep) { - *datep = [date retain]; - } - return NO; + return StubReturn(); } static UCalendarDateFields icuFieldFromUnit(NSCalendarUnit unit) { @@ -454,27 +449,7 @@ static UCalendarDateFields icuFieldFromUnit(NSCalendarUnit unit) { */ - (NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate*)date { UNIMPLEMENTED(); - NSRange ret; - - double time = [date timeIntervalSince1970]; - - UErrorCode status = U_ZERO_ERROR; - Calendar* copy = [self _getICUCalendar]->clone(); - copy->setTime(time * 1000.0, status); - - icu::TimeZone* tz = [_timeZone _createICUTimeZone]; - copy->setTimeZone(*tz); - delete tz; - - UCalendarDateFields icuSmaller = icuFieldFromUnit(smaller); - ret.location = copy->getActualMinimum(icuSmaller, status); - ret.length = copy->getActualMaximum(icuSmaller, status) - ret.location + 1; - - if (smaller == NSMonthCalendarUnit) { - ret.location++; - } - delete copy; - return ret; + return StubReturn(); } /** diff --git a/Frameworks/Foundation/NSDate.h b/Frameworks/Foundation/NSDate.h index 2d52c882ed..b567f58b84 100644 --- a/Frameworks/Foundation/NSDate.h +++ b/Frameworks/Foundation/NSDate.h @@ -27,7 +27,6 @@ - (double)timeIntervalSinceDate:(id)ref; - (NSDate*)dateByAddingTimeInterval:(double)interval; - (NSDate*)initWithCoder:(NSCoder*)coder; -- (NSDate*)initWithString:(NSString*)string; - (NSDate*)initWithTimeIntervalSince1970:(double)secondsSince1970; - (NSDate*)initWithTimeIntervalSinceNow:(double)secondsSinceNow; - (NSDate*)initWithTimeIntervalSinceReferenceDate:(double)ref; @@ -43,7 +42,6 @@ - (NSObject*)init; - (NSObject*)encodeWithCoder:(NSCoder*)coder; - (NSString*)description; -+ (NSDate*)dateWithString:(NSString*)string; + (NSDate*)date; + (NSDate*)distantPast; + (NSDate*)distantFuture; diff --git a/Frameworks/Foundation/NSDate.mm b/Frameworks/Foundation/NSDate.mm index d631b7e8ad..88b6b8eba6 100644 --- a/Frameworks/Foundation/NSDate.mm +++ b/Frameworks/Foundation/NSDate.mm @@ -48,14 +48,6 @@ + (double)timeIntervalSinceReferenceDate { return TimeIntervalSinceReferenceDate(); } -/** - @Status Stub -*/ -+ (NSDate*)dateWithString:(NSString*)string { - UNIMPLEMENTED(); - return [[[self alloc] initWithString:string] autorelease]; -} - /** @Status Interoperable */ @@ -162,17 +154,6 @@ - (NSDate*)initWithCoder:(NSCoder*)coder { return [self initWithTimeIntervalSinceReferenceDate:time]; } -/** - @Status Stub -*/ -- (NSDate*)initWithString:(NSString*)string { - UNIMPLEMENTED(); - TraceVerbose(TAG, L"NSDate initWithString not supported"); - [self init]; - - return self; -} - /** @Status Interoperable */ @@ -307,7 +288,9 @@ - (NSDate*)addTimeInterval:(double)seconds { @Status Interoperable */ - (NSObject*)init { - _curTime = TimeIntervalSinceReferenceDate(); + if (self = [super init]) { + _curTime = TimeIntervalSinceReferenceDate(); + } return self; } diff --git a/Frameworks/Foundation/NSDateFormatter.mm b/Frameworks/Foundation/NSDateFormatter.mm index 167954aff5..f99b24488b 100644 --- a/Frameworks/Foundation/NSDateFormatter.mm +++ b/Frameworks/Foundation/NSDateFormatter.mm @@ -319,14 +319,15 @@ - (void)_setFormatterProperty:(ICUPropertyMapper::PropertyTypes)type withValue:( static NSDateFormatterBehavior s_defaultFormatterBehavior = NSDateFormatterBehaviorDefault; /** - @Status Stub + @Status Interoperable */ + (NSDateFormatterBehavior)defaultFormatterBehavior { return s_defaultFormatterBehavior; } /** - @Status Stub + @Status Caveat + @Notes Setting this does not affect NSDateFormatter in the current implementation. */ + (void)setDefaultFormatterBehavior:(NSDateFormatterBehavior)behavior { s_defaultFormatterBehavior = behavior; @@ -419,7 +420,9 @@ - (instancetype)initWithDateFormat:(NSString*)format allowNaturalLanguage:(BOOL) */ - (instancetype)initWithDateFormat:(NSString*)format allowNaturalLanguage:(BOOL)flag locale:(NSLocale*)locale { if (flag == YES) { - [NSException raiseWithLogging:@"NSDateFormatterException" format:@"allowNatrualLanguage = YES not supported"]; + [self release]; + UNIMPLEMENTED_WITH_MSG("allowNaturalLanguage is unimplemented for initWithDateFormat"); + return nil; } [super init]; diff --git a/Frameworks/Foundation/NSDecimalNumber.mm b/Frameworks/Foundation/NSDecimalNumber.mm index 2022f917b8..bc0e4e058c 100644 --- a/Frameworks/Foundation/NSDecimalNumber.mm +++ b/Frameworks/Foundation/NSDecimalNumber.mm @@ -152,10 +152,10 @@ NSCalculationError NSDecimalSubtract(NSDecimal* result, @implementation NSDecimalNumber /** - @Status Stub + @Status Caveat + @Notes does not support locale using ',', does not support exponents */ + (NSDecimalNumber*)decimalNumberWithString:(NSString*)str { - UNIMPLEMENTED(); const char* pStr = [str UTF8String]; if (strstr(pStr, ".") != NULL) { double fVal = strtod(pStr, NULL); diff --git a/Frameworks/Foundation/NSDictionary.mm b/Frameworks/Foundation/NSDictionary.mm index e8c4739709..5e70162c71 100644 --- a/Frameworks/Foundation/NSDictionary.mm +++ b/Frameworks/Foundation/NSDictionary.mm @@ -776,10 +776,9 @@ - (NSArray*)keysSortedByValueUsingSelector:(SEL)selector { } /** - @Status Stub + @Status Interoperable */ - (NSArray*)keysSortedByValueUsingComparator:(NSComparator)comparator { - UNIMPLEMENTED(); SortedKeysHelperCtx ctx; ctx.dict = self; diff --git a/Frameworks/Foundation/NSFileManager.mm b/Frameworks/Foundation/NSFileManager.mm index 6afe29bfb3..3c30adb1db 100644 --- a/Frameworks/Foundation/NSFileManager.mm +++ b/Frameworks/Foundation/NSFileManager.mm @@ -112,29 +112,20 @@ - (instancetype)init { // Locating System Directories /** - @Status Stub + @Status Caveat + @Notes Ignores appropriateForURL, create, and error. Calls URLsForDirectory and returns first result. */ - (NSURL*)URLForDirectory:(NSSearchPathDirectory)directory inDomain:(NSSearchPathDomainMask)domains appropriateForURL:(NSURL*)forURL create:(BOOL)create error:(NSError**)error { - UNIMPLEMENTED(); - assert(forURL == nil); - id paths = NSSearchPathForDirectoriesInDomains(directory, domains, TRUE); - - int count = [paths count]; - - for (int i = 0; i < count; i++) { - id curObj = [paths objectAtIndex:i]; - - id newUrl = [NSURL fileURLWithPath:curObj]; - - return newUrl; + + NSArray* urls = [self URLsForDirectory:directory inDomains:domains]; + if ([urls count] > 0) { + return [urls objectAtIndex:0]; } - assert(0); - return nil; } @@ -573,14 +564,11 @@ - (BOOL)linkItemAtPath:(NSString*)fromPath toPath:(NSString*)toPath error:(NSErr } /** - @Status Stub + @Status Caveat + @Notes does not resolve symlinks */ -- (id)destinationOfSymbolicLinkAtPath:(id)path error:(NSError**)error { - UNIMPLEMENTED(); - const char* pPath = [path UTF8String]; - TraceVerbose(TAG, L"destinationOfSymbolicLinkAtPath: %hs", pPath); - - return [path retain]; +- (NSString*)destinationOfSymbolicLinkAtPath:(NSString*)path error:(NSError* _Nullable*)error { + return [[path copy] autorelease]; } // Determining Access to Files @@ -939,16 +927,11 @@ - (NSDictionary*)fileAttributesAtPath:(NSString*)pathAddr traverseLink:(BOOL)tra } /** - @Status Stub + @Status Caveat + @Notes returns hardcoded attributes */ - (NSDictionary*)fileSystemAttributesAtPath:(NSString*)pathAddr { - UNIMPLEMENTED(); - const char* path = [pathAddr UTF8String]; - - TraceVerbose(TAG, L"fileAttributesAtPath: %hs", path); - id ret = [NSMutableDictionary dictionary]; - [ret setValue:[NSNumber numberWithInt:32 * 1024 * 1024] forKey:NSFileSystemFreeSize]; [ret setValue:[NSNumber numberWithInt:64 * 1024 * 1024 * 1024] forKey:NSFileSystemSize]; diff --git a/Frameworks/Foundation/NSMutableAttributedString.mm b/Frameworks/Foundation/NSMutableAttributedString.mm index 898c33224a..e5685fa798 100644 --- a/Frameworks/Foundation/NSMutableAttributedString.mm +++ b/Frameworks/Foundation/NSMutableAttributedString.mm @@ -22,6 +22,7 @@ @implementation NSMutableAttributedString /** @Status Stub + @Notes Not implemented on the concrete subclass. */ - (NSMutableString*)mutableString { return NSInvalidAbstractInvocationReturn(); diff --git a/Frameworks/Foundation/NSNumberFormatter.mm b/Frameworks/Foundation/NSNumberFormatter.mm index 3c79b8dd70..4aadb29542 100644 --- a/Frameworks/Foundation/NSNumberFormatter.mm +++ b/Frameworks/Foundation/NSNumberFormatter.mm @@ -182,21 +182,6 @@ - (id)decimalSeparator { return _decimalSeparator; } -/** - @Status Interoperable -*/ -- (BOOL)alwaysShowsDecimalSeparator { - return _alwaysShowsDecimalSeparator; -} - -/** - @Status Stub -*/ -- (void)setAlwaysShowsDecimalSeparator:(BOOL)value { - UNIMPLEMENTED(); - _alwaysShowsDecimalSeparator = value; -} - /** @Status Interoperable */ diff --git a/Frameworks/Foundation/NSRunLoop.mm b/Frameworks/Foundation/NSRunLoop.mm index 2942dbf0cc..edcc5da8da 100644 --- a/Frameworks/Foundation/NSRunLoop.mm +++ b/Frameworks/Foundation/NSRunLoop.mm @@ -312,7 +312,6 @@ - (void)addTimer:(NSTimer*)timer forMode:(NSString*)mode { */ - (void)addPort:(id)port forMode:(id)mode { UNIMPLEMENTED(); - TraceVerbose(TAG, L"NSRunLoop addPort not supported"); } - (BOOL)containsTimer:(NSTimer*)timer forMode:(NSString*)mode { diff --git a/Frameworks/Foundation/NSScanner.mm b/Frameworks/Foundation/NSScanner.mm index 0c8e9a3c52..03772d4e41 100644 --- a/Frameworks/Foundation/NSScanner.mm +++ b/Frameworks/Foundation/NSScanner.mm @@ -84,14 +84,6 @@ - (BOOL)caseSensitive { return _isCaseSensitive; } -/** - @Status Stub -*/ -- (id)locale { - UNIMPLEMENTED(); - return _locale; -} - /** @Status Interoperable */ @@ -110,18 +102,6 @@ - (void)setCaseSensitive:(BOOL)flag { _isCaseSensitive = flag; } -/** - @Status Stub -*/ -- (void)setLocale:(id)locale { - UNIMPLEMENTED(); - if (locale != _locale) { - locale = [locale retain]; - [_locale release]; - _locale = locale; - } -} - /** @Status Interoperable */ diff --git a/Frameworks/Foundation/NSStream.mm b/Frameworks/Foundation/NSStream.mm index c817c801f1..88b7fdf90e 100644 --- a/Frameworks/Foundation/NSStream.mm +++ b/Frameworks/Foundation/NSStream.mm @@ -87,38 +87,6 @@ - (void)dealloc { [super dealloc]; } -/** - @Status Stub -*/ -+ (void)getStreamsToHost:(id)host - port:(int)port - inputStream:(NSInputStream* _Nullable*)inputStreamp - outputStream:(NSOutputStream* _Nullable*)outputStreamp { - UNIMPLEMENTED(); - id socket = [[[NSSocket alloc] initTCPStream] autorelease]; - id error; - BOOL immediate; - id input; - id output; - - if ((error = [socket connectToHost:host port:port immediate:&immediate]) != nil) { - if (inputStreamp) { - *inputStreamp = nil; - } - if (outputStreamp) { - *outputStreamp = nil; - } - return; - } - - if (inputStreamp) { - *inputStreamp = input = [[[NSInputStream_socket alloc] initWithSocket:socket streamStatus:NSStreamStatusNotOpen] autorelease]; - } - if (outputStreamp) { - *outputStreamp = output = [[[NSOutputStream_socket alloc] initWithSocket:socket streamStatus:NSStreamStatusNotOpen] autorelease]; - } -} - /** @Status Stub */ diff --git a/Frameworks/Foundation/NSString.mm b/Frameworks/Foundation/NSString.mm index ba381f5f4e..988a24d1ad 100644 --- a/Frameworks/Foundation/NSString.mm +++ b/Frameworks/Foundation/NSString.mm @@ -2976,11 +2976,11 @@ - (NSString*)stringByRemovingPercentEncoding { } /** - @Status Stub + @Status Caveat + @Notes Always returns YES */ - (BOOL)canBeConvertedToEncoding:(NSStringEncoding)encoding { - UNIMPLEMENTED(); - return TRUE; // [BUG: Blatant lie] + return YES; } /** @@ -3102,7 +3102,6 @@ - (void)getParagraphStart:(NSUInteger*)startp end:(NSUInteger*)endp contentsEnd: */ - (NSString*)precomposedStringWithCanonicalMapping { UNIMPLEMENTED(); - TraceVerbose(TAG, L"precomposedStringWithCanonicalMapping??"); return [self retain]; } diff --git a/Frameworks/Foundation/NSURL.mm b/Frameworks/Foundation/NSURL.mm index aca76413dc..e4718a966c 100644 --- a/Frameworks/Foundation/NSURL.mm +++ b/Frameworks/Foundation/NSURL.mm @@ -1201,8 +1201,7 @@ - (id)absoluteURL { */ - (id)standardizedURL { UNIMPLEMENTED(); - TraceVerbose(TAG, L"standardizedURL needs attention"); - return [self copy]; + return [[self copy] autorelease]; } /** diff --git a/Frameworks/Foundation/NSURLSession.mm b/Frameworks/Foundation/NSURLSession.mm index aad78aaa39..c1a35c49de 100644 --- a/Frameworks/Foundation/NSURLSession.mm +++ b/Frameworks/Foundation/NSURLSession.mm @@ -381,12 +381,12 @@ - (NSURLSessionUploadTask*)uploadTaskWithRequest:(NSURLRequest*)request fromData - (NSURLSessionUploadTask*)uploadTaskWithRequest:(NSURLRequest*)request fromData:(NSData*)data completionHandler:(NSURLSessionTaskCompletionHandler)completionHandler { + UNIMPLEMENTED(); if (_invalidating) { return nil; } // stream data? - UNIMPLEMENTED(); [self _dispatchUnsupportedFailureToCompletionBlock:completionHandler]; return nil; } @@ -404,11 +404,11 @@ - (NSURLSessionUploadTask*)uploadTaskWithRequest:(NSURLRequest*)request fromFile - (NSURLSessionUploadTask*)uploadTaskWithRequest:(NSURLRequest*)request fromFile:(NSURL*)fileURL completionHandler:(NSURLSessionTaskCompletionHandler)completionHandler { + UNIMPLEMENTED(); if (_invalidating) { return nil; } - UNIMPLEMENTED(); [self _dispatchUnsupportedFailureToCompletionBlock:completionHandler]; return nil; } @@ -417,11 +417,11 @@ - (NSURLSessionUploadTask*)uploadTaskWithRequest:(NSURLRequest*)request @Status Stub */ - (NSURLSessionUploadTask*)uploadTaskWithStreamedRequest:(NSURLRequest*)request { + UNIMPLEMENTED(); if (_invalidating) { return nil; } - UNIMPLEMENTED(); [self _dispatchUnsupportedFailureToCompletionBlock:nil]; return nil; } diff --git a/Frameworks/Foundation/NSURLSessionTask.mm b/Frameworks/Foundation/NSURLSessionTask.mm index 0971fff3e0..92bf618e6a 100644 --- a/Frameworks/Foundation/NSURLSessionTask.mm +++ b/Frameworks/Foundation/NSURLSessionTask.mm @@ -219,11 +219,11 @@ - (void)_stopLoading { @Status Stub */ - (void)suspend { + UNIMPLEMENTED(); @synchronized(self) { if (_state == NSURLSessionTaskStateSuspended) { return; } - UNIMPLEMENTED(); } } diff --git a/Frameworks/Foundation/NSUserDefaults.mm b/Frameworks/Foundation/NSUserDefaults.mm index 15e0e9a28e..03c8ee0ed8 100644 --- a/Frameworks/Foundation/NSUserDefaults.mm +++ b/Frameworks/Foundation/NSUserDefaults.mm @@ -531,7 +531,6 @@ - (void)setValue:(id)value forKey:(NSString*)key { */ + (void)resetStandardUserDefaults { UNIMPLEMENTED(); - TraceWarning(TAG, L"Warning: resetStandardUserDefaults not implemented"); } /** diff --git a/Frameworks/Foundation/NSXMLParser.mm b/Frameworks/Foundation/NSXMLParser.mm index 37d745782c..3c674e0327 100644 --- a/Frameworks/Foundation/NSXMLParser.mm +++ b/Frameworks/Foundation/NSXMLParser.mm @@ -82,51 +82,6 @@ - (id)delegate { return _delegate; } -/** - @Status Stub -*/ -- (void)setShouldProcessNamespaces:(BOOL)flag { - UNIMPLEMENTED(); - _shouldProcessNamespaces = flag; -} - -/** - @Status Stub -*/ -- (void)setShouldReportNamespacePrefixes:(BOOL)flag { - UNIMPLEMENTED(); - _shouldReportNamespacePrefixes = flag; -} - -/** - @Status Interoperable -*/ -- (BOOL)shouldProcessNamespaces { - return _shouldProcessNamespaces; -} - -/** - @Status Interoperable -*/ -- (BOOL)shouldReportNamespacePrefixes { - return _shouldReportNamespacePrefixes; -} - -/** - @Status Stub -*/ -- (void)setShouldResolveExternalEntities:(BOOL)flag { - UNIMPLEMENTED(); - _shouldResolveExternalEntities = flag; -} - -/** - @Status Interoperable -*/ -- (BOOL)shouldResolveExternalEntities { - return _shouldResolveExternalEntities; -} - static void startDocumentCallback(void* ctx) { NSXMLParser* self = (NSXMLParser*)ctx; @@ -249,36 +204,12 @@ void abortParsing__unused() { assert(0); } -/** - @Status Stub -*/ -- (NSError*)parserError { - UNIMPLEMENTED(); - return _parserError; -} - -/** - @Status Stub -*/ -- (NSString*)systemID { - UNIMPLEMENTED(); - return _systemID; -} - -/** - @Status Stub -*/ -- (NSString*)publicID { - UNIMPLEMENTED(); - return _publicID; -} - /** @Status Stub */ - (int)columnNumber { UNIMPLEMENTED(); - return xmlSAX2GetColumnNumber((void*)self); + return StubReturn(); } /** @@ -286,7 +217,7 @@ - (int)columnNumber { */ - (int)lineNumber { UNIMPLEMENTED(); - return xmlSAX2GetColumnNumber((void*)self); + return StubReturn(); } /** diff --git a/include/Foundation/NSCalendar.h b/include/Foundation/NSCalendar.h index 34cd925194..75df657758 100644 --- a/include/Foundation/NSCalendar.h +++ b/include/Foundation/NSCalendar.h @@ -122,8 +122,8 @@ FOUNDATION_EXPORT_CLASS @property NSUInteger minimumDaysInFirstWeek; - (NSRange)minimumRangeOfUnit:(NSCalendarUnit)unit STUB_METHOD; - (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate*)date; -- (NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate*)date; -- (BOOL)rangeOfUnit:(NSCalendarUnit)unit startDate:(NSDate* _Nullable*)datep interval:(NSTimeInterval*)tip forDate:(NSDate*)date; +- (NSRange)rangeOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate*)date STUB_METHOD; +- (BOOL)rangeOfUnit:(NSCalendarUnit)unit startDate:(NSDate* _Nullable*)datep interval:(NSTimeInterval*)tip forDate:(NSDate*)date STUB_METHOD; - (BOOL)rangeOfWeekendStartDate:(NSDate* _Nullable*)datep interval:(NSTimeInterval*)tip containingDate:(NSDate*)date STUB_METHOD; @property (copy) NSTimeZone* timeZone; - (NSDate*)dateByAddingComponents:(NSDateComponents*)comps toDate:(NSDate*)date options:(NSCalendarOptions)opts; diff --git a/include/Foundation/NSNumberFormatter.h b/include/Foundation/NSNumberFormatter.h index 2d801c5452..d3da20ad9e 100644 --- a/include/Foundation/NSNumberFormatter.h +++ b/include/Foundation/NSNumberFormatter.h @@ -125,7 +125,7 @@ FOUNDATION_EXPORT_CLASS @property (copy) NSString* groupingSeparator; @property BOOL usesGroupingSeparator; @property (copy) NSString* decimalSeparator; -@property BOOL alwaysShowsDecimalSeparator; +@property BOOL alwaysShowsDecimalSeparator STUB_PROPERTY; @property (copy) NSString* currencyDecimalSeparator STUB_PROPERTY; @property NSUInteger groupingSize; @property NSUInteger secondaryGroupingSize; diff --git a/tests/unittests/Foundation/NSDictionaryTests.mm b/tests/unittests/Foundation/NSDictionaryTests.mm index de8608795e..9992fb3e4c 100644 --- a/tests/unittests/Foundation/NSDictionaryTests.mm +++ b/tests/unittests/Foundation/NSDictionaryTests.mm @@ -46,4 +46,14 @@ }]; ASSERT_EQ(0, waitingCount); +} + +TEST(NSDictionary, keysSortedByValueUsingComparator) { + NSDictionary* testDict = @{ @"A" : @2, @"B" : @4, @"C" : @3, @"D" : @1 }; + NSArray* actualArray = [testDict keysSortedByValueUsingComparator: ^(id obj1, id obj2) { + return [obj1 compare:obj2]; + }]; + + NSArray* expectedArray = @[@"D", @"A", @"C", @"B" ]; + ASSERT_OBJCEQ(expectedArray, actualArray); } \ No newline at end of file From d2f5269f8c3888066c165810863020afb50aefca Mon Sep 17 00:00:00 2001 From: Jeyaram Jeyaraj Date: Fri, 29 Apr 2016 15:41:57 -0700 Subject: [PATCH 22/31] Stubbing out defaultQueue. --- Frameworks/Foundation/NSNotificationQueue.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Frameworks/Foundation/NSNotificationQueue.mm b/Frameworks/Foundation/NSNotificationQueue.mm index aee12db218..79b10d1fcf 100644 --- a/Frameworks/Foundation/NSNotificationQueue.mm +++ b/Frameworks/Foundation/NSNotificationQueue.mm @@ -21,10 +21,12 @@ @implementation NSNotificationQueue /** - @Status Interoperable + @Status Stub + @Notes */ + (instancetype)defaultQueue { - return nil; + UNIMPLEMENTED(); + return StubReturn(); } /** From 6b17fe7fc8533b8f429f7c305f501feadf649113 Mon Sep 17 00:00:00 2001 From: Jeyaram Jeyaraj Date: Fri, 29 Apr 2016 17:12:20 -0700 Subject: [PATCH 23/31] Implementation of NSURL getFileSystemRepresentation. Reviewed by: Ben Viglietta ; Raj Seshasankaran ; Dustin Howett (duhowett@microsoft.com) --- Frameworks/Foundation/NSURL.mm | 34 ++++++++++++++++++++++--- include/Foundation/NSURL.h | 2 +- tests/unittests/Foundation/NSURLTests.m | 18 ++++++++++--- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/Frameworks/Foundation/NSURL.mm b/Frameworks/Foundation/NSURL.mm index e4718a966c..07785fdf21 100644 --- a/Frameworks/Foundation/NSURL.mm +++ b/Frameworks/Foundation/NSURL.mm @@ -20,6 +20,7 @@ #import "Foundation/NSMutableArray.h" #import "Foundation/NSNumber.h" #import "Foundation/NSURL.h" +#import "Foundation/NSRange.h" #import "libxml/uri.h" #import "HashFn.h" #import "Etc.h" @@ -1278,12 +1279,37 @@ - (instancetype)initByResolvingBookmarkData:(NSData*)bookmarkData } /** - @Status Stub - @Notes + @Status Caveat + @Notes Supported given the url is a file url. */ - (BOOL)getFileSystemRepresentation:(char*)buffer maxLength:(NSUInteger)maxBufferLength { - UNIMPLEMENTED(); - return StubReturn(); + if ([self isFileURL] && buffer) { + NSUInteger numBytes = 0; + [[self path] getBytes:nullptr + maxLength:maxBufferLength + usedLength:&numBytes + encoding:NSUTF8StringEncoding + options:0 + range:NSMakeRange(0, [[self path] length]) + remainingRange:nullptr]; + + if (maxBufferLength < numBytes + 1) { + return NO; + } + + [[self path] getBytes:buffer + maxLength:maxBufferLength + usedLength:&numBytes + encoding:NSUTF8StringEncoding + options:0 + range:NSMakeRange(0, [[self path] length]) + remainingRange:nullptr]; + + buffer[numBytes] = '\0'; + return YES; + } + + return NO; } /** diff --git a/include/Foundation/NSURL.h b/include/Foundation/NSURL.h index 3343e22ae5..c174304470 100644 --- a/include/Foundation/NSURL.h +++ b/include/Foundation/NSURL.h @@ -173,7 +173,7 @@ FOUNDATION_EXPORT_CLASS bookmarkDataIsStale:(BOOL*)isStale error:(NSError* _Nullable*)error STUB_METHOD; + (NSURL*)fileURLWithFileSystemRepresentation:(const char*)path isDirectory:(BOOL)isDir relativeToURL:(NSURL*)baseURL STUB_METHOD; -- (BOOL)getFileSystemRepresentation:(char*)buffer maxLength:(NSUInteger)maxBufferLength STUB_METHOD; +- (BOOL)getFileSystemRepresentation:(char*)buffer maxLength:(NSUInteger)maxBufferLength; - (instancetype)initFileURLWithFileSystemRepresentation:(const char*)path isDirectory:(BOOL)isDir relativeToURL:(NSURL*)baseURL STUB_METHOD; - (BOOL)isEqual:(id)anObject; - (BOOL)checkResourceIsReachableAndReturnError:(NSError* _Nullable*)error; diff --git a/tests/unittests/Foundation/NSURLTests.m b/tests/unittests/Foundation/NSURLTests.m index 69859ec5ae..3601cdb24f 100644 --- a/tests/unittests/Foundation/NSURLTests.m +++ b/tests/unittests/Foundation/NSURLTests.m @@ -23,7 +23,7 @@ void testNSURLMethod(SEL selector, NSURL* input, id argument, NSURL* expected) { ASSERT_OBJCEQ_MSG(expected, actual, "FAILED: expected != actual"); } -TEST(NSFoundation, NSURLTests) { +TEST(NSURL, NSURLTests) { NSURL* testURL = [[NSURL alloc] initWithString:@"http://www.test.com/home/index.html?Foo#24"]; NSURL* testURL2 = [[NSURL alloc] initWithString:@"http://www.test.com/"]; NSURL* testURL3 = [[NSURL alloc] initWithString:@"http://www.test.com/home/asdf/./index.html?Foo#24"]; @@ -159,7 +159,7 @@ void testNSURLMethod(SEL selector, NSURL* input, id argument, NSURL* expected) { [testURL7 release]; } -TEST(NSFoundation, NSURL_URLByAppendingPathComponent) { +TEST(NSURL, URLByAppendingPathComponent) { NSURL* fileURL = [NSURL fileURLWithPath:@"."]; NSURL* newFileURL = [fileURL URLByAppendingPathComponent:@"Hello.txt"]; ASSERT_TRUE_MSG([newFileURL isFileURL], "The passed URL should be a file URL type"); @@ -170,7 +170,7 @@ void testNSURLMethod(SEL selector, NSURL* input, id argument, NSURL* expected) { ASSERT_OBJCEQ_MSG(fileURLString, newFileURLString, "File URLs do not match!"); } -TEST(NSFoundation, NSURL_URLByAppendingPathExtension) { +TEST(NSURL, URLByAppendingPathExtension) { NSURL* fileURL = [NSURL fileURLWithPath:@"usr"]; NSURL* newFileURL = [fileURL URLByAppendingPathExtension:@"World.txt"]; ASSERT_TRUE_MSG([newFileURL isFileURL], "The passed URL should be a file URL type"); @@ -186,7 +186,7 @@ void testNSURLMethod(SEL selector, NSURL* input, id argument, NSURL* expected) { ASSERT_OBJCEQ_MSG(fileURLString, newFileURLString, "File URLs do not match!"); } -TEST(NSFoundation, NSURL_checkResourceIsReachable) { +TEST(NSURL, CheckResourceIsReachable) { // construct target URL using current directory and relative URL // get test startup full path wchar_t startUpPath[_MAX_PATH]; @@ -211,3 +211,13 @@ void testNSURLMethod(SEL selector, NSURL* input, id argument, NSURL* expected) { "The target %@URL does not exist", targetURLNonExist); } + +TEST(NSURL, GetFileSystemRepresentation) { + NSURL* url = [NSURL fileURLWithPath:@"Hello.txt"]; + ASSERT_OBJCNE(url, nil); + + char resultPath[_MAX_PATH]; + ASSERT_TRUE([url getFileSystemRepresentation:resultPath maxLength:_MAX_PATH]); + NSString* expectedPath = [NSString stringWithFormat:@"%s", resultPath]; + ASSERT_OBJCEQ(@"/Hello.txt", expectedPath); +} From dddfff46c296861f0a5dae2c713139fd547d931f Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 25 Apr 2016 14:56:45 -0700 Subject: [PATCH 24/31] Deep copy NSStrings created from un-owned memory. --- Frameworks/Foundation/NSString.mm | 4 ++++ tests/unittests/Foundation/NSStringTests.m | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/Frameworks/Foundation/NSString.mm b/Frameworks/Foundation/NSString.mm index 988a24d1ad..dbc76af8b3 100644 --- a/Frameworks/Foundation/NSString.mm +++ b/Frameworks/Foundation/NSString.mm @@ -1323,6 +1323,10 @@ - (void)getCharacters:(unichar*)dest { @Status Interoperable */ - (instancetype)copyWithZone:(NSZone*)zone { + if ([self class] == [NSString class] && strType == NSConstructedString_NoOwn) { + // If we don't own the buffer, a deep copy must be made. + return [[[self class] alloc] initWithBytes:u->NoOwnString._address length:u->NoOwnString._length encoding:u->NoOwnString._encoding]; + } return [self retain]; } diff --git a/tests/unittests/Foundation/NSStringTests.m b/tests/unittests/Foundation/NSStringTests.m index e518bd840b..6a1740afab 100644 --- a/tests/unittests/Foundation/NSStringTests.m +++ b/tests/unittests/Foundation/NSStringTests.m @@ -108,4 +108,16 @@ void testUrlCharacterSetEncoding(NSString* decodedString, NSString* encodedStrin ASSERT_EQ(kCFStringEncodingASCII, CFStringGetFastestEncoding(reinterpret_cast(asciiStr))); ASSERT_EQ(kCFStringEncodingUnicode, CFStringGetFastestEncoding(reinterpret_cast(extendedAsciiStr))); ASSERT_EQ(kCFStringEncodingUnicode, CFStringGetFastestEncoding(reinterpret_cast(chineseStr))); +} + +TEST(NSString, UnownedDeepCopy) { + char* buffer = _strdup("Hello World"); + NSString* firstString = [[[NSString alloc] initWithBytesNoCopy:buffer length:11 encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease]; + NSString* secondString = [[firstString copy] autorelease]; + + EXPECT_OBJCEQ(firstString, secondString); + + buffer[0] = '\''; + EXPECT_OBJCNE(firstString, secondString); + free(buffer); } \ No newline at end of file From 969be97aec40a5b7a7bfbcb4ed5a188819e590a2 Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Mon, 25 Apr 2016 14:54:57 -0700 Subject: [PATCH 25/31] Don't assert(0) for aggregate keys in NSDictionary. --- Frameworks/Foundation/NSDictionary.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Frameworks/Foundation/NSDictionary.mm b/Frameworks/Foundation/NSDictionary.mm index 5e70162c71..546dbd51cd 100644 --- a/Frameworks/Foundation/NSDictionary.mm +++ b/Frameworks/Foundation/NSDictionary.mm @@ -249,7 +249,8 @@ - (id)valueForKey:(id)key { const char* keyName = (const char*)[key UTF8String]; if (keyName[0] == '@') { - assert(0); + TraceError(L"NSDictionary", L"Unsupported aggregate key %hs", keyName); + return nil; } id ret = [self objectForKey:key]; From 836a58ad88b0e10aae821606d7ff9f9b13029084 Mon Sep 17 00:00:00 2001 From: Muktesh Khole Date: Mon, 2 May 2016 12:46:10 -0700 Subject: [PATCH 26/31] Replacing internalObject selector with Get method on the comObj, necessitated by recent projection change. --- Frameworks/OpenGLES/EAGLContext.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Frameworks/OpenGLES/EAGLContext.mm b/Frameworks/OpenGLES/EAGLContext.mm index c056bdedf9..76165c3e00 100644 --- a/Frameworks/OpenGLES/EAGLContext.mm +++ b/Frameworks/OpenGLES/EAGLContext.mm @@ -336,7 +336,7 @@ - (BOOL)renderbufferStorage:(int)target fromDrawable:(CAEAGLLayer*)surface { { EGL_WIDTH, _rbWidth, EGL_HEIGHT, _rbHeight, EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER, EGL_TRUE, EGL_FIXED_SIZE_ANGLE, EGL_TRUE, EGL_NONE }; - IUnknown* pUnkRaw = (IUnknown*)[surface.swapChainPanel internalObject]; + IUnknown* pUnkRaw = (IUnknown*)[surface.swapChainPanel comObj].Get(); IInspectable* pSwapChainInspectable; pUnkRaw->QueryInterface(__uuidof(pSwapChainInspectable), (void**)&pSwapChainInspectable); From 0d6a202ba19dcdfa9c2734871a4e8dfa81458b7a Mon Sep 17 00:00:00 2001 From: Ehren Metcalfe Date: Tue, 19 Apr 2016 13:01:38 -0400 Subject: [PATCH 27/31] WOCOperationMode should change UIUserInterfaceIdiom. Support UIModalPresentationFormSheet on tablets (non-fullscreen presentation). Also adds examples to WOCCatalog app including resizing modal via preferredContentSize and toggling tablet mode at runtime. --- Frameworks/StarboardXaml/ApplicationMain.mm | 32 ------- Frameworks/UIKit/UIApplication.mm | 1 + Frameworks/UIKit/UIViewController.mm | 88 +++++++++---------- .../WOCCatalog/ControlsViewController.m | 58 ++++++++++-- .../WOCCatalog/DisplayModeViewController.m | 14 +++ .../WOCCatalog/PopoverViewController.m | 4 +- 6 files changed, 114 insertions(+), 83 deletions(-) diff --git a/Frameworks/StarboardXaml/ApplicationMain.mm b/Frameworks/StarboardXaml/ApplicationMain.mm index fd8e634bef..86ac1a705a 100644 --- a/Frameworks/StarboardXaml/ApplicationMain.mm +++ b/Frameworks/StarboardXaml/ApplicationMain.mm @@ -39,26 +39,6 @@ void SetCACompositorClient(CACompositorClientInterface* client) { _compositorClient = client; } -struct ApplicationProperties { - float width; - float height; - float scale; - std::string name; - bool isTablet; - bool isLandscape; -}; - -ApplicationProperties g_applicationProperties; - -std::string GetAppNameFromPList() { - NSString* appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]; - if (appName != nil) { - return [appName UTF8String]; - } - - return "Starboard"; -} - int ApplicationMainStart( int argc, char* argv[], const char* principalName, const char* delegateName, float windowWidth, float windowHeight) { // Note: We must use nil rather than an empty string for these class names @@ -68,11 +48,6 @@ int ApplicationMainStart( WOCDisplayMode* displayMode = [UIApplication displayMode]; [displayMode _setWindowSize:CGSizeMake(windowWidth, windowHeight)]; - float defaultWidth = GetCACompositor()->screenWidth(); - float defaultHeight = GetCACompositor()->screenHeight(); - float defaultScale = GetCACompositor()->screenScale(); - bool defaultTablet = false; - [NSBundle setMainBundlePath:@"."]; NSDictionary* infoDict = [[NSBundle mainBundle] infoDictionary]; @@ -124,14 +99,7 @@ int ApplicationMainStart( [UIApplication setStartupDisplayMode:displayMode]; } - g_applicationProperties.width = defaultWidth; - g_applicationProperties.height = defaultHeight; - g_applicationProperties.scale = defaultScale; - g_applicationProperties.name = GetAppNameFromPList(); - g_applicationProperties.isTablet = defaultTablet; - [displayMode _updateDisplaySettings]; - GetCACompositor()->setTablet(g_applicationProperties.isTablet); UIApplicationMainInit(argc, argv, principalClassName, delegateClassName, defaultOrientation); return UIApplicationMainLoop(); diff --git a/Frameworks/UIKit/UIApplication.mm b/Frameworks/UIKit/UIApplication.mm index da3d272774..f5995af564 100644 --- a/Frameworks/UIKit/UIApplication.mm +++ b/Frameworks/UIKit/UIApplication.mm @@ -2578,6 +2578,7 @@ - (void)_updateDisplaySettings { break; } + GetCACompositor()->setTablet(_operationMode == WOCOperationModeTablet); GetCACompositor()->setScreenSize(newWidth, newHeight, newMagnification, newRotation); GetCACompositor()->setDeviceSize(newWidth, newHeight); diff --git a/Frameworks/UIKit/UIViewController.mm b/Frameworks/UIKit/UIViewController.mm index 457e2b0090..7fa6191b84 100644 --- a/Frameworks/UIKit/UIViewController.mm +++ b/Frameworks/UIKit/UIViewController.mm @@ -344,14 +344,7 @@ - (CGRect)_orientationRect:(UIInterfaceOrientation)orientation { appFrame = [[UIScreen mainScreen] applicationFrame]; if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - appFrame.size.width = 540; - appFrame.size.height = 575; - - appFrame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - appFrame.size.width / 2.0f; - appFrame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - appFrame.size.height / 2.0f; + appFrame = [self _modalPresentationFormSheetFrame]; } CGRect rect; @@ -386,6 +379,35 @@ - (CGRect)_orientationRect:(UIInterfaceOrientation)orientation { return rect; } +- (CGRect)_modalPresentationFormSheetFrame { + if (!GetCACompositor()->isTablet()) { + // fullscreen on non-tablets + return [[UIScreen mainScreen] applicationFrame]; + } + + CGRect frame; + if (!CGSizeEqualToSize(priv->_preferredContentSize, CGSizeZero)) { + frame.size = priv->_preferredContentSize; + } else { + frame.size.width = 540; + frame.size.height = 620; + } + + CGRect screenFrame = [[UIScreen mainScreen] applicationFrame]; + frame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - frame.size.width / 2.0f; + frame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - frame.size.height / 2.0f; + + return frame; +} + +- (BOOL)_hidesParent { + if (priv->_presentationStyle == UIModalPresentationFormSheet && GetCACompositor()->isTablet()) { + return NO; + } + + return YES; +} + - (void)_setResizeToScreen:(BOOL)resize { priv->_resizeToScreen = TRUE; } @@ -408,14 +430,7 @@ - (void)setOrientationInternal:(UIInterfaceOrientation)orientation animated:(BOO appFrame = [[UIScreen mainScreen] applicationFrame]; } if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - appFrame.size.width = GetCACompositor()->screenWidth(); - appFrame.size.height = GetCACompositor()->screenHeight(); - - appFrame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - appFrame.size.width / 2.0f; - appFrame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - appFrame.size.height / 2.0f; + appFrame = [self _modalPresentationFormSheetFrame]; } switch (orientation) { @@ -787,14 +802,7 @@ - (void)loadView { frame = [[UIScreen mainScreen] applicationFrame]; /** This is correct **/ if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - frame.size.width = 540; - frame.size.height = 575; - - frame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - frame.size.width / 2.0f; - frame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - frame.size.height / 2.0f; + frame = [self _modalPresentationFormSheetFrame]; } UIView* view = [[[UIEmptyController alloc] initWithFrame:frame] autorelease]; @@ -817,14 +825,7 @@ - (void)_doResizeToScreen { } if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - frame.size.width = 540; - frame.size.height = 575; - - frame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - frame.size.width / 2.0f; - frame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - frame.size.height / 2.0f; + frame = [self _modalPresentationFormSheetFrame]; } UIInterfaceOrientation curOrientation = (UIInterfaceOrientation)[[UIApplication sharedApplication] statusBarOrientation]; @@ -858,14 +859,7 @@ - (UIView*)view { frame = [[UIScreen mainScreen] applicationFrame]; if (priv->_presentationStyle == UIModalPresentationFormSheet) { - CGRect screenFrame; - screenFrame = [[UIScreen mainScreen] applicationFrame]; - - frame.size.width = 540; - frame.size.height = 575; - - frame.origin.x = screenFrame.origin.x + screenFrame.size.width / 2.0f - frame.size.width / 2.0f; - frame.origin.y = screenFrame.origin.y + screenFrame.size.height / 2.0f - frame.size.height / 2.0f; + frame = [self _modalPresentationFormSheetFrame]; } UIView* view = [[[UIEmptyController alloc] initWithFrame:frame] autorelease]; @@ -1069,7 +1063,9 @@ - (void)presentViewController:(UIViewController*)controller animated:(BOOL)anima [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; } - [self _notifyViewWillDisappear:animated]; + if ([controller _hidesParent]) { + [self _notifyViewWillDisappear:animated]; + } priv->_modalViewController = controller; priv->_presentedViewController = controller; @@ -1225,7 +1221,9 @@ - (void)_notifyDidAppearAnimated:(UIView*)view { - (void)_transitionStopped:(id)context { UIView* view = [self view]; - [[priv->_parentViewController view] setHidden:TRUE]; + if ([self _hidesParent]) { + [[priv->_parentViewController view] setHidden:TRUE]; + } [self _notifyDidAppearAnimated:view]; [[UIApplication sharedApplication] endIgnoringInteractionEvents]; } @@ -1264,7 +1262,7 @@ - (void)_addToTop:(NSNumber*)animatedValue { g_presentingAnimated = TRUE; [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; [self _notifyViewWillAppear:TRUE]; - } else { + } else if ([self _hidesParent]) { [[priv->_parentViewController view] setHidden:TRUE]; } @@ -1331,7 +1329,9 @@ - (void)_addToTop:(NSNumber*)animatedValue { g_presentingAnimated = FALSE; } - [priv->_parentViewController _notifyViewDidDisappear:animated]; + if ([self _hidesParent]) { + [priv->_parentViewController _notifyViewDidDisappear:animated]; + } } else { TraceVerbose(TAG, L"Modal controller doesn't have a parent!"); } diff --git a/samples/WOCCatalog/WOCCatalog/ControlsViewController.m b/samples/WOCCatalog/WOCCatalog/ControlsViewController.m index b7e76bbcac..bd1ae3fbe5 100644 --- a/samples/WOCCatalog/WOCCatalog/ControlsViewController.m +++ b/samples/WOCCatalog/WOCCatalog/ControlsViewController.m @@ -17,7 +17,14 @@ #import "ControlsViewController.h" #import "PopoverViewController.h" -#define UIPOPOVERCONTROL_ROW 4 +static const int POPOVERCONTROL_ROW = 4; +static const int MODALFORMSHEET_ROW = 5; + +@interface ControlsViewController () + +@property (nonatomic) BOOL resizeModal; + +@end @implementation ControlsViewController @@ -25,8 +32,15 @@ - (void)viewDidLoad { [super viewDidLoad]; } +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:(BOOL)animated]; + + // UIModalPresentationFormSheet shouldn't cover parent with tablet. + assert(!([[self presentedViewController] modalPresentationStyle] == UIModalPresentationFormSheet && [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)); +} + - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { - return 5; + return 6; } - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath { @@ -96,18 +110,35 @@ - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSI cell.textLabel.text = @"UIProgressView"; cell.selectionStyle = UITableViewCellSelectionStyleNone; - } else if (indexPath.row == UIPOPOVERCONTROL_ROW) { + } else if (indexPath.row == POPOVERCONTROL_ROW) { // UIPopoverPresentationController - cell.textLabel.text = @"UIPopupPresentationController (press me)"; + cell.textLabel.text = @"UIPopupPresentationController (press to launch)"; cell.selectionStyle = UITableViewCellSelectionStyleBlue; + } else if (indexPath.row == MODALFORMSHEET_ROW) { + // form sheet modal + + UITableViewCell* subtitleCell = [tableView dequeueReusableCellWithIdentifier:@"MenuSubtitleCell"]; + if (!subtitleCell) { + subtitleCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MenuSubtitleCell"]; + } + + subtitleCell.textLabel.text = @"UIModalPresentationFormSheet (press to launch)"; + subtitleCell.detailTextLabel.text = @"Toggle switch to resize (tablet only)"; + subtitleCell.selectionStyle = UITableViewCellSelectionStyleBlue; + UISwitch* resizeSwitch = [[UISwitch alloc] init]; + resizeSwitch.on = self.resizeModal; + [resizeSwitch addTarget:self action:@selector(toggleResizeModal) forControlEvents:UIControlEventValueChanged]; + subtitleCell.accessoryView = resizeSwitch; + + return subtitleCell; } return cell; } - (NSIndexPath*)tableView:(UITableView*)tableView willSelectRowAtIndexPath:(NSIndexPath*)indexPath { - if (indexPath.row == UIPOPOVERCONTROL_ROW) { + if (indexPath.row == POPOVERCONTROL_ROW || indexPath.row == MODALFORMSHEET_ROW) { return indexPath; } @@ -115,7 +146,7 @@ - (NSIndexPath*)tableView:(UITableView*)tableView willSelectRowAtIndexPath:(NSIn } - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { - if (indexPath.row == UIPOPOVERCONTROL_ROW) { + if (indexPath.row == POPOVERCONTROL_ROW) { // Note: presenting a UIViewController with the UIModalPresentationStyle of Popover does not yet present the view controller // as a popover. UIPopoverController has been depricated in ios9.0. // This work will need to be completed as part of UIPopoverPresentationController work. @@ -133,7 +164,22 @@ - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*) presentationController.permittedArrowDirections = UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionRight; presentationController.sourceView = self.view; presentationController.sourceRect = CGRectMake(100, 100, 100, 100); + } else if (indexPath.row == MODALFORMSHEET_ROW) { + UIViewController* viewController = [[PopoverViewController alloc] initWithImage:[UIImage imageNamed:@"photo1.jpg"]]; + viewController.modalPresentationStyle = UIModalPresentationFormSheet; + + if (self.resizeModal) { + viewController.preferredContentSize = CGSizeMake(200, 200); + } + + [self presentViewController:viewController animated:YES completion:^{ + assert(!([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad && self.view.hidden)); + }]; } } +- (void)toggleResizeModal { + self.resizeModal = !self.resizeModal; +} + @end diff --git a/samples/WOCCatalog/WOCCatalog/DisplayModeViewController.m b/samples/WOCCatalog/WOCCatalog/DisplayModeViewController.m index d9e27b6ca0..df523d8181 100644 --- a/samples/WOCCatalog/WOCCatalog/DisplayModeViewController.m +++ b/samples/WOCCatalog/WOCCatalog/DisplayModeViewController.m @@ -37,6 +37,11 @@ - (void)toggleAdjustWindowSize:(UISwitch*)sender { [UIApplication.displayMode updateDisplaySettings]; } +- (void)toggleTabletMode:(UISwitch*)sender { + UIApplication.displayMode.operationMode = sender.on ? WOCOperationModeTablet : WOCOperationModePhone; + [UIApplication.displayMode updateDisplaySettings]; +} + - (void)toggleScreenAwake:(UISwitch*)sender { [[UIApplication sharedApplication] setIdleTimerDisabled:sender.on]; } @@ -262,6 +267,15 @@ - (id)init { cell.textLabel.text = @"Disable idle screen timer"; [self.rows addObject:cell]; + UISwitch* enableTabletMode = [UISwitch new]; + enableTabletMode.on = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad; + [enableTabletMode addTarget:self action:@selector(toggleTabletMode:) forControlEvents:UIControlEventValueChanged]; + + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MenuCell"]; + cell.accessoryView = enableTabletMode; + cell.textLabel.text = @"Tablet Mode"; + [self.rows addObject:cell]; + fixedWidth = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 20)]; fixedWidth.text = [NSString stringWithFormat:@"%.1f", UIApplication.displayMode.fixedWidth]; fixedWidth.borderStyle = UITextBorderStyleBezel; diff --git a/samples/WOCCatalog/WOCCatalog/PopoverViewController.m b/samples/WOCCatalog/WOCCatalog/PopoverViewController.m index dba17e3a81..22c883a43a 100644 --- a/samples/WOCCatalog/WOCCatalog/PopoverViewController.m +++ b/samples/WOCCatalog/WOCCatalog/PopoverViewController.m @@ -72,10 +72,12 @@ - (void)viewDidLoad { scrollView.maximumZoomScale = 1.; scrollView.minimumZoomScale = minimumScale; scrollView.zoomScale = minimumScale; + + imageView.center = CGPointMake(scrollView.contentSize.width * 0.5, scrollView.contentSize.height * 0.5); } - (void)createLayout { - [scrollView setBackgroundColor:[UIColor whiteColor]]; + [scrollView setBackgroundColor:[UIColor lightGrayColor]]; } - (void)scrollViewDidZoom:(UIScrollView*)aScrollView { From 68412591ece84de75b815755e171a0c7482636d7 Mon Sep 17 00:00:00 2001 From: Ehren Metcalfe Date: Wed, 20 Apr 2016 10:24:00 -0400 Subject: [PATCH 28/31] various accessing of private members switched to use objective-c public accessors in UIViewController.mm --- Frameworks/UIKit/UIViewController.mm | 47 ++++++++++++++-------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/Frameworks/UIKit/UIViewController.mm b/Frameworks/UIKit/UIViewController.mm index 7fa6191b84..b187cfbc36 100644 --- a/Frameworks/UIKit/UIViewController.mm +++ b/Frameworks/UIKit/UIViewController.mm @@ -343,7 +343,7 @@ - (CGRect)_orientationRect:(UIInterfaceOrientation)orientation { appFrame = [[UIScreen mainScreen] applicationFrame]; - if (priv->_presentationStyle == UIModalPresentationFormSheet) { + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { appFrame = [self _modalPresentationFormSheetFrame]; } @@ -386,8 +386,8 @@ - (CGRect)_modalPresentationFormSheetFrame { } CGRect frame; - if (!CGSizeEqualToSize(priv->_preferredContentSize, CGSizeZero)) { - frame.size = priv->_preferredContentSize; + if (!CGSizeEqualToSize([self preferredContentSize], CGSizeZero)) { + frame.size = [self preferredContentSize]; } else { frame.size.width = 540; frame.size.height = 620; @@ -401,7 +401,7 @@ - (CGRect)_modalPresentationFormSheetFrame { } - (BOOL)_hidesParent { - if (priv->_presentationStyle == UIModalPresentationFormSheet && GetCACompositor()->isTablet()) { + if ([self modalPresentationStyle] == UIModalPresentationFormSheet && GetCACompositor()->isTablet()) { return NO; } @@ -424,12 +424,12 @@ - (void)setOrientationInternal:(UIInterfaceOrientation)orientation animated:(BOO [[UIApplication sharedApplication] setStatusBarOrientation:orientation animated:FALSE]; - if (priv->_wantsFullScreenLayout) { + if ([self wantsFullScreenLayout]) { appFrame = [[UIScreen mainScreen] bounds]; } else { appFrame = [[UIScreen mainScreen] applicationFrame]; } - if (priv->_presentationStyle == UIModalPresentationFormSheet) { + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { appFrame = [self _modalPresentationFormSheetFrame]; } @@ -801,7 +801,7 @@ - (void)loadView { CGRect frame = { 0.0f, 0.0f, GetCACompositor()->screenWidth(), GetCACompositor()->screenHeight() }; frame = [[UIScreen mainScreen] applicationFrame]; /** This is correct **/ - if (priv->_presentationStyle == UIModalPresentationFormSheet) { + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { frame = [self _modalPresentationFormSheetFrame]; } @@ -815,16 +815,16 @@ - (void)loadView { } - (void)_doResizeToScreen { - if ((priv->_resizeToScreen && priv->view && priv->_autoresize) || priv->_wantsFullScreenLayout) { + if ((priv->_resizeToScreen && priv->view && priv->_autoresize) || [self wantsFullScreenLayout]) { CGRect frame = { 0.0f, 0.0f, GetCACompositor()->screenHeight(), GetCACompositor()->screenWidth() }; - if (priv->_wantsFullScreenLayout) { + if ([self wantsFullScreenLayout]) { frame = [[UIScreen mainScreen] bounds]; } else { frame = [[UIScreen mainScreen] applicationFrame]; } - if (priv->_presentationStyle == UIModalPresentationFormSheet) { + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { frame = [self _modalPresentationFormSheetFrame]; } UIInterfaceOrientation curOrientation = (UIInterfaceOrientation)[[UIApplication sharedApplication] statusBarOrientation]; @@ -858,7 +858,7 @@ - (UIView*)view { CGRect frame = { 0.0f, 0.0f, GetCACompositor()->screenHeight(), GetCACompositor()->screenWidth() }; frame = [[UIScreen mainScreen] applicationFrame]; - if (priv->_presentationStyle == UIModalPresentationFormSheet) { + if ([self modalPresentationStyle] == UIModalPresentationFormSheet) { frame = [self _modalPresentationFormSheetFrame]; } @@ -1040,7 +1040,7 @@ - (void)presentViewController:(UIViewController*)controller animated:(BOOL)anima if (curController->priv->_visibility != controllerNotVisible) { shouldShow = true; } - curController = curController->priv->_parentViewController; + curController = [curController parentViewController]; } if (!shouldShow) { TraceWarning(TAG, L"Controller is not visible!"); @@ -1125,8 +1125,8 @@ - (void)_dismissTransitionStopped:(id)anim finished:(BOOL)finished { */ - (void)dismissViewControllerAnimated:(BOOL)animated completion:(void (^)(void))completion { if (priv->_modalViewController == nil) { - if (priv->_parentViewController) { - [priv->_parentViewController dismissViewControllerAnimated:animated completion:completion]; + if ([self parentViewController] != nil) { + [[self parentViewController] dismissViewControllerAnimated:animated completion:completion]; return; } TraceWarning(TAG, L"dismissModalViewController invalid!"); @@ -1222,7 +1222,7 @@ - (void)_transitionStopped:(id)context { UIView* view = [self view]; if ([self _hidesParent]) { - [[priv->_parentViewController view] setHidden:TRUE]; + [[[self parentViewController] view] setHidden:TRUE]; } [self _notifyDidAppearAnimated:view]; [[UIApplication sharedApplication] endIgnoringInteractionEvents]; @@ -1233,18 +1233,18 @@ - (void)_addToTop:(NSNumber*)animatedValue { priv->_isRootView = true; - if (priv->_parentViewController != nil) { + if ([self parentViewController] != nil) { // TODO: This implementation satisfies the contract that the popoverPresentationController is not nil when presenting a // UIViewController with modalPresentationType equal to UIModalPresentationPopover. // The full implementation will need to utilize the UIPresentationController for UIViewController presentations - if (priv->_presentationStyle == UIModalPresentationPopover) { + if ([self modalPresentationStyle] == UIModalPresentationPopover) { if (priv->_popoverPresentationController != nil) { [priv->_popoverPresentationController release]; } priv->_popoverPresentationController = [[UIPopoverPresentationController alloc] initWithPresentedViewController:self - presentingViewController:priv->_parentViewController]; + presentingViewController:[self parentViewController]]; if (priv->_presentationController != nil) { [priv->_presentationController release]; @@ -1256,14 +1256,14 @@ - (void)_addToTop:(NSNumber*)animatedValue { float endY = 0; UIView* view = [self view]; - UIWindow* parentWindow = [[priv->_parentViewController view] window]; + UIWindow* parentWindow = [[[self parentViewController] view] window]; if (animated) { g_presentingAnimated = TRUE; [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; [self _notifyViewWillAppear:TRUE]; } else if ([self _hidesParent]) { - [[priv->_parentViewController view] setHidden:TRUE]; + [[[self parentViewController] view] setHidden:TRUE]; } if (parentWindow != nil) { @@ -1330,7 +1330,7 @@ - (void)_addToTop:(NSNumber*)animatedValue { } if ([self _hidesParent]) { - [priv->_parentViewController _notifyViewDidDisappear:animated]; + [[self parentViewController] _notifyViewDidDisappear:animated]; } } else { TraceVerbose(TAG, L"Modal controller doesn't have a parent!"); @@ -1371,8 +1371,9 @@ - (BOOL)isModalInPopover { static UIInterfaceOrientation findOrientation(UIViewController* self) { UIInterfaceOrientation orientation = (UIInterfaceOrientation)[[UIDevice currentDevice] orientation]; - if (self->priv->_parentViewController != nil && [self->priv->_parentViewController _rotationLocked:orientation]) { - UIInterfaceOrientation parentOrientation = (UIInterfaceOrientation)[self->priv->_parentViewController interfaceOrientation]; + UIViewController* parent = [self parentViewController]; + if (parent != nil && [parent _rotationLocked:orientation]) { + UIInterfaceOrientation parentOrientation = (UIInterfaceOrientation)[parent interfaceOrientation]; if (parentOrientation != 0) { orientation = parentOrientation; } From 05a024eb45750a256e9f5e4d21d1e24c7bd83e7b Mon Sep 17 00:00:00 2001 From: Ehren Metcalfe Date: Thu, 28 Apr 2016 16:07:23 -0400 Subject: [PATCH 29/31] UINavigationBar should retain _curItem and _newItem UINavigationItem instances (fix crash on UINavigationBar dealloc) --- Frameworks/UIKit/UINavigationBar.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Frameworks/UIKit/UINavigationBar.mm b/Frameworks/UIKit/UINavigationBar.mm index 34122132d4..ea1baef261 100644 --- a/Frameworks/UIKit/UINavigationBar.mm +++ b/Frameworks/UIKit/UINavigationBar.mm @@ -47,7 +47,7 @@ @implementation UINavigationBar { CGSize _textShadowOffset; idretain _font, _textColor, _textShadowColor; idretaintype(UIImage) _navGradient; - UINavigationItem *_curItem, *_newItem; + idretaintype(UINavigationItem) _curItem, _newItem; idretaintype(UIBarButtonItem) _leftButton, _rightButton; idretaintype(UIBarButtonItem) _backButton; idretaintype(UIView) _titleView; From d21cb918e66e541b2d5272ec3a1cc89d22a8ee0d Mon Sep 17 00:00:00 2001 From: Ehren Metcalfe Date: Thu, 28 Apr 2016 19:29:14 -0400 Subject: [PATCH 30/31] remove nilling out of changed idretaintype instances on dealloc --- Frameworks/UIKit/UINavigationBar.mm | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Frameworks/UIKit/UINavigationBar.mm b/Frameworks/UIKit/UINavigationBar.mm index ea1baef261..b55f59d3a3 100644 --- a/Frameworks/UIKit/UINavigationBar.mm +++ b/Frameworks/UIKit/UINavigationBar.mm @@ -568,24 +568,6 @@ - (void)dealloc { [_curItem _setDelegate:nil]; } - _items = nil; - _font = nil; - _textColor = nil; - _textShadowColor = nil; - _navGradient = nil; - _curItem = nil; - _newItem = nil; - _leftButton = nil; - _rightButton = nil; - _backButton = nil; - _titleView = nil; - _titleLabel = nil; - _titleTextAttributes = nil; - _tintColor = nil; - _barTintColor = nil; - _shadowImage = nil; - _shadowImageView = nil; - [super dealloc]; } From 75a75e539a641449502af244fd1a9694dc2d5681 Mon Sep 17 00:00:00 2001 From: Ben Viglietta Date: Mon, 2 May 2016 13:24:18 -0700 Subject: [PATCH 31/31] Miscellaneous UI fixes to improve emulation of reference platform UIColor is now copyable Subclasses of UIButton can now override the drawable area You can specify an affine transformation in CGPathAddCurveToPoint The lineBreakMode property on NSMutableParagraphStyle can now bet set, although its value still isn't respected --- Frameworks/CoreGraphics/CGPath.mm | 26 ++++++++++++++------- Frameworks/UIKit/NSMutableParagraphStyle.mm | 16 +++++++++++++ Frameworks/UIKit/UIButton.mm | 26 ++++++++++----------- Frameworks/UIKit/UIColor.mm | 5 ++-- include/UIKit/NSMutableParagraphStyle.h | 2 +- include/UIKit/UIButton.h | 11 ++++----- 6 files changed, 53 insertions(+), 33 deletions(-) diff --git a/Frameworks/CoreGraphics/CGPath.mm b/Frameworks/CoreGraphics/CGPath.mm index 3ff1fce95b..ce87c940da 100644 --- a/Frameworks/CoreGraphics/CGPath.mm +++ b/Frameworks/CoreGraphics/CGPath.mm @@ -522,14 +522,22 @@ void CGPathAddQuadCurveToPoint(CGMutablePathRef path, const CGAffineTransform* m } /** - @Status Caveat - @Notes transform property not supported + @Status Interoperable + @Notes */ void CGPathAddCurveToPoint( CGMutablePathRef path, const CGAffineTransform* m, CGFloat cp1x, CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y) { CGPathRef pathObj = path; - assert(!m); + CGPoint cp1 = CGPointMake(cp1x, cp1y); + CGPoint cp2 = CGPointMake(cp2x, cp2y); + CGPoint end = CGPointMake(x, y); + + if (m) { + cp1 = CGPointApplyAffineTransform(cp1, *m); + cp2 = CGPointApplyAffineTransform(cp2, *m); + end = CGPointApplyAffineTransform(end, *m); + } if (pathObj->_count + 1 >= pathObj->_max) { pathObj->_max += 32; @@ -539,12 +547,12 @@ void CGPathAddCurveToPoint( int count = pathObj->_count; pathObj->_components[count].type = pathComponentCurve; - pathObj->_components[count].ctp.x1 = cp1x; - pathObj->_components[count].ctp.y1 = cp1y; - pathObj->_components[count].ctp.x2 = cp2x; - pathObj->_components[count].ctp.y2 = cp2y; - pathObj->_components[count].ctp.x = x; - pathObj->_components[count].ctp.y = y; + pathObj->_components[count].ctp.x1 = cp1.x; + pathObj->_components[count].ctp.y1 = cp1.y; + pathObj->_components[count].ctp.x2 = cp2.x; + pathObj->_components[count].ctp.y2 = cp2.y; + pathObj->_components[count].ctp.x = end.x; + pathObj->_components[count].ctp.y = end.y; pathObj->_count++; } diff --git a/Frameworks/UIKit/NSMutableParagraphStyle.mm b/Frameworks/UIKit/NSMutableParagraphStyle.mm index c87f85e0ed..f2e19a039f 100644 --- a/Frameworks/UIKit/NSMutableParagraphStyle.mm +++ b/Frameworks/UIKit/NSMutableParagraphStyle.mm @@ -52,6 +52,22 @@ - (void)removeTabStop:(NSTextTab*)anObject { UNIMPLEMENTED(); } +/** + @Status Caveat + @Notes Setting this property has no effect +*/ +- (void)setLineBreakMode:(NSLineBreakMode)lineBreakMode { + _lineBreakMode = lineBreakMode; +} + +/** + @Status Interoperable + @Notes +*/ +- (NSLineBreakMode)lineBreakMode { + return _lineBreakMode; +} + /** @Status Stub @Notes diff --git a/Frameworks/UIKit/UIButton.mm b/Frameworks/UIKit/UIButton.mm index 0c6b70c714..2c298384c6 100644 --- a/Frameworks/UIKit/UIButton.mm +++ b/Frameworks/UIKit/UIButton.mm @@ -1013,8 +1013,9 @@ - (void)layoutSubviews { bounds = [self bounds]; bounds = UIEdgeInsetsInsetRect(bounds, contentInsets); - CGRect textFrame = calcTitleRect(self, bounds); - CGRect imageFrame = calcImageRect(self, bounds); + CGRect contentFrame = [self contentRectForBounds:bounds]; + CGRect textFrame = [self titleRectForContentRect:contentFrame]; + CGRect imageFrame = [self imageRectForContentRect:contentFrame]; [_label setFrame:textFrame]; [_imageView setFrame:imageFrame]; @@ -1116,35 +1117,32 @@ - (CGSize)intrinsicContentSize { } /** - @Status Stub + @Status Caveat + @Notes Overriding this method has no effect */ - (CGRect)backgroundRectForBounds:(CGRect)bounds { - UNIMPLEMENTED(); - return StubReturn(); + return bounds; } /** - @Status Stub + @Status Interoperable */ - (CGRect)contentRectForBounds:(CGRect)bounds { - UNIMPLEMENTED(); - return StubReturn(); + return bounds; } /** - @Status Stub + @Status Interoperable */ - (CGRect)imageRectForContentRect:(CGRect)contentRect { - UNIMPLEMENTED(); - return StubReturn(); + return calcImageRect(self, contentRect); } /** - @Status Stub + @Status Interoperable */ - (CGRect)titleRectForContentRect:(CGRect)contentRect { - UNIMPLEMENTED(); - return StubReturn(); + return calcTitleRect(self, contentRect); } /** diff --git a/Frameworks/UIKit/UIColor.mm b/Frameworks/UIKit/UIColor.mm index 63306b43af..2a12de0e7d 100644 --- a/Frameworks/UIKit/UIColor.mm +++ b/Frameworks/UIKit/UIColor.mm @@ -184,11 +184,10 @@ @implementation UIColor { } /** - @Status Stub + @Status Interoperable */ - (instancetype)copyWithZone:(NSZone*)zone { - UNIMPLEMENTED(); - return StubReturn(); + return [self retain]; } /** diff --git a/include/UIKit/NSMutableParagraphStyle.h b/include/UIKit/NSMutableParagraphStyle.h index bf14b1eb6d..f32b9d846a 100644 --- a/include/UIKit/NSMutableParagraphStyle.h +++ b/include/UIKit/NSMutableParagraphStyle.h @@ -30,7 +30,7 @@ UIKIT_EXPORT_CLASS @property (nonatomic) CGFloat firstLineHeadIndent STUB_PROPERTY; @property (nonatomic) CGFloat headIndent STUB_PROPERTY; @property (nonatomic) CGFloat tailIndent STUB_PROPERTY; -@property (nonatomic) NSLineBreakMode lineBreakMode STUB_PROPERTY; +@property (nonatomic) NSLineBreakMode lineBreakMode; @property (nonatomic) CGFloat maximumLineHeight STUB_PROPERTY; @property (nonatomic) CGFloat minimumLineHeight STUB_PROPERTY; @property (nonatomic) CGFloat lineSpacing STUB_PROPERTY; diff --git a/include/UIKit/UIButton.h b/include/UIKit/UIButton.h index 524c8f45c8..6dd84394dd 100644 --- a/include/UIKit/UIButton.h +++ b/include/UIKit/UIButton.h @@ -60,12 +60,11 @@ UIKIT_EXPORT_CLASS UIFocusEnvironment, UITraitEnvironment> -+ (id)buttonWithType:(UIButtonType)buttonType; -+ (instancetype)buttonWithType:(UIButtonType)buttonType STUB_METHOD; -- (CGRect)backgroundRectForBounds:(CGRect)bounds STUB_METHOD; -- (CGRect)contentRectForBounds:(CGRect)bounds STUB_METHOD; -- (CGRect)imageRectForContentRect:(CGRect)contentRect STUB_METHOD; -- (CGRect)titleRectForContentRect:(CGRect)contentRect STUB_METHOD; ++ (instancetype)buttonWithType:(UIButtonType)buttonType; +- (CGRect)backgroundRectForBounds:(CGRect)bounds; +- (CGRect)contentRectForBounds:(CGRect)bounds; +- (CGRect)imageRectForContentRect:(CGRect)contentRect; +- (CGRect)titleRectForContentRect:(CGRect)contentRect; - (NSAttributedString*)attributedTitleForState:(UIControlState)state STUB_METHOD; - (NSString*)titleForState:(UIControlState)state; - (UIColor*)titleColorForState:(UIControlState)state;