Skip to content

Commit 75ed91e

Browse files
committed
XAML-backed controls - UIActivityIndicatorView hooked up via an IBOutlet; Xib2Xaml updates - fixed canvas placement; fix bug in UISlider
CHANGES ======= 1. UIActivityIndicatorView can now be controlled via its IBOutlet using XAML markup 2. Xib2Xaml updates - fixed UISlider minValue bug; remove special handling of TextBox and Button width and height; handle TextAlignment markup in TextBlock/UILabel 3. Xib2Xaml x:Name will be updated to the IBOutlet property attribute using a second pass over the XIB <placeholder> tag 4. General clean up - consolidate UIKit controls headers so they are consistent NOTE ==== 1. ProgressBar is outputted by X2X when we require ProgressRing (manually changed the markup for now) 2. UIActivityIndicatorViewStyle default is UIActivityIndicatorViewStyleWhite according to their documentation but it looks like it's actually UIActivityIndicatorViewStyleGray under the simulator TESTS ===== Unit tests - PASSED Verified using XAMLTest sample app (desktop/phone)
1 parent 89ec5fe commit 75ed91e

File tree

9 files changed

+83
-58
lines changed

9 files changed

+83
-58
lines changed

Frameworks/UIKit/UIActivityIndicatorView.mm

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,26 @@
1414
//
1515
//******************************************************************************
1616

17-
#import "Starboard.h"
18-
#import <UIKit/UIKit.h>
19-
#import <UWP/WindowsUIXamlControls.h>
20-
2117
#import "AssertARCEnabled.h"
18+
#import <Starboard.h>
19+
#import <StubReturn.h>
20+
2221
#import "XamlUtilities.h"
2322

23+
#import <UWP/WindowsUIXamlControls.h>
24+
2425
static const int c_normalSquareLength = 20;
2526
static const int c_largeSquareLength = 37;
2627

2728
@implementation UIActivityIndicatorView {
2829
BOOL _hidesWhenStopped;
2930
BOOL _isAnimating;
3031
BOOL _startAnimating;
32+
3133
StrongId<UIColor> _color;
3234
StrongId<WXCProgressRing> _progressRing;
3335
StrongId<UIView> _subView;
36+
3437
UIActivityIndicatorViewStyle _style;
3538
}
3639

@@ -40,7 +43,7 @@ @implementation UIActivityIndicatorView {
4043
*/
4144
- (instancetype)initWithCoder:(NSCoder*)coder {
4245
if (self = [super initWithCoder:coder]) {
43-
[self _UIActivityIndicatorView_initInternal];
46+
[self _UIActivityIndicatorView_initInternal:nil];
4447

4548
if ([coder containsValueForKey:@"UIHidesWhenStopped"]) {
4649
[self setHidesWhenStopped:[coder decodeInt32ForKey:@"UIHidesWhenStopped"]];
@@ -84,6 +87,7 @@ - (void)awakeFromNib {
8487
if (_startAnimating) {
8588
[self startAnimating];
8689
}
90+
8791
[super awakeFromNib];
8892
}
8993

@@ -92,19 +96,25 @@ - (void)awakeFromNib {
9296
*/
9397
- (instancetype)initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style {
9498
if (self = [super initWithFrame:CGRectZero]) {
95-
[self _UIActivityIndicatorView_initInternal];
99+
[self _UIActivityIndicatorView_initInternal:nil];
96100
[self setActivityIndicatorViewStyle:style];
97101
}
102+
98103
return self;
99104
}
100105

101106
/**
102107
@Status Interoperable
103108
*/
104109
- (instancetype)initWithFrame:(CGRect)frame {
110+
return [self _initWithFrame:frame xamlElement:nil];
111+
}
112+
113+
- (instancetype)_initWithFrame:(CGRect)frame xamlElement:(WXFrameworkElement*)xamlElement {
105114
if (self = [super initWithFrame:frame]) {
106-
[self _UIActivityIndicatorView_initInternal];
115+
[self _UIActivityIndicatorView_initInternal:xamlElement];
107116
}
117+
108118
return self;
109119
}
110120

@@ -117,15 +127,20 @@ - (void)setFrame:(CGRect)frame {
117127
_subView.center = { self.center.x - self.frame.origin.x, self.center.y - self.frame.origin.y };
118128
}
119129

120-
- (void)_UIActivityIndicatorView_initInternal {
121-
_progressRing = [WXCProgressRing make];
130+
- (void)_UIActivityIndicatorView_initInternal:(WXFrameworkElement*)xamlElement {
131+
if (xamlElement != nil && [xamlElement isKindOfClass:[WXCProgressRing class]]) {
132+
_progressRing = static_cast<WXCProgressRing*>(xamlElement);
133+
} else {
134+
_progressRing = [WXCProgressRing make];
135+
}
136+
122137
_subView = [[UIView alloc] initWithFrame:CGRectZero];
123138

124139
[_subView setNativeElement:_progressRing];
125140
[self addSubview:_subView];
126141

127-
_isAnimating = FALSE;
128-
[self setHidesWhenStopped:TRUE];
142+
_isAnimating = NO;
143+
[self setHidesWhenStopped:YES];
129144
[self setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhite];
130145
}
131146

@@ -139,7 +154,7 @@ - (void)setHidesWhenStopped:(BOOL)shouldhide {
139154
_hidesWhenStopped = shouldhide;
140155

141156
if (_hidesWhenStopped && !_isAnimating) {
142-
[self setHidden:TRUE];
157+
[self setHidden:YES];
143158
}
144159
}
145160

@@ -192,9 +207,9 @@ - (void)startAnimating {
192207
return;
193208
}
194209

195-
_isAnimating = TRUE;
196-
[self setHidden:FALSE];
197-
[_progressRing setIsActive:TRUE];
210+
_isAnimating = YES;
211+
[self setHidden:NO];
212+
[_progressRing setIsActive:YES];
198213
}
199214

200215
/**
@@ -203,12 +218,12 @@ - (void)startAnimating {
203218
*/
204219
- (void)stopAnimating {
205220
if (_isAnimating) {
206-
_isAnimating = FALSE;
221+
_isAnimating = NO;
207222
}
208223

209-
[_progressRing setIsActive:FALSE];
224+
[_progressRing setIsActive:YES];
210225
if (_hidesWhenStopped) {
211-
[self setHidden:TRUE];
226+
[self setHidden:NO];
212227
}
213228
}
214229

Frameworks/UIKit/UISlider.mm

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@
1515
//******************************************************************************
1616

1717
#import "AssertARCEnabled.h"
18-
#import "Starboard.h"
19-
#import "StubReturn.h"
20-
#import "UIKit/UIView.h"
21-
#import "UIKit/UIControl.h"
22-
#import "UIKit/UIImage.h"
23-
#import "UIKit/UIImageView.h"
24-
#import "UIKit/UIGestureRecognizer.h"
25-
#import "UIKit/UISlider.h"
18+
#import <Starboard.h>
19+
#import <StubReturn.h>
20+
21+
#import <UIKit/UIView.h>
22+
#import <UIKit/UIControl.h>
23+
#import <UIKit/UIImage.h>
24+
#import <UIKit/UIImageView.h>
25+
#import <UIKit/UIGestureRecognizer.h>
26+
#import <UIKit/UISlider.h>
2627

2728
#import "UIGestureRecognizerInternal.h"
29+
2830
#import "UWP/WindowsUIXamlControls.h"
2931

3032
static const double c_defaultStepFrequency = 0.1;
@@ -37,6 +39,7 @@ @implementation UISlider {
3739
// _rootPanel, which is a panel that holds the xaml slider and minimumValueImage and maximumValueImage.
3840
StrongId<WXCGrid> _rootPanel;
3941
StrongId<WXCSlider> _xamlSlider;
42+
4043
EventRegistrationToken _manipulationStartingEvent;
4144
EventRegistrationToken _manipulationCompletedEvent;
4245
EventRegistrationToken _valueChangedEvent;

Frameworks/UIKit/UITextField.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ @implementation UITextField {
6161
StrongId<UIColor> _textColor;
6262
StrongId<UIColor> _backgroundColor;
6363
StrongId<UIImage> _backgroundImage;
64+
6465
UITextAlignment _alignment;
6566
UITextBorderStyle _borderStyle;
67+
6668
BOOL _secureTextMode;
6769
BOOL _isFirstResponder;
6870

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Page x:Class="IslandwoodAutoGenNamespace.MainViewController" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
33
<Canvas>
4-
<TextBlock x:Name="label" Width="208" Height="21" Canvas.Left="8" Canvas.Top="25" Text="XAML Test" Foreground="#FF000000" />
5-
<Button x:Name="button" Width="232" Height="54" Canvas.Left="-4" Canvas.Top="113" MinWidth="0" MinHeight="0" Content="Let's do this" />
6-
<TextBox x:Name="text" Width="245" Height="54" Canvas.Left="-4" Canvas.Top="59" MinWidth="0" MinHeight="0" TextWrapping="Wrap" />
7-
<ProgressBar x:Name="spinner" Width="20" Height="20" Canvas.Left="102" Canvas.Top="163" />
4+
<TextBlock x:Name="label" Width="208" Height="21" Canvas.Left="8" Canvas.Top="25" Text="XAML Test" TextAlignment="center" Foreground="#FF000000" />
5+
<Button x:Name="button" Width="208" Height="30" Canvas.Left="8" Canvas.Top="125" Content="Let's do this" />
6+
<TextBox x:Name="text" Width="221" Height="30" Canvas.Left="8" Canvas.Top="71" TextWrapping="Wrap" />
7+
<ProgressRing x:Name="spinner" Width="20" Height="20" Canvas.Left="102" Canvas.Top="163" />
88
<Slider x:Name="slider" Width="118" Height="31" Canvas.Left="59" Canvas.Top="191" Value="0.5" Minimum="0" Maximum="1" />
99
</Canvas>
1010
</Page>

samples/XAMLTest/XamlTest/MainViewController.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ - (void)viewDidLoad {
2929
self.slider.value = 0.33;
3030

3131
// Spinners should be spinning
32+
[self.spinner setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
3233
[self.spinner startAnimating];
3334
}
3435

tools/vsimporter/xib2xaml/xib2xaml/Handlers/LabelHandler.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ internal class LabelHandler : ViewHandler
4747
// TextBlock doesn't like inlines as content in attribute form...
4848
GetAndSetValue(tag, domObject, "text", domObject.Type.GetMember("Text"));
4949

50+
GetAndSetValue(tag, domObject, "textAlignment", domObject.Type.GetMember("TextAlignment"));
51+
5052
var backgroundColor = GetElementWithMatchingAttribute(tag, "key", "textColor");
5153
if (backgroundColor != null)
5254
{

tools/vsimporter/xib2xaml/xib2xaml/Handlers/SliderHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ internal class SliderHandler : ViewHandler
4949
var maxValue = float.Parse(tag.Attribute(XName.Get("maxValue")).Value);
5050

5151
domObject.SetMemberValue("Value", value.ToString());
52-
domObject.SetMemberValue("Minimum", maxValue.ToString());
52+
domObject.SetMemberValue("Minimum", minValue.ToString());
5353
domObject.SetMemberValue("Maximum", maxValue.ToString());
5454
}
5555
}

tools/vsimporter/xib2xaml/xib2xaml/Handlers/ViewHandler.cs

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ protected static void SetColor(XamlDomObject domObject, XElement color, XamlMemb
243243
{
244244
string value = null;
245245

246-
//Image doesn't have a background but the XIB file allows setting it
246+
// Image doesn't have a background but the XIB file allows setting it
247247
if (colorMember == null && domObject.Type.UnderlyingType == typeof(Image))
248248
{
249249
return;
@@ -364,32 +364,10 @@ protected static void GetDimensions(XElement element, XamlDomObject domObject)
364364
var widthAttr = frame.Attribute(XName.Get("width"));
365365
var heightAttr = frame.Attribute(XName.Get("height"));
366366

367-
// Certain controls have a 12 pixel border around them. Make them look normal
368-
if (domObject.Type.CanAssignTo(domObject.SchemaContext.GetXamlType(typeof(TextBox))) ||
369-
domObject.Type.CanAssignTo(domObject.SchemaContext.GetXamlType(typeof(Button)))
370-
)
371-
{
372-
var left = int.Parse(xAttr.Value) - 12; // XamlXibReader.WIDTHMULTIPLIER);
373-
var top = int.Parse(yAttr.Value) - 12; // * XamlXibReader.HEIGHTMULTIPLIER);
374-
var width = int.Parse(widthAttr.Value) + 24; // * XamlXibReader.WIDTHMULTIPLIER);
375-
var height = int.Parse(heightAttr.Value) + 24; // * XamlXibReader.HEIGHTMULTIPLIER);
376-
377-
domObject.SetAttachableMemberValue(typeof(Canvas), "Left", left.ToString());
378-
domObject.SetAttachableMemberValue(typeof(Canvas), "Top", top.ToString());
379-
380-
domObject.SetMemberValue("Width", width.ToString());
381-
domObject.SetMemberValue("Height", height.ToString());
382-
383-
domObject.SetMemberValue("MinWidth", "0");
384-
domObject.SetMemberValue("MinHeight", "0");
385-
}
386-
else
387-
{
388-
domObject.SetAttachableMemberValue(typeof(Canvas), "Left", xAttr.Value);
389-
domObject.SetAttachableMemberValue(typeof(Canvas), "Top", yAttr.Value);
390-
domObject.SetMemberValue("Width", widthAttr.Value);
391-
domObject.SetMemberValue("Height", heightAttr.Value);
392-
}
367+
domObject.SetAttachableMemberValue(typeof(Canvas), "Left", xAttr.Value);
368+
domObject.SetAttachableMemberValue(typeof(Canvas), "Top", yAttr.Value);
369+
domObject.SetMemberValue("Width", widthAttr.Value);
370+
domObject.SetMemberValue("Height", heightAttr.Value);
393371
}
394372
else
395373
{

tools/vsimporter/xib2xaml/xib2xaml/XamlXibReader.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,33 @@ from outletNode in placeholderTag.Descendants(XName.Get("outlet"))
134134
}
135135
}
136136

137+
// Second pass over the outlets to insert x:Name and x:Bind against added controls
138+
WireNamesAndEvents(placeholderTag);
139+
137140
return rootDomObject;
138141
}
139142

143+
private void WireNamesAndEvents(XElement placeholderTag)
144+
{
145+
// Handle names
146+
foreach (var outletElement in placeholderTag.Descendants(XName.Get("outlet")))
147+
{
148+
XamlDomObject targetObject;
149+
var destinationId = outletElement.Attribute(XName.Get("destination")).Value;
150+
if (IdToObjectMap.TryGetValue(destinationId, out targetObject))
151+
{
152+
var name = outletElement.Attribute(XName.Get("property")).Value;
153+
if (!string.IsNullOrWhiteSpace(name))
154+
{
155+
// x:Name is always the first element so replace it with the outlet property
156+
targetObject.MemberNodes[0] = new XamlDomMember(XamlLanguage.Name, name);
157+
}
158+
}
159+
}
160+
161+
// TODO: Handle events
162+
}
163+
140164
internal static XElement GetReference(XDocument document, string reference)
141165
{
142166
var elements = from objectTag in document.Descendants()

0 commit comments

Comments
 (0)