[All] Basic Right-To-Left Support (#1222)
* Restart RTL work * Remove IsInherited flag as it never got used * [Core] Unit tests * [Core] FlowDirection * Add FlowDirectionGallery * Android gallery supports RTL Need to set minSdkVersion to 17 to test * iOS gallery supports RTL * UWP gallery supports RTL * [Android] Implement FlowDirection * [iOS] Implement FlowDirection * [macOS] Implement FlowDirection * [UWP] Implement FlowDirection * Update docs * [Core] Simplify EffectiveFlowDirection enum & expose helper extensions Also, TEST TEST TEST * Update docs
This commit is contained in:
Родитель
0a0f8f092e
Коммит
d3d59ee4f0
|
@ -16,7 +16,7 @@
|
|||
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" />
|
||||
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
||||
<application android:label="AndroidControlGallery">
|
||||
<application android:label="AndroidControlGallery" android:supportsRtl="true">
|
||||
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
|
||||
</application>
|
||||
</manifest>
|
|
@ -209,7 +209,7 @@ namespace Xamarin.Forms.ControlGallery.WP8
|
|||
//
|
||||
// If a compiler error is hit then ResourceFlowDirection is missing from
|
||||
// the resource file.
|
||||
FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), AppResources.ResourceFlowDirection);
|
||||
System.Windows.FlowDirection flow = (System.Windows.FlowDirection)Enum.Parse(typeof(System.Windows.FlowDirection), AppResources.ResourceFlowDirection);
|
||||
RootFrame.FlowDirection = flow;
|
||||
}
|
||||
catch
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
</Dependencies>
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
<Resource Language="en" />
|
||||
<Resource Language="ar" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="Xamarin.Forms.ControlGallery.WindowsUniversal.App">
|
||||
|
|
|
@ -96,6 +96,13 @@
|
|||
<string>{320, 480}</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleLocalizations</key>
|
||||
<array>
|
||||
<string>en</string>
|
||||
<string>ar</string>
|
||||
</array>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads </key>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
<MtouchUseLlvm>False</MtouchUseLlvm>
|
||||
<MtouchUseThumb>False</MtouchUseThumb>
|
||||
<MtouchOptimizePNGs>True</MtouchOptimizePNGs>
|
||||
<MtouchI18n />
|
||||
<MtouchI18n>mideast</MtouchI18n>
|
||||
<BuildIpa>True</BuildIpa>
|
||||
<IpaMetadata />
|
||||
<IpaPackageName />
|
||||
|
@ -132,6 +132,9 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'AppStore|iPhoneSimulator'">
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Default' ">
|
||||
<AppExtensionDebugBundleId />
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BrokenImageSourceHandler.cs" />
|
||||
<Compile Include="BrokenNativeControl.cs" />
|
||||
|
|
|
@ -0,0 +1,429 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xamarin.Forms.Controls
|
||||
{
|
||||
|
||||
public class FlowDirectionGalleryLandingPage : ContentPage
|
||||
{
|
||||
FlowDirection DeviceDirection => Device.FlowDirection;
|
||||
|
||||
public FlowDirectionGalleryLandingPage()
|
||||
{
|
||||
|
||||
var np = new Button { Text = "Try NavigationPage", Command = new Command(() => { PushNavigationPage(DeviceDirection); }) };
|
||||
var mdp = new Button { Text = "Try MasterDetailPage", Command = new Command(() => { PushMasterDetailPage(DeviceDirection); }) };
|
||||
var crp = new Button { Text = "Try CarouselPage", Command = new Command(() => { PushCarouselPage(DeviceDirection); }) };
|
||||
var tp = new Button { Text = "Try TabbedPage", Command = new Command(() => { PushTabbedPage(DeviceDirection); }) };
|
||||
var cp = new Button { Text = "Try ContentPage", Command = new Command(() => { PushContentPage(DeviceDirection); }) };
|
||||
|
||||
Content = new StackLayout
|
||||
{
|
||||
Children = {
|
||||
new Label { Text = "Click a button below to swap the MainPage of the app." },
|
||||
np,
|
||||
mdp,
|
||||
crp,
|
||||
tp,
|
||||
cp
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void PushNavigationPage(FlowDirection direction)
|
||||
{
|
||||
((App)Application.Current).SetMainPage(new FlowDirectionGalleryNP(direction));
|
||||
}
|
||||
|
||||
public static void PushMasterDetailPage(FlowDirection direction)
|
||||
{
|
||||
((App)Application.Current).SetMainPage(new FlowDirectionGalleryMDP(direction));
|
||||
}
|
||||
|
||||
public static void PushCarouselPage(FlowDirection direction)
|
||||
{
|
||||
((App)Application.Current).SetMainPage(new FlowDirectionGalleryCarP(direction));
|
||||
}
|
||||
|
||||
public static void PushTabbedPage(FlowDirection direction)
|
||||
{
|
||||
((App)Application.Current).SetMainPage(new FlowDirectionGalleryTP(direction));
|
||||
}
|
||||
|
||||
public static void PushContentPage(FlowDirection direction)
|
||||
{
|
||||
((App)Application.Current).SetMainPage(new FlowDirectionGalleryCP(direction)
|
||||
{
|
||||
FlowDirection = direction
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class FlowDirectionGalleryNP : NavigationPage
|
||||
{
|
||||
public FlowDirectionGalleryNP(FlowDirection direction)
|
||||
{
|
||||
FlowDirection = direction;
|
||||
Navigation.PushAsync(new FlowDirectionGalleryCP(direction));
|
||||
Navigation.PushAsync(new FlowDirectionGalleryCP(direction));
|
||||
}
|
||||
}
|
||||
|
||||
public class FlowDirectionGalleryMDP : MasterDetailPage
|
||||
{
|
||||
public FlowDirectionGalleryMDP(FlowDirection direction)
|
||||
{
|
||||
FlowDirection = direction;
|
||||
Master = new FlowDirectionGalleryCP(direction) { Title = "Master", BackgroundColor = Color.Red };
|
||||
Detail = new FlowDirectionGalleryCP(direction) { Title = "Detail" };
|
||||
IsPresented = true;
|
||||
}
|
||||
}
|
||||
|
||||
public class FlowDirectionGalleryCarP : CarouselPage
|
||||
{
|
||||
public FlowDirectionGalleryCarP(FlowDirection direction)
|
||||
{
|
||||
FlowDirection = direction;
|
||||
Children.Add(new FlowDirectionGalleryCP(direction) { Title = "1" });
|
||||
Children.Add(new FlowDirectionGalleryCP(direction) { Title = "2" });
|
||||
Children.Add(new FlowDirectionGalleryCP(direction) { Title = "3" });
|
||||
}
|
||||
}
|
||||
|
||||
public class FlowDirectionGalleryTP : TabbedPage
|
||||
{
|
||||
public FlowDirectionGalleryTP(FlowDirection direction)
|
||||
{
|
||||
FlowDirection = direction;
|
||||
Children.Add(new FlowDirectionGalleryCP(direction) { Title = "1", BackgroundColor = Color.Red });
|
||||
Children.Add(new FlowDirectionGalleryCP(direction) { Title = "2", BackgroundColor = Color.Orange });
|
||||
Children.Add(new FlowDirectionGalleryCP(direction) { Title = "3", BackgroundColor = Color.Yellow });
|
||||
}
|
||||
}
|
||||
|
||||
public class FlowDirectionGalleryCP : ContentPage
|
||||
{
|
||||
FlowDirection DeviceDirection => Device.FlowDirection;
|
||||
|
||||
Page ParentPage => (Parent as Page) ?? this;
|
||||
|
||||
public FlowDirectionGalleryCP(FlowDirection direction)
|
||||
{
|
||||
var item = new ToolbarItem
|
||||
{
|
||||
Icon = "coffee.png",
|
||||
Text = "Item 1",
|
||||
};
|
||||
|
||||
var item2 = new ToolbarItem
|
||||
{
|
||||
Icon = "bank.png",
|
||||
Text = "Item 2",
|
||||
};
|
||||
|
||||
ToolbarItems.Add(item);
|
||||
ToolbarItems.Add(item2);
|
||||
|
||||
Title = "Flow Direction Gallery";
|
||||
NavigationPage.SetHasBackButton(this, true);
|
||||
NavigationPage.SetBackButtonTitle(this, "Back");
|
||||
SetContent(direction);
|
||||
}
|
||||
|
||||
void SetContent(FlowDirection direction)
|
||||
{
|
||||
var hOptions = LayoutOptions.Start;
|
||||
|
||||
var imageCell = new DataTemplate(typeof(ImageCell));
|
||||
imageCell.SetBinding(ImageCell.ImageSourceProperty, ".");
|
||||
imageCell.SetBinding(ImageCell.TextProperty, ".");
|
||||
|
||||
var textCell = new DataTemplate(typeof(TextCell));
|
||||
textCell.SetBinding(TextCell.DetailProperty, ".");
|
||||
|
||||
var entryCell = new DataTemplate(typeof(EntryCell));
|
||||
entryCell.SetBinding(EntryCell.TextProperty, ".");
|
||||
|
||||
var switchCell = new DataTemplate(typeof(SwitchCell));
|
||||
switchCell.SetBinding(SwitchCell.OnProperty, ".");
|
||||
switchCell.SetValue(SwitchCell.TextProperty, "Switch Cell!");
|
||||
|
||||
var vc = new ViewCell
|
||||
{
|
||||
View = new StackLayout
|
||||
{
|
||||
Children = { new Label { HorizontalOptions = hOptions, Text = "View Cell! I have context actions." } }
|
||||
}
|
||||
};
|
||||
|
||||
var a1 = new MenuItem { Text = "First" };
|
||||
vc.ContextActions.Add(a1);
|
||||
var a2 = new MenuItem { Text = "Second" };
|
||||
vc.ContextActions.Add(a2);
|
||||
|
||||
var viewCell = new DataTemplate(() => vc);
|
||||
|
||||
var relayout = new Switch
|
||||
{
|
||||
IsToggled = true,
|
||||
HorizontalOptions = LayoutOptions.End,
|
||||
VerticalOptions = LayoutOptions.Center
|
||||
};
|
||||
|
||||
var flipButton = new Button
|
||||
{
|
||||
Text = direction == FlowDirection.RightToLeft ? "Switch to Left To Right" : "Switch to Right To Left",
|
||||
HorizontalOptions = LayoutOptions.StartAndExpand,
|
||||
VerticalOptions = LayoutOptions.Center
|
||||
};
|
||||
|
||||
flipButton.Clicked += (s, e) =>
|
||||
{
|
||||
FlowDirection newDirection;
|
||||
if (direction == FlowDirection.LeftToRight || direction == FlowDirection.MatchParent)
|
||||
newDirection = FlowDirection.RightToLeft;
|
||||
else
|
||||
newDirection = FlowDirection.LeftToRight;
|
||||
|
||||
if (relayout.IsToggled)
|
||||
{
|
||||
ParentPage.FlowDirection = newDirection;
|
||||
|
||||
direction = newDirection;
|
||||
|
||||
flipButton.Text = direction == FlowDirection.RightToLeft ? "Switch to Left To Right" : "Switch to Right To Left";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ParentPage == this)
|
||||
{
|
||||
FlowDirectionGalleryLandingPage.PushContentPage(newDirection);
|
||||
return;
|
||||
}
|
||||
string parentType = ParentPage.GetType().ToString();
|
||||
switch (parentType)
|
||||
{
|
||||
case "Xamarin.Forms.Controls.FlowDirectionGalleryMDP":
|
||||
FlowDirectionGalleryLandingPage.PushMasterDetailPage(newDirection);
|
||||
break;
|
||||
case "Xamarin.Forms.Controls.FlowDirectionGalleryCarP":
|
||||
FlowDirectionGalleryLandingPage.PushCarouselPage(newDirection);
|
||||
break;
|
||||
case "Xamarin.Forms.Controls.FlowDirectionGalleryNP":
|
||||
FlowDirectionGalleryLandingPage.PushNavigationPage(newDirection);
|
||||
break;
|
||||
case "Xamarin.Forms.Controls.FlowDirectionGalleryTP":
|
||||
FlowDirectionGalleryLandingPage.PushTabbedPage(newDirection);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
var horStack = new StackLayout
|
||||
{
|
||||
Orientation = StackOrientation.Horizontal,
|
||||
Children = { flipButton, new Label { Text = "Relayout", HorizontalOptions = LayoutOptions.End, VerticalOptions = LayoutOptions.Center }, relayout }
|
||||
};
|
||||
|
||||
var grid = new Grid
|
||||
{
|
||||
ColumnDefinitions = {
|
||||
new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
|
||||
new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) },
|
||||
},
|
||||
RowDefinitions = {
|
||||
new RowDefinition { Height = new GridLength(100, GridUnitType.Absolute) },
|
||||
new RowDefinition { Height = new GridLength(100, GridUnitType.Absolute) },
|
||||
new RowDefinition { Height = new GridLength(100, GridUnitType.Absolute) },
|
||||
new RowDefinition { Height = new GridLength(100, GridUnitType.Absolute) },
|
||||
new RowDefinition { Height = new GridLength(100, GridUnitType.Absolute) },
|
||||
new RowDefinition { Height = new GridLength(100, GridUnitType.Absolute) },
|
||||
new RowDefinition { Height = new GridLength(100, GridUnitType.Absolute) },
|
||||
}
|
||||
};
|
||||
|
||||
int col = 0;
|
||||
int row = 0;
|
||||
|
||||
var ai = AddView<ActivityIndicator>(grid, ref col, ref row);
|
||||
ai.IsRunning = true;
|
||||
|
||||
var box = AddView<BoxView>(grid, ref col, ref row);
|
||||
box.WidthRequest = box.HeightRequest = 20;
|
||||
box.BackgroundColor = Color.Purple;
|
||||
|
||||
var btn = AddView<Button>(grid, ref col, ref row);
|
||||
btn.Text = "Some text";
|
||||
|
||||
var date = AddView<DatePicker>(grid, ref col, ref row, 2);
|
||||
|
||||
var edit = AddView<Editor>(grid, ref col, ref row);
|
||||
edit.WidthRequest = 100;
|
||||
edit.HeightRequest = 100;
|
||||
edit.Text = "Some longer text for wrapping";
|
||||
|
||||
var entry = AddView<Entry>(grid, ref col, ref row);
|
||||
entry.WidthRequest = 100;
|
||||
entry.Text = "Some text";
|
||||
|
||||
var image = AddView<Image>(grid, ref col, ref row);
|
||||
image.Source = "oasis.jpg";
|
||||
|
||||
var lbl1 = AddView<Label>(grid, ref col, ref row);
|
||||
lbl1.WidthRequest = 100;
|
||||
lbl1.HorizontalTextAlignment = TextAlignment.Start;
|
||||
lbl1.Text = "Start text";
|
||||
|
||||
var lblLong = AddView<Label>(grid, ref col, ref row);
|
||||
lblLong.WidthRequest = 100;
|
||||
lblLong.HorizontalTextAlignment = TextAlignment.Start;
|
||||
lblLong.Text = "Start text that should wrap and wrap and wrap";
|
||||
|
||||
var lbl2 = AddView<Label>(grid, ref col, ref row);
|
||||
lbl2.WidthRequest = 100;
|
||||
lbl2.HorizontalTextAlignment = TextAlignment.End;
|
||||
lbl2.Text = "End text";
|
||||
|
||||
var lbl3 = AddView<Label>(grid, ref col, ref row);
|
||||
lbl3.WidthRequest = 100;
|
||||
lbl3.HorizontalTextAlignment = TextAlignment.Center;
|
||||
lbl3.Text = "Center text";
|
||||
|
||||
//var ogv = AddView<OpenGLView>(grid, ref col, ref row, hOptions, vOptions, margin);
|
||||
|
||||
var pkr = AddView<Picker>(grid, ref col, ref row);
|
||||
pkr.ItemsSource = Enumerable.Range(0, 10).ToList();
|
||||
|
||||
var sld = AddView<Slider>(grid, ref col, ref row);
|
||||
sld.WidthRequest = 100;
|
||||
sld.Maximum = 10;
|
||||
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
|
||||
{
|
||||
sld.Value += 1;
|
||||
if (sld.Value == 10d)
|
||||
sld.Value = 0;
|
||||
return true;
|
||||
});
|
||||
|
||||
var stp = AddView<Stepper>(grid, ref col, ref row);
|
||||
|
||||
var swt = AddView<Switch>(grid, ref col, ref row);
|
||||
|
||||
var time = AddView<TimePicker>(grid, ref col, ref row, 2);
|
||||
|
||||
var prog = AddView<ProgressBar>(grid, ref col, ref row, 2);
|
||||
prog.WidthRequest = 200;
|
||||
prog.BackgroundColor = Color.DarkGray;
|
||||
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
|
||||
{
|
||||
prog.Progress += .1;
|
||||
if (prog.Progress == 1d)
|
||||
prog.Progress = 0;
|
||||
return true;
|
||||
});
|
||||
|
||||
var srch = AddView<SearchBar>(grid, ref col, ref row, 2);
|
||||
srch.WidthRequest = 200;
|
||||
srch.Text = "Some text";
|
||||
|
||||
TableView tbl = new TableView
|
||||
{
|
||||
Intent = TableIntent.Menu,
|
||||
Root = new TableRoot
|
||||
{
|
||||
new TableSection("TableView")
|
||||
{
|
||||
new TextCell
|
||||
{
|
||||
Text = "A",
|
||||
},
|
||||
|
||||
new TextCell
|
||||
{
|
||||
Text = "B",
|
||||
},
|
||||
|
||||
new TextCell
|
||||
{
|
||||
Text = "C",
|
||||
},
|
||||
|
||||
new TextCell
|
||||
{
|
||||
Text = "D",
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var stack = new StackLayout
|
||||
{
|
||||
Children = { new Button { Text = "Go back to Gallery home", Command = new Command(()=> { ((App)Application.Current).SetMainPage(((App)Application.Current).CreateDefaultMainPage()); }) },
|
||||
new Label { Text = $"Device Direction: {DeviceDirection}" },
|
||||
horStack,
|
||||
grid,
|
||||
new Label { Text = "TableView", FontSize = 10, TextColor = Color.DarkGray },
|
||||
tbl,
|
||||
new Label { Text = "ListView w/ TextCell", FontSize = 10, TextColor = Color.DarkGray },
|
||||
new ListView { HorizontalOptions = hOptions, ItemsSource = Enumerable.Range(0, 3).Select(c => "Text Cell!"), ItemTemplate = textCell },
|
||||
new Label { Text = "ListView w/ SwitchCell", FontSize = 10, TextColor = Color.DarkGray },
|
||||
new ListView { HorizontalOptions = hOptions, ItemsSource = Enumerable.Range(0, 3).Select(c => true), ItemTemplate = switchCell },
|
||||
new Label { Text = "ListView w/ EntryCell", FontSize = 10, TextColor = Color.DarkGray },
|
||||
new ListView { HorizontalOptions = hOptions, ItemsSource = Enumerable.Range(0, 3).Select(c => "Entry Cell!"), ItemTemplate = entryCell },
|
||||
new Label { Text = "ListView w/ ImageCell", FontSize = 10, TextColor = Color.DarkGray },
|
||||
new ListView { HorizontalOptions = hOptions, ItemsSource = Enumerable.Range(0, 3).Select(c => "coffee.png"), ItemTemplate = imageCell },
|
||||
new Label { Text = "ListView w/ ViewCell", FontSize = 10, TextColor = Color.DarkGray },
|
||||
new ListView { HorizontalOptions = hOptions, ItemsSource = Enumerable.Range(0, 3), ItemTemplate = viewCell },
|
||||
},
|
||||
|
||||
HorizontalOptions = hOptions
|
||||
};
|
||||
|
||||
Content = new ScrollView
|
||||
{
|
||||
Content = stack
|
||||
};
|
||||
}
|
||||
|
||||
T AddView<T>(Grid grid, ref int col, ref int row, int colSpan = 1) where T : View
|
||||
{
|
||||
var hOptions = LayoutOptions.Start;
|
||||
var vOptions = LayoutOptions.End;
|
||||
var margin = new Thickness(0, 10);
|
||||
var bgColor = Color.LightGray;
|
||||
|
||||
T view = (T)Activator.CreateInstance(typeof(T));
|
||||
|
||||
view.VerticalOptions = vOptions;
|
||||
view.HorizontalOptions = hOptions;
|
||||
view.Margin = margin;
|
||||
view.BackgroundColor = bgColor;
|
||||
|
||||
var label = new Label { Text = $"({col},{row}) {typeof(T).ToString()}", FontSize = 10, TextColor = Color.DarkGray };
|
||||
|
||||
if (colSpan > 1 && col > 0)
|
||||
NextCell(ref col, ref row, colSpan);
|
||||
|
||||
grid.Children.Add(label, col, col + colSpan, row, row + 1);
|
||||
grid.Children.Add(view, col, col + colSpan, row, row + 1);
|
||||
|
||||
NextCell(ref col, ref row, colSpan);
|
||||
|
||||
return (T)view;
|
||||
}
|
||||
|
||||
void NextCell(ref int col, ref int row, int colspan)
|
||||
{
|
||||
if (col == 0 && colspan == 1)
|
||||
{
|
||||
col = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
col = 0;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -250,6 +250,7 @@ namespace Xamarin.Forms.Controls
|
|||
}
|
||||
|
||||
List<GalleryPageFactory> _pages = new List<GalleryPageFactory> {
|
||||
new GalleryPageFactory(() => new FlowDirectionGalleryLandingPage(), "FlowDirection"),
|
||||
new GalleryPageFactory(() => new AutomationPropertiesGallery(), "Accessibility"),
|
||||
new GalleryPageFactory(() => new PlatformSpecificsGallery(), "Platform Specifics"),
|
||||
new GalleryPageFactory(() => new NativeBindingGalleryPage(), "Native Binding Controls Gallery"),
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
<Compile Include="Bugzilla44596SplashPage.cs" />
|
||||
<Compile Include="ControlGalleryPages\AutomationPropertiesGallery.cs" />
|
||||
<Compile Include="ControlGalleryPages\CellForceUpdateSizeGalleryPage.cs" />
|
||||
<Compile Include="ControlGalleryPages\FlowDirectionGallery.cs" />
|
||||
<Compile Include="ControlGalleryPages\LayoutAddPerformance.xaml.cs">
|
||||
<DependentUpon>LayoutAddPerformance.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xamarin.Forms.Core.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class EffectiveFlowDirectionExtensions : BaseTestFixture
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void LeftToRightImplicit()
|
||||
{
|
||||
var target = FlowDirection.LeftToRight.ToEffectiveFlowDirection();
|
||||
|
||||
Assert.IsTrue(target.IsLeftToRight());
|
||||
Assert.IsTrue(target.IsImplicit());
|
||||
|
||||
Assert.IsFalse(target.IsRightToLeft());
|
||||
Assert.IsFalse(target.IsExplicit());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LeftToRightExplicit()
|
||||
{
|
||||
var target = FlowDirection.LeftToRight.ToEffectiveFlowDirection(isExplicit: true);
|
||||
|
||||
Assert.IsTrue(target.IsLeftToRight());
|
||||
Assert.IsTrue(target.IsExplicit());
|
||||
|
||||
Assert.IsFalse(target.IsRightToLeft());
|
||||
Assert.IsFalse(target.IsImplicit());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RightToLeftImplicit()
|
||||
{
|
||||
var target = FlowDirection.RightToLeft.ToEffectiveFlowDirection();
|
||||
|
||||
Assert.IsTrue(target.IsRightToLeft());
|
||||
Assert.IsTrue(target.IsImplicit());
|
||||
|
||||
Assert.IsFalse(target.IsLeftToRight());
|
||||
Assert.IsFalse(target.IsExplicit());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RightToLeftExplicit()
|
||||
{
|
||||
var target = FlowDirection.RightToLeft.ToEffectiveFlowDirection(isExplicit: true);
|
||||
|
||||
Assert.IsTrue(target.IsRightToLeft());
|
||||
Assert.IsTrue(target.IsExplicit());
|
||||
|
||||
Assert.IsFalse(target.IsLeftToRight());
|
||||
Assert.IsFalse(target.IsImplicit());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,630 @@
|
|||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Core.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class FlowDirectionTests : BaseTestFixture
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void ListViewFlowDirectionIsInheritedByViewCells()
|
||||
{
|
||||
var lv = new ListView { FlowDirection = FlowDirection.RightToLeft, ItemTemplate = new DataTemplate(() => new ViewCell { View = new View() }) };
|
||||
|
||||
lv.ItemsSource = Enumerable.Range(0, 10);
|
||||
|
||||
ViewCell cell = lv.TemplatedItems[0] as ViewCell;
|
||||
IViewController target = cell.View;
|
||||
Assert.IsTrue(target.EffectiveFlowDirection.IsRightToLeft(), "ViewCell View is not RightToLeft");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ListViewFlowDirectionIsInheritedByImageInViewCells()
|
||||
{
|
||||
var lv = new ListView { FlowDirection = FlowDirection.RightToLeft, ItemTemplate = new DataTemplate(() => new ViewCell { View = new Label() }) };
|
||||
|
||||
lv.ItemsSource = Enumerable.Range(0, 10);
|
||||
|
||||
ViewCell cell = lv.TemplatedItems[0] as ViewCell;
|
||||
IViewController target = cell.View;
|
||||
Assert.IsTrue(target.EffectiveFlowDirection.IsRightToLeft(), "ViewCell View is not RightToLeft");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ScrollViewSetsFlowDirectionAndGrandchildMaintainsParentExplicitValue()
|
||||
{
|
||||
var layout = ImplicitLeftToRightScrollView();
|
||||
var layout2 = ExplicitRightToLeftScrollView();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
|
||||
AddExplicitRTLToScrollView(layout, layout2);
|
||||
AddImplicitToRTLScrollView(layout2, (View)view);
|
||||
|
||||
layout.FlowDirection = FlowDirection.LeftToRight;
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(target.IsRightToLeft(), "EffectiveFlowDirection should be RightToLeft");
|
||||
Assert.IsTrue(!target.IsLeftToRight(), "EffectiveFlowDirection should be RightToLeft");
|
||||
|
||||
Assert.AreEqual(FlowDirection.MatchParent, ((View)view).FlowDirection);
|
||||
Assert.AreEqual(FlowDirection.RightToLeft, layout2.FlowDirection);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GrandparentSetsFlowDirectionAndGrandchildMaintainsParentExplicitValue()
|
||||
{
|
||||
var layout = ImplicitLeftToRightLayout();
|
||||
var layout2 = ExplicitLeftToRightLayout();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
|
||||
AddExplicitLTRToLayout(layout, layout2);
|
||||
AddImplicitToLTR(layout2, (View)view);
|
||||
|
||||
layout.FlowDirection = FlowDirection.RightToLeft;
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsRightToLeft(), "EffectiveFlowDirection should be LeftToRight");
|
||||
Assert.IsTrue(target.IsLeftToRight(), "EffectiveFlowDirection should be LeftToRight");
|
||||
|
||||
Assert.AreEqual(FlowDirection.MatchParent, ((View)view).FlowDirection);
|
||||
Assert.AreEqual(FlowDirection.LeftToRight, layout2.FlowDirection);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GrandparentSetsFlowDirectionAndImplicitDescendentsInheritValue()
|
||||
{
|
||||
var layout = ImplicitLeftToRightLayout();
|
||||
var layout2 = ImplicitLeftToRightLayout();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
|
||||
AddImplicitToLTR(layout, layout2);
|
||||
|
||||
AddImplicitToLTR(layout2, (View)view);
|
||||
|
||||
layout.FlowDirection = FlowDirection.RightToLeft;
|
||||
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsRightToLeft());
|
||||
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsImplicit());
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsRightToLeft());
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(target.IsRightToLeft(), "EffectiveFlowDirection should be RightToLeft");
|
||||
Assert.IsTrue(!target.IsLeftToRight(), "EffectiveFlowDirection should be RightToLeft");
|
||||
|
||||
Assert.AreEqual(FlowDirection.MatchParent, ((View)view).FlowDirection);
|
||||
Assert.AreEqual(FlowDirection.MatchParent, layout2.FlowDirection);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GrandparentSetsOppositeFlowDirectionAndGrandchildInheritsParentExplicitValue()
|
||||
{
|
||||
var layout = ExplicitRightToLeftLayout();
|
||||
var layout2 = ExplicitRightToLeftLayout();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
|
||||
AddExplicitRTLToLayout(layout, layout2);
|
||||
|
||||
AddImplicitToRTL(layout2, (View)view);
|
||||
|
||||
layout.FlowDirection = FlowDirection.LeftToRight;
|
||||
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsLeftToRight());
|
||||
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsRightToLeft());
|
||||
|
||||
Assume.That(view.EffectiveFlowDirection.IsImplicit());
|
||||
Assume.That(view.EffectiveFlowDirection.IsRightToLeft());
|
||||
|
||||
var target = ((View)view).FlowDirection;
|
||||
|
||||
Assert.AreEqual(FlowDirection.MatchParent, target);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NotifyFlowDirectionChangedDoesNotTriggerFlowDirectionPropertyChangedUnnecessarily()
|
||||
{
|
||||
var layout = ExplicitRightToLeftLayout();
|
||||
var layout2 = ImplicitLeftToRightLayout();
|
||||
IViewController view = new PropertyWatchingView();
|
||||
|
||||
AddImplicitToRTL(layout, layout2);
|
||||
|
||||
AddImplicitToRTL(layout2, (View)view);
|
||||
|
||||
layout2.FlowDirection = FlowDirection.RightToLeft;
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsExplicit(), "Explicit EffectiveFlowDirection not set on inner layout");
|
||||
Assume.That(view.EffectiveFlowDirection.IsRightToLeft(), "Implicit FlowDirection not set on view");
|
||||
|
||||
layout.FlowDirection = FlowDirection.LeftToRight;
|
||||
Assume.That(layout2.FlowDirection == FlowDirection.RightToLeft, "Explicit FlowDirection not respected on inner layout");
|
||||
Assume.That(view.EffectiveFlowDirection.IsRightToLeft(), "Implicit FlowDirection not set on view");
|
||||
|
||||
var target = ((PropertyWatchingView)view).FlowDirectionPropertyChangedCount;
|
||||
|
||||
Assert.AreEqual(1, target);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReParentAndInheritNewParentValue()
|
||||
{
|
||||
var layout = ExplicitRightToLeftLayout();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
var layout2 = ExplicitLeftToRightLayout();
|
||||
|
||||
AddImplicitToRTL(layout, (View)view);
|
||||
|
||||
((View)view).Parent = layout2;
|
||||
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsLeftToRight());
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsRightToLeft(), "EffectiveFlowDirection should be LeftToRight");
|
||||
Assert.IsTrue(target.IsLeftToRight(), "EffectiveFlowDirection should be LeftToRight");
|
||||
|
||||
Assert.AreEqual(FlowDirection.MatchParent, ((View)view).FlowDirection);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReParentParentAndInheritNewGrandParentValue()
|
||||
{
|
||||
var layout = ExplicitRightToLeftLayout();
|
||||
var layout2 = ImplicitLeftToRightLayout();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
var layout3 = ExplicitLeftToRightLayout();
|
||||
|
||||
AddImplicitToRTL(layout, layout2);
|
||||
AddImplicitToRTL(layout2, (View)view);
|
||||
|
||||
layout2.Parent = layout3;
|
||||
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsImplicit());
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsLeftToRight());
|
||||
|
||||
Assume.That(view.EffectiveFlowDirection.IsImplicit());
|
||||
Assume.That(view.EffectiveFlowDirection.IsLeftToRight());
|
||||
|
||||
var target = ((View)view).FlowDirection;
|
||||
|
||||
Assert.AreEqual(FlowDirection.MatchParent, target);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetFlowDirectionToMatchParentAndInheritParentValue()
|
||||
{
|
||||
var layout = ImplicitLeftToRightLayout();
|
||||
var layout2 = ExplicitRightToLeftLayout();
|
||||
IViewController view = ExplicitLeftToRightView();
|
||||
|
||||
AddExplicitRTLToLayout(layout, layout2);
|
||||
|
||||
AddExplicitLTRToLayout(layout2, (View)view);
|
||||
|
||||
((View)view).FlowDirection = FlowDirection.MatchParent;
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(target.IsRightToLeft(), "EffectiveFlowDirection should be RightToLeft");
|
||||
Assert.IsTrue(!target.IsLeftToRight(), "EffectiveFlowDirection should be RightToLeft");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetGrandparentAndInheritExplicitParentValue()
|
||||
{
|
||||
var layout = ExplicitRightToLeftLayout();
|
||||
var layout2 = ExplicitLeftToRightLayout();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
|
||||
AddExplicitLTRToLayout(layout, layout2);
|
||||
AddImplicitToLTR(layout2, (View)view);
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsRightToLeft());
|
||||
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsLeftToRight());
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsRightToLeft(), "EffectiveFlowDirection should be LeftToRight");
|
||||
Assert.IsTrue(target.IsLeftToRight(), "EffectiveFlowDirection should be LeftToRight");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetGrandparentUsingAnonCtorAndMaintainExplicitParentValue()
|
||||
{
|
||||
var layout = new StackLayout
|
||||
{
|
||||
FlowDirection = FlowDirection.RightToLeft,
|
||||
Children = {
|
||||
new StackLayout {
|
||||
FlowDirection = FlowDirection.LeftToRight,
|
||||
Children = { ImplicitLeftToRightView() }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var layout2 = layout.Children[0] as StackLayout;
|
||||
IViewController view = layout2.Children[0] as View;
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsRightToLeft());
|
||||
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsLeftToRight());
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsRightToLeft(), "EffectiveFlowDirection should be LeftToRight");
|
||||
Assert.IsTrue(target.IsLeftToRight(), "EffectiveFlowDirection should be LeftToRight");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetGrandparentUsingCtorAndMaintainExplicitParentValue()
|
||||
{
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
var layout2 = new StackLayout { FlowDirection = FlowDirection.LeftToRight, Children = { (View)view } };
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft, Children = { layout2 } };
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsRightToLeft());
|
||||
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout2).EffectiveFlowDirection.IsLeftToRight());
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsRightToLeft(), "EffectiveFlowDirection should be LeftToRight");
|
||||
Assert.IsTrue(target.IsLeftToRight(), "EffectiveFlowDirection should be LeftToRight");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetParentAndGrandchildrenInheritValue()
|
||||
{
|
||||
var layout = ExplicitRightToLeftLayout();
|
||||
var layout2 = ImplicitLeftToRightLayout();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
|
||||
AddImplicitToRTL(layout, layout2);
|
||||
|
||||
AddImplicitToRTL(layout2, (View)view);
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(target.IsRightToLeft(), "EffectiveFlowDirection should be RightToLeft");
|
||||
Assert.IsTrue(!target.IsLeftToRight(), "EffectiveFlowDirection should be RightToLeft");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetParentAndContentAndGrandchildrenInheritValue()
|
||||
{
|
||||
var layout = ExplicitRightToLeftLayout();
|
||||
var layout2 = ImplicitLeftToRightScrollView();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
|
||||
AddImplicitToRTL(layout, layout2);
|
||||
|
||||
AddImplicitToRTLScrollView(layout2, (View)view);
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(target.IsRightToLeft(), "EffectiveFlowDirection should be RightToLeft");
|
||||
Assert.IsTrue(!target.IsLeftToRight(), "EffectiveFlowDirection should be RightToLeft");
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void SetParentAndInheritExplicitParentValue()
|
||||
{
|
||||
var layout = ExplicitRightToLeftLayout();
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
|
||||
AddImplicitToRTL(layout, (View)view);
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(target.IsRightToLeft(), "EffectiveFlowDirection should be RightToLeft");
|
||||
Assert.IsTrue(!target.IsLeftToRight(), "EffectiveFlowDirection should be RightToLeft");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetParentAndMaintainExplicitValue()
|
||||
{
|
||||
var layout = ExplicitRightToLeftLayout();
|
||||
IViewController view = ExplicitLeftToRightView();
|
||||
|
||||
AddExplicitLTRToLayout(layout, (View)view);
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(!target.IsImplicit(), "EffectiveFlowDirection should be Explicit");
|
||||
Assert.IsTrue(target.IsExplicit(), "EffectiveFlowDirection should be Explicit");
|
||||
Assert.IsTrue(!target.IsRightToLeft(), "EffectiveFlowDirection should be LeftToRight");
|
||||
Assert.IsTrue(target.IsLeftToRight(), "EffectiveFlowDirection should be LeftToRight");
|
||||
Assert.AreEqual(FlowDirection.LeftToRight, ((View)view).FlowDirection);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetParentUsingCtorAndInheritParentValue()
|
||||
{
|
||||
IViewController view = ImplicitLeftToRightView();
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft, Children = { (View)view } };
|
||||
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsExplicit());
|
||||
Assume.That(((IViewController)layout).EffectiveFlowDirection.IsRightToLeft());
|
||||
|
||||
Assume.That(((View)view).FlowDirection == FlowDirection.MatchParent);
|
||||
|
||||
var target = view.EffectiveFlowDirection;
|
||||
|
||||
Assert.IsTrue(target.IsImplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(!target.IsExplicit(), "EffectiveFlowDirection should be Implicit");
|
||||
Assert.IsTrue(target.IsRightToLeft(), "EffectiveFlowDirection should be RightToLeft");
|
||||
Assert.IsTrue(!target.IsLeftToRight(), "EffectiveFlowDirection should be RightToLeft");
|
||||
Assert.AreEqual(FlowDirection.MatchParent, ((View)view).FlowDirection);
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public override void Setup()
|
||||
{
|
||||
base.Setup();
|
||||
Device.PlatformServices = new MockPlatformServices();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public override void TearDown()
|
||||
{
|
||||
base.TearDown();
|
||||
Device.PlatformServices = null;
|
||||
}
|
||||
|
||||
static void AddExplicitLTRToScrollView(ScrollView parent, View child)
|
||||
{
|
||||
parent.Content = child;
|
||||
|
||||
IViewController controller = child;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "child view FlowDirection should be Explicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "child view FlowDirection should be LeftToRight");
|
||||
Assume.That(child.FlowDirection == FlowDirection.LeftToRight, "child view FlowDirection should be LeftToRight");
|
||||
}
|
||||
|
||||
static void AddExplicitLTRToLayout(StackLayout parent, View child)
|
||||
{
|
||||
parent.Children.Add(child);
|
||||
|
||||
IViewController controller = child;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "child view FlowDirection should be Explicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "child view FlowDirection should be LeftToRight");
|
||||
Assume.That(child.FlowDirection == FlowDirection.LeftToRight, "child view FlowDirection should be LeftToRight");
|
||||
}
|
||||
|
||||
static void AddExplicitRTLToScrollView(ScrollView parent, View child)
|
||||
{
|
||||
parent.Content = child;
|
||||
|
||||
IViewController controller = child;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "child view EffectiveFlowDirection should be Implicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsRightToLeft(), "child view EffectiveFlowDirection should be RightToLeft");
|
||||
Assume.That(child.FlowDirection == FlowDirection.RightToLeft, "child view FlowDirection should be RightToLeft");
|
||||
}
|
||||
|
||||
static void AddExplicitRTLToLayout(StackLayout parent, View child)
|
||||
{
|
||||
parent.Children.Add(child);
|
||||
|
||||
IViewController controller = child;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "child view EffectiveFlowDirection should be Implicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsRightToLeft(), "child view EffectiveFlowDirection should be RightToLeft");
|
||||
Assume.That(child.FlowDirection == FlowDirection.RightToLeft, "child view FlowDirection should be RightToLeft");
|
||||
}
|
||||
|
||||
static void AddImplicitToLTR(StackLayout parent, View child)
|
||||
{
|
||||
parent.Children.Add(child);
|
||||
|
||||
IViewController controller = child;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsImplicit(), "child view EffectiveFlowDirection should be Implicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "child view EffectiveFlowDirection should be LeftToRight");
|
||||
Assume.That(child.FlowDirection == FlowDirection.MatchParent, "child view FlowDirection should be MatchParent");
|
||||
}
|
||||
|
||||
static void AddImplicitToLTRScrollView(ScrollView parent, View child)
|
||||
{
|
||||
parent.Content = child;
|
||||
|
||||
IViewController controller = child;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsImplicit(), "child view EffectiveFlowDirection should be Implicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "child view EffectiveFlowDirection should be LeftToRight");
|
||||
Assume.That(child.FlowDirection == FlowDirection.MatchParent, "child view FlowDirection should be MatchParent");
|
||||
}
|
||||
|
||||
static void AddImplicitToRTL(StackLayout parent, View child)
|
||||
{
|
||||
parent.Children.Add(child);
|
||||
|
||||
IViewController controller = child;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsImplicit(), "child view EffectiveFlowDirection should be Implicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsRightToLeft(), "child view EffectiveFlowDirection should be RightToLeft");
|
||||
Assume.That(child.FlowDirection == FlowDirection.MatchParent, "child view FlowDirection should be MatchParent");
|
||||
}
|
||||
|
||||
static void AddImplicitToRTLScrollView(ScrollView parent, View child)
|
||||
{
|
||||
parent.Content = child;
|
||||
|
||||
IViewController controller = child;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsImplicit(), "child view EffectiveFlowDirection should be Implicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsRightToLeft(), "child view EffectiveFlowDirection should be RightToLeft");
|
||||
Assume.That(child.FlowDirection == FlowDirection.MatchParent, "child view FlowDirection should be MatchParent");
|
||||
}
|
||||
|
||||
static ScrollView ExplicitLeftToRightScrollView()
|
||||
{
|
||||
var layout = new ScrollView { FlowDirection = FlowDirection.LeftToRight };
|
||||
|
||||
IViewController controller = layout;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "Explicit LTR view EffectiveFlowDirection should be Explicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "Explicit LTR view EffectiveFlowDirection should be LeftToRight");
|
||||
Assume.That(layout.FlowDirection == FlowDirection.LeftToRight, "Explicit LTR view FlowDirection should be LeftToRight");
|
||||
return layout;
|
||||
}
|
||||
|
||||
static StackLayout ExplicitLeftToRightLayout()
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.LeftToRight };
|
||||
|
||||
IViewController controller = layout;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "Explicit LTR view EffectiveFlowDirection should be Explicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "Explicit LTR view EffectiveFlowDirection should be LeftToRight");
|
||||
Assume.That(layout.FlowDirection == FlowDirection.LeftToRight, "Explicit LTR view FlowDirection should be LeftToRight");
|
||||
return layout;
|
||||
}
|
||||
|
||||
static View ExplicitLeftToRightView()
|
||||
{
|
||||
var view = new View { FlowDirection = FlowDirection.LeftToRight };
|
||||
|
||||
IViewController controller = view;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "Explicit LTR view EffectiveFlowDirection should be Explicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "Explicit LTR view EffectiveFlowDirection should be LeftToRight");
|
||||
Assume.That(((View)view).FlowDirection == FlowDirection.LeftToRight, "Explicit LTR view FlowDirection should be LeftToRight");
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
static ScrollView ExplicitRightToLeftScrollView()
|
||||
{
|
||||
var layout = new ScrollView { FlowDirection = FlowDirection.RightToLeft };
|
||||
|
||||
IViewController controller = layout;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "Explicit RTL view EffectiveFlowDirection should be Explicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsRightToLeft(), "Explicit RTL view EffectiveFlowDirection should be RightToLeft");
|
||||
Assume.That(layout.FlowDirection == FlowDirection.RightToLeft, "Explicit RTL view FlowDirection should be RightToLeft");
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
static StackLayout ExplicitRightToLeftLayout()
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
|
||||
IViewController controller = layout;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "Explicit RTL view EffectiveFlowDirection should be Explicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsRightToLeft(), "Explicit RTL view EffectiveFlowDirection should be RightToLeft");
|
||||
Assume.That(layout.FlowDirection == FlowDirection.RightToLeft, "Explicit RTL view FlowDirection should be RightToLeft");
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
static View ExplicitRightToLeftView()
|
||||
{
|
||||
var view = new View { FlowDirection = FlowDirection.RightToLeft };
|
||||
|
||||
IViewController controller = view;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsExplicit(), "Explicit RTL view EffectiveFlowDirection should be Explicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsRightToLeft(), "Explicit RTL view EffectiveFlowDirection should be RightToLeft");
|
||||
Assume.That(((View)view).FlowDirection == FlowDirection.RightToLeft, "Explicit RTL view FlowDirection should be RightToLeft");
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
static ScrollView ImplicitLeftToRightScrollView()
|
||||
{
|
||||
var layout = new ScrollView();
|
||||
|
||||
IViewController controller = layout;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsImplicit(), "New view EffectiveFlowDirection should be Implicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "New view EffectiveFlowDirection should be LeftToRight");
|
||||
Assume.That(layout.FlowDirection == FlowDirection.MatchParent, "New view FlowDirection should be MatchParent");
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
static StackLayout ImplicitLeftToRightLayout()
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
|
||||
IViewController controller = layout;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsImplicit(), "New view EffectiveFlowDirection should be Implicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "New view EffectiveFlowDirection should be LeftToRight");
|
||||
Assume.That(layout.FlowDirection == FlowDirection.MatchParent, "New view FlowDirection should be MatchParent");
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
static View ImplicitLeftToRightView()
|
||||
{
|
||||
var view = new View();
|
||||
|
||||
IViewController controller = view;
|
||||
|
||||
Assume.That(controller.EffectiveFlowDirection.IsImplicit(), "New view EffectiveFlowDirection should be Implicit");
|
||||
Assume.That(controller.EffectiveFlowDirection.IsLeftToRight(), "New view EffectiveFlowDirection should be LeftToRight");
|
||||
Assume.That(((View)view).FlowDirection == FlowDirection.MatchParent, "New view FlowDirection should be MatchParent");
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
class PropertyWatchingView : View
|
||||
{
|
||||
public int FlowDirectionPropertyChangedCount { get; private set; }
|
||||
|
||||
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
base.OnPropertyChanged(propertyName);
|
||||
|
||||
if (propertyName == View.FlowDirectionProperty.PropertyName)
|
||||
FlowDirectionPropertyChangedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,844 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
|
||||
namespace Xamarin.Forms.Core.UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class LayoutChildIntoBoundingRegionTests : BaseTestFixture
|
||||
{
|
||||
const int Layout_Width = 100;
|
||||
const int Margin_Large = 12;
|
||||
const int Margin_None = 0;
|
||||
const int Margin_Small = 2;
|
||||
const int Region_Height = 50;
|
||||
const int Region_Width = 150;
|
||||
const int Region_X = 5;
|
||||
const int Region_Y = 5;
|
||||
const int View_Size = 20;
|
||||
|
||||
int Expected_Empty_Region_Height => Region_Height - View_Size;
|
||||
int Expected_Empty_Region_Width => Region_Width - View_Size;
|
||||
int Expected_Height_Start_End => View_Size;
|
||||
int Expected_Region_Right => Region_X + Region_Width;
|
||||
int Expected_Width_Start_End => View_Size;
|
||||
int Expected_X_Center => Expected_Empty_Region_Width / 2 + Region_X;
|
||||
int Expected_Y_Center => Expected_Empty_Region_Height / 2 + Region_Y;
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void Default(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
|
||||
var view = new MockView(margin);
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void Default_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
|
||||
var view = new MockView(margin);
|
||||
|
||||
layout.Children.Add(view);
|
||||
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_Region_Right, region.Right, "region.Right");
|
||||
Assert.AreEqual(Layout_Width, layout.Width, "layout.Width");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_RTL_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalCenter(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.Center };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Center,
|
||||
"view.HorizontalOptions.Alignment should be Center");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 0.5,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 0.5");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Center, target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalCenter_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.Center };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
var center_margin = Math.Ceiling(margin / 2d);
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Center,
|
||||
"view.HorizontalOptions.Alignment should be Center");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 0.5,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 0.5");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Center_RTL_Plus_Margin(0), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalCenterAndExpand(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.CenterAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Center,
|
||||
"view.HorizontalOptions.Alignment should be Center");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 0.5,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 0.5");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Center, target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalCenterAndExpand_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.CenterAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Center,
|
||||
"view.HorizontalOptions.Alignment should be Center");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 0.5,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 0.5");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Center_RTL_Plus_Margin(0), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalEnd(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.End };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.End,
|
||||
"view.HorizontalOptions.Alignment should be End");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 1,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 1");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_End_Less_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalEnd_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.End };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.End,
|
||||
"view.HorizontalOptions.Alignment should be End");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 1,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 1");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_End_RTL_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalEndAndExpand(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.EndAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.End,
|
||||
"view.HorizontalOptions.Alignment should be End");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 1,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 1");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_End_Less_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalEndAndExpand_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.EndAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.End,
|
||||
"view.HorizontalOptions.Alignment should be End");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 1,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 1");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_End_RTL_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalStart(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.Start };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Start,
|
||||
"view.HorizontalOptions.Alignment should be Start");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 0,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 0");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalStart_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.Start };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Start,
|
||||
"view.HorizontalOptions.Alignment should be Start");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 0,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 0");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Start_Less_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalStartAndExpand(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.StartAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Start,
|
||||
"view.HorizontalOptions.Alignment should be Start");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 0,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 0");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void HorizontalStartAndExpand_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { HorizontalOptions = LayoutOptions.StartAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Start,
|
||||
"view.HorizontalOptions.Alignment should be Start");
|
||||
Assume.That(view.HorizontalOptions.Alignment.ToDouble() == 0,
|
||||
"view.HorizontalOptions.Alignment.ToDouble() should be 0");
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.VerticalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Start_Less_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Start_End, target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Fill_Less_Thickness(thickness), target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalCenter(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.Center };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Center,
|
||||
"view.VerticalOptions.Alignment should be Center");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 0.5,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 0.5");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Center, target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalCenter_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.Center };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Center,
|
||||
"view.VerticalOptions.Alignment should be Center");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 0.5,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 0.5");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_RTL_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Center, target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalCenterAndExpand(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.CenterAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Center,
|
||||
"view.VerticalOptions.Alignment should be Center");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 0.5,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 0.5");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Center, target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalCenterAndExpand_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.CenterAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Center,
|
||||
"view.VerticalOptions.Alignment should be Center");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 0.5,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 0.5");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_RTL_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Center, target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalEnd(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.End };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.End,
|
||||
"view.VerticalOptions.Alignment should be End");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 1,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 1");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_End_Less_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalEnd_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.End };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.End,
|
||||
"view.VerticalOptions.Alignment should be End");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 1,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 1");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_RTL_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_End_Less_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalEndAndExpand(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.EndAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.End,
|
||||
"view.VerticalOptions.Alignment should be End");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 1,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 1");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_End_Less_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalEndAndExpand_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.EndAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.End,
|
||||
"view.VerticalOptions.Alignment should be End");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 1,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 1");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_RTL_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_End_Less_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalStart(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.Start };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Start,
|
||||
"view.VerticalOptions.Alignment should be Start");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 0,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 0");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalStart_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.Start };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Start,
|
||||
"view.VerticalOptions.Alignment should be Start");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 0,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 0");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_RTL_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalStartAndExpand(int margin)
|
||||
{
|
||||
var layout = new StackLayout();
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.StartAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Start,
|
||||
"view.VerticalOptions.Alignment should be Start");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 0,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 0");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
[TestCase(Margin_None)]
|
||||
[TestCase(Margin_Small)]
|
||||
[TestCase(Margin_Large)]
|
||||
public void VerticalStartAndExpand_RTL(int margin)
|
||||
{
|
||||
var layout = new StackLayout { FlowDirection = FlowDirection.RightToLeft };
|
||||
layout.MockBounds(new Rectangle(0, 0, Layout_Width, double.PositiveInfinity));
|
||||
var view = new MockView(margin) { VerticalOptions = LayoutOptions.StartAndExpand };
|
||||
|
||||
layout.Children.Add(view);
|
||||
var region = new Rectangle(Region_X, Region_Y, Region_Width, Region_Height);
|
||||
|
||||
Layout.LayoutChildIntoBoundingRegion(view, region);
|
||||
|
||||
var target = view.Bounds;
|
||||
var thickness = margin * 2;
|
||||
|
||||
Assume.That(view.VerticalOptions.Alignment == LayoutAlignment.Start,
|
||||
"view.VerticalOptions.Alignment should be Start");
|
||||
Assume.That(view.VerticalOptions.Alignment.ToDouble() == 0,
|
||||
"view.VerticalOptions.Alignment.ToDouble() should be 0");
|
||||
Assume.That(view.HorizontalOptions.Alignment == LayoutAlignment.Fill,
|
||||
"view.HorizontalOptions.Alignment should be Fill");
|
||||
|
||||
Assert.AreEqual(Expected_X_Fill_RTL_Plus_Margin(margin), target.X, "X");
|
||||
Assert.AreEqual(Expected_Y_Fill_Plus_Margin(margin), target.Y, "Y");
|
||||
Assert.AreEqual(Expected_Width_Fill_Less_Thickness(thickness), target.Width, "Width");
|
||||
Assert.AreEqual(Expected_Height_Start_End, target.Height, "Height");
|
||||
}
|
||||
|
||||
int Expected_Height_Fill_Less_Thickness(int thickness) => Region_Height - thickness;
|
||||
|
||||
int Expected_Width_Fill_Less_Thickness(int thickness) => Region_Width - thickness;
|
||||
|
||||
int Expected_X_Center_RTL_Plus_Margin(int margin) => Expected_Empty_Region_Width / 2 + Expected_X_Fill_RTL_Plus_Margin(margin);
|
||||
|
||||
int Expected_X_End_Less_Margin(int margin) => Expected_Empty_Region_Width + Region_X - margin;
|
||||
|
||||
int Expected_X_End_RTL_Plus_Margin(int margin) => Layout_Width - Region_Width - Region_X + margin;
|
||||
|
||||
int Expected_X_Fill_Plus_Margin(int margin) => Region_X + margin;
|
||||
|
||||
int Expected_X_Fill_RTL_Plus_Margin(int margin) => Layout_Width - Expected_Region_Right + margin;
|
||||
|
||||
int Expected_X_Start_Less_Margin(int margin) => Layout_Width - View_Size - Region_X - margin;
|
||||
|
||||
int Expected_Y_End_Less_Margin(int margin) => Expected_Empty_Region_Height + Region_Y - margin;
|
||||
|
||||
int Expected_Y_Fill_Plus_Margin(int margin) => Region_Y + margin;
|
||||
|
||||
class MockView : View
|
||||
{
|
||||
public MockView(int margin)
|
||||
{
|
||||
Margin = new Thickness(margin);
|
||||
WidthRequest = View_Size;
|
||||
HeightRequest = View_Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,6 +71,9 @@
|
|||
<Compile Include="ColorUnitTests.cs" />
|
||||
<Compile Include="CommandSourceTests.cs" />
|
||||
<Compile Include="CommandTests.cs" />
|
||||
<Compile Include="EffectiveFlowDirectionExtensions.cs" />
|
||||
<Compile Include="FlowDirectionTests.cs" />
|
||||
<Compile Include="LayoutChildIntoBoundingRegionTests.cs" />
|
||||
<Compile Include="MenuUnitTests.cs" />
|
||||
<Compile Include="TemplatedViewUnitTests.cs" />
|
||||
<Compile Include="TemplatedPageUnitTests.cs" />
|
||||
|
@ -208,4 +211,4 @@
|
|||
<LogicalName>Images/crimson.jpg</LogicalName>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -593,8 +593,7 @@ namespace Xamarin.Forms
|
|||
|
||||
OnPropertyChanged(property.PropertyName);
|
||||
|
||||
if (property.PropertyChanged != null)
|
||||
property.PropertyChanged(this, original, value);
|
||||
property.PropertyChanged?.Invoke(this, original, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -661,4 +660,4 @@ namespace Xamarin.Forms
|
|||
RaiseOnEqual = 1 << 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ using System.Collections.ObjectModel;
|
|||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
public abstract class Cell : Element, ICellController
|
||||
public abstract class Cell : Element, ICellController, IFlowDirectionController
|
||||
{
|
||||
public const int DefaultCellHeight = 40;
|
||||
public static readonly BindableProperty IsEnabledProperty = BindableProperty.Create("IsEnabled", typeof(bool), typeof(Cell), true, propertyChanged: OnIsEnabledPropertyChanged);
|
||||
|
@ -18,6 +19,25 @@ namespace Xamarin.Forms
|
|||
|
||||
bool _nextCallToForceUpdateSizeQueued;
|
||||
|
||||
EffectiveFlowDirection _effectiveFlowDirection = default(EffectiveFlowDirection);
|
||||
EffectiveFlowDirection IFlowDirectionController.EffectiveFlowDirection
|
||||
{
|
||||
get { return _effectiveFlowDirection; }
|
||||
set
|
||||
{
|
||||
if (value == _effectiveFlowDirection)
|
||||
return;
|
||||
|
||||
_effectiveFlowDirection = value;
|
||||
|
||||
var ve = (Parent as VisualElement);
|
||||
ve?.InvalidateMeasureInternal(InvalidationTrigger.Undefined);
|
||||
OnPropertyChanged(VisualElement.FlowDirectionProperty.PropertyName);
|
||||
}
|
||||
}
|
||||
|
||||
IFlowDirectionController FlowController => this;
|
||||
|
||||
public IList<MenuItem> ContextActions
|
||||
{
|
||||
get
|
||||
|
@ -75,6 +95,8 @@ namespace Xamarin.Forms
|
|||
}
|
||||
}
|
||||
|
||||
double IFlowDirectionController.Width => (Parent as VisualElement)?.Width ?? 0;
|
||||
|
||||
public event EventHandler Appearing;
|
||||
|
||||
public event EventHandler Disappearing;
|
||||
|
@ -136,6 +158,8 @@ namespace Xamarin.Forms
|
|||
}
|
||||
|
||||
base.OnParentSet();
|
||||
|
||||
FlowController.NotifyFlowDirectionChanged();
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanging(string propertyName = null)
|
||||
|
@ -147,6 +171,8 @@ namespace Xamarin.Forms
|
|||
RealParent.PropertyChanged -= OnParentPropertyChanged;
|
||||
RealParent.PropertyChanging -= OnParentPropertyChanging;
|
||||
}
|
||||
|
||||
FlowController.NotifyFlowDirectionChanged();
|
||||
}
|
||||
|
||||
base.OnPropertyChanging(propertyName);
|
||||
|
@ -172,6 +198,19 @@ namespace Xamarin.Forms
|
|||
container.SendCellDisappearing(this);
|
||||
}
|
||||
|
||||
void IFlowDirectionController.NotifyFlowDirectionChanged()
|
||||
{
|
||||
SetFlowDirectionFromParent(this);
|
||||
|
||||
foreach (var element in LogicalChildren)
|
||||
{
|
||||
var view = element as IFlowDirectionController;
|
||||
if (view == null)
|
||||
continue;
|
||||
view.NotifyFlowDirectionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void OnContextActionsChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
for (var i = 0; i < _contextActions.Count; i++)
|
||||
|
@ -202,6 +241,8 @@ namespace Xamarin.Forms
|
|||
// its uncommon enough that we don't want to take the penalty of N GetValue calls to verify.
|
||||
if (e.PropertyName == "RowHeight")
|
||||
OnPropertyChanged("RenderHeight");
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
FlowController.NotifyFlowDirectionChanged();
|
||||
}
|
||||
|
||||
void OnParentPropertyChanging(object sender, PropertyChangingEventArgs e)
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace Xamarin.Forms
|
|||
public static void SetIdiom(TargetIdiom value) => Idiom = value;
|
||||
public static TargetIdiom Idiom { get; internal set; }
|
||||
|
||||
//TODO: Why are there two of these? This is never used...?
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static void SetTargetIdiom(TargetIdiom value) => Idiom = value;
|
||||
|
||||
|
@ -65,6 +66,10 @@ namespace Xamarin.Forms
|
|||
set { info = value; }
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static void SetFlowDirection(FlowDirection value) => FlowDirection = value;
|
||||
public static FlowDirection FlowDirection { get; internal set; }
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static bool IsInvokeRequired
|
||||
{
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
[Flags]
|
||||
public enum EffectiveFlowDirection
|
||||
{
|
||||
RightToLeft = 1 << 0,
|
||||
Explicit = 1 << 1,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class EffectiveFlowDirectionExtensions
|
||||
{
|
||||
internal static EffectiveFlowDirection ToEffectiveFlowDirection(this FlowDirection self, bool isExplicit = false)
|
||||
{
|
||||
switch (self)
|
||||
{
|
||||
case FlowDirection.MatchParent:
|
||||
return default(EffectiveFlowDirection);
|
||||
|
||||
|
||||
case FlowDirection.LeftToRight:
|
||||
if (isExplicit)
|
||||
{
|
||||
return EffectiveFlowDirection.Explicit;
|
||||
}
|
||||
else
|
||||
{
|
||||
return default(EffectiveFlowDirection);
|
||||
}
|
||||
|
||||
case FlowDirection.RightToLeft:
|
||||
if (isExplicit)
|
||||
{
|
||||
return EffectiveFlowDirection.RightToLeft | EffectiveFlowDirection.Explicit;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EffectiveFlowDirection.RightToLeft;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException($"Cannot convert {self} to {nameof(EffectiveFlowDirection)}.");
|
||||
}
|
||||
}
|
||||
|
||||
internal static FlowDirection ToFlowDirection(this EffectiveFlowDirection self)
|
||||
{
|
||||
if (self.IsLeftToRight())
|
||||
return FlowDirection.LeftToRight;
|
||||
else
|
||||
return FlowDirection.RightToLeft;
|
||||
|
||||
throw new InvalidOperationException($"Cannot convert {self} to {nameof(FlowDirection)}.");
|
||||
}
|
||||
|
||||
public static bool IsRightToLeft(this EffectiveFlowDirection self)
|
||||
{
|
||||
return (self & EffectiveFlowDirection.RightToLeft) == EffectiveFlowDirection.RightToLeft;
|
||||
}
|
||||
|
||||
public static bool IsLeftToRight(this EffectiveFlowDirection self)
|
||||
{
|
||||
return (self & EffectiveFlowDirection.RightToLeft) != EffectiveFlowDirection.RightToLeft;
|
||||
}
|
||||
|
||||
public static bool IsImplicit(this EffectiveFlowDirection self)
|
||||
{
|
||||
return (self & EffectiveFlowDirection.Explicit) != EffectiveFlowDirection.Explicit;
|
||||
}
|
||||
|
||||
public static bool IsExplicit(this EffectiveFlowDirection self)
|
||||
{
|
||||
return (self & EffectiveFlowDirection.Explicit) == EffectiveFlowDirection.Explicit;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -503,6 +503,27 @@ namespace Xamarin.Forms
|
|||
|
||||
internal event EventHandler ParentSet;
|
||||
|
||||
internal static void SetFlowDirectionFromParent(Element child)
|
||||
{
|
||||
IFlowDirectionController controller = child as IFlowDirectionController;
|
||||
if (controller == null)
|
||||
return;
|
||||
|
||||
if (controller.EffectiveFlowDirection.IsImplicit())
|
||||
{
|
||||
var parentView = child.Parent as IFlowDirectionController;
|
||||
if (parentView == null)
|
||||
return;
|
||||
|
||||
var flowDirection = parentView.EffectiveFlowDirection.ToFlowDirection();
|
||||
|
||||
if (flowDirection != controller.EffectiveFlowDirection.ToFlowDirection())
|
||||
{
|
||||
controller.EffectiveFlowDirection = flowDirection.ToEffectiveFlowDirection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public event EventHandler PlatformSet;
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
namespace Xamarin.Forms
|
||||
{
|
||||
public enum FlowDirection
|
||||
{
|
||||
MatchParent = 0,
|
||||
LeftToRight = 1,
|
||||
RightToLeft = 2,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace Xamarin.Forms
|
||||
{
|
||||
internal interface IFlowDirectionController
|
||||
{
|
||||
EffectiveFlowDirection EffectiveFlowDirection { get; set; }
|
||||
|
||||
double Width { get; }
|
||||
|
||||
void NotifyFlowDirectionChanged();
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ namespace Xamarin.Forms
|
|||
void InvalidateMeasure(InvalidationTrigger trigger);
|
||||
bool Batched { get; }
|
||||
bool DisableLayout { get; set; }
|
||||
EffectiveFlowDirection EffectiveFlowDirection { get; }
|
||||
bool IsInNativeLayout { get; set; }
|
||||
bool IsNativeStateConsistent { get; set; }
|
||||
bool IsPlatformEnabled { get; set; }
|
||||
|
|
|
@ -55,7 +55,8 @@ namespace Xamarin.Forms
|
|||
public static readonly BindableProperty IsClippedToBoundsProperty = BindableProperty.Create("IsClippedToBounds", typeof(bool), typeof(Layout), false);
|
||||
|
||||
public static readonly BindableProperty PaddingProperty = BindableProperty.Create("Padding", typeof(Thickness), typeof(Layout), default(Thickness),
|
||||
propertyChanged: (bindable, old, newValue) => {
|
||||
propertyChanged: (bindable, old, newValue) =>
|
||||
{
|
||||
var layout = (Layout)bindable;
|
||||
layout.UpdateChildrenLayout();
|
||||
}, defaultValueCreator: (bindable) => ((Layout)bindable).CreateDefaultPadding());
|
||||
|
@ -125,6 +126,11 @@ namespace Xamarin.Forms
|
|||
|
||||
public static void LayoutChildIntoBoundingRegion(VisualElement child, Rectangle region)
|
||||
{
|
||||
var parent = child.Parent as IFlowDirectionController;
|
||||
bool isRightToLeft = false;
|
||||
if (parent != null && (isRightToLeft = parent.EffectiveFlowDirection.IsRightToLeft()))
|
||||
region = new Rectangle(parent.Width - region.Right, region.Y, region.Width, region.Height);
|
||||
|
||||
var view = child as View;
|
||||
if (view == null)
|
||||
{
|
||||
|
@ -137,7 +143,10 @@ namespace Xamarin.Forms
|
|||
{
|
||||
SizeRequest request = child.Measure(region.Width, region.Height, MeasureFlags.IncludeMargins);
|
||||
double diff = Math.Max(0, region.Width - request.Request.Width);
|
||||
region.X += (int)(diff * horizontalOptions.Alignment.ToDouble());
|
||||
double horizontalAlign = horizontalOptions.Alignment.ToDouble();
|
||||
if (isRightToLeft)
|
||||
horizontalAlign = 1 - horizontalAlign;
|
||||
region.X += (int)(diff * horizontalAlign);
|
||||
region.Width -= diff;
|
||||
}
|
||||
|
||||
|
@ -260,23 +269,33 @@ namespace Xamarin.Forms
|
|||
|
||||
internal static void LayoutChildIntoBoundingRegion(View child, Rectangle region, SizeRequest childSizeRequest)
|
||||
{
|
||||
var parent = child.Parent as IFlowDirectionController;
|
||||
bool isRightToLeft = false;
|
||||
if (parent != null && (isRightToLeft = parent.EffectiveFlowDirection.IsRightToLeft()))
|
||||
region = new Rectangle(parent.Width - region.Right, region.Y, region.Width, region.Height);
|
||||
|
||||
if (region.Size != childSizeRequest.Request)
|
||||
{
|
||||
bool canUseAlreadyDoneRequest = region.Width >= childSizeRequest.Request.Width && region.Height >= childSizeRequest.Request.Height;
|
||||
|
||||
if (child.HorizontalOptions.Alignment != LayoutAlignment.Fill)
|
||||
LayoutOptions horizontalOptions = child.HorizontalOptions;
|
||||
if (horizontalOptions.Alignment != LayoutAlignment.Fill)
|
||||
{
|
||||
SizeRequest request = canUseAlreadyDoneRequest ? childSizeRequest : child.Measure(region.Width, region.Height, MeasureFlags.IncludeMargins);
|
||||
double diff = Math.Max(0, region.Width - request.Request.Width);
|
||||
region.X += (int)(diff * child.HorizontalOptions.Alignment.ToDouble());
|
||||
double horizontalAlign = horizontalOptions.Alignment.ToDouble();
|
||||
if (isRightToLeft)
|
||||
horizontalAlign = 1 - horizontalAlign;
|
||||
region.X += (int)(diff * horizontalAlign);
|
||||
region.Width -= diff;
|
||||
}
|
||||
|
||||
if (child.VerticalOptions.Alignment != LayoutAlignment.Fill)
|
||||
LayoutOptions verticalOptions = child.VerticalOptions;
|
||||
if (verticalOptions.Alignment != LayoutAlignment.Fill)
|
||||
{
|
||||
SizeRequest request = canUseAlreadyDoneRequest ? childSizeRequest : child.Measure(region.Width, region.Height, MeasureFlags.IncludeMargins);
|
||||
double diff = Math.Max(0, region.Height - request.Request.Height);
|
||||
region.Y += (int)(diff * child.VerticalOptions.Alignment.ToDouble());
|
||||
region.Y += (int)(diff * verticalOptions.Alignment.ToDouble());
|
||||
region.Height -= diff;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ using Xamarin.Forms.Internals;
|
|||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
public partial class VisualElement : Element, IAnimatable, IVisualElementController, IResourcesProvider
|
||||
public partial class VisualElement : Element, IAnimatable, IVisualElementController, IResourcesProvider, IFlowDirectionController
|
||||
{
|
||||
internal static readonly BindablePropertyKey NavigationPropertyKey = BindableProperty.CreateReadOnly("Navigation", typeof(INavigation), typeof(VisualElement), default(INavigation));
|
||||
|
||||
|
@ -93,6 +93,33 @@ namespace Xamarin.Forms
|
|||
|
||||
public static readonly BindableProperty IsFocusedProperty = IsFocusedPropertyKey.BindableProperty;
|
||||
|
||||
public static readonly BindableProperty FlowDirectionProperty = BindableProperty.Create(nameof(FlowDirection), typeof(FlowDirection), typeof(VisualElement), FlowDirection.MatchParent, propertyChanged: FlowDirectionChanged);
|
||||
|
||||
IFlowDirectionController FlowController => this;
|
||||
|
||||
public FlowDirection FlowDirection
|
||||
{
|
||||
get { return (FlowDirection)GetValue(FlowDirectionProperty); }
|
||||
set { SetValue(FlowDirectionProperty, value); }
|
||||
}
|
||||
|
||||
EffectiveFlowDirection _effectiveFlowDirection = default(EffectiveFlowDirection);
|
||||
EffectiveFlowDirection IFlowDirectionController.EffectiveFlowDirection
|
||||
{
|
||||
get { return _effectiveFlowDirection; }
|
||||
set
|
||||
{
|
||||
if (value == _effectiveFlowDirection)
|
||||
return;
|
||||
|
||||
_effectiveFlowDirection = value;
|
||||
InvalidateMeasureInternal(InvalidationTrigger.Undefined);
|
||||
OnPropertyChanged(FlowDirectionProperty.PropertyName);
|
||||
}
|
||||
}
|
||||
|
||||
EffectiveFlowDirection IVisualElementController.EffectiveFlowDirection => FlowController.EffectiveFlowDirection;
|
||||
|
||||
readonly Dictionary<Size, SizeRequest> _measureCache = new Dictionary<Size, SizeRequest>();
|
||||
|
||||
readonly MergedStyle _mergedStyle;
|
||||
|
@ -250,7 +277,7 @@ namespace Xamarin.Forms
|
|||
set { SetValue(StyleProperty, value); }
|
||||
}
|
||||
|
||||
[TypeConverter (typeof(ListStringTypeConverter))]
|
||||
[TypeConverter(typeof(ListStringTypeConverter))]
|
||||
public IList<string> StyleClass
|
||||
{
|
||||
get { return _mergedStyle.StyleClass; }
|
||||
|
@ -537,9 +564,6 @@ namespace Xamarin.Forms
|
|||
|
||||
if (includeMargins)
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (!margin.IsDefault)
|
||||
{
|
||||
result.Minimum = new Size(result.Minimum.Width + margin.HorizontalThickness, result.Minimum.Height + margin.VerticalThickness);
|
||||
|
@ -616,6 +640,8 @@ namespace Xamarin.Forms
|
|||
NavigationProxy.Inner = null;
|
||||
}
|
||||
#pragma warning restore 0618
|
||||
|
||||
FlowController.NotifyFlowDirectionChanged();
|
||||
}
|
||||
|
||||
protected virtual void OnSizeAllocated(double width, double height)
|
||||
|
@ -738,6 +764,20 @@ namespace Xamarin.Forms
|
|||
focus(this, new FocusEventArgs(this, true));
|
||||
}
|
||||
|
||||
static void FlowDirectionChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
var self = bindable as IFlowDirectionController;
|
||||
|
||||
if (self.EffectiveFlowDirection.IsExplicit() && oldValue == newValue)
|
||||
return;
|
||||
|
||||
var newFlowDirection = (FlowDirection)newValue;
|
||||
|
||||
self.EffectiveFlowDirection = newFlowDirection.ToEffectiveFlowDirection(isExplicit: true);
|
||||
|
||||
self.NotifyFlowDirectionChanged();
|
||||
}
|
||||
|
||||
static void OnIsFocusedPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
|
||||
{
|
||||
var element = bindable as VisualElement;
|
||||
|
@ -777,6 +817,19 @@ namespace Xamarin.Forms
|
|||
unFocus(this, new FocusEventArgs(this, false));
|
||||
}
|
||||
|
||||
void IFlowDirectionController.NotifyFlowDirectionChanged()
|
||||
{
|
||||
SetFlowDirectionFromParent(this);
|
||||
|
||||
foreach (var element in LogicalChildren)
|
||||
{
|
||||
var view = element as IFlowDirectionController;
|
||||
if (view == null)
|
||||
continue;
|
||||
view.NotifyFlowDirectionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SetSize(double width, double height)
|
||||
{
|
||||
if (Width == width && Height == height)
|
||||
|
|
|
@ -77,7 +77,9 @@
|
|||
<Compile Include="DataTemplateSelector.cs" />
|
||||
<Compile Include="DateChangedEventArgs.cs" />
|
||||
<Compile Include="DelegateLogListener.cs" />
|
||||
<Compile Include="EffectiveFlowDirectionExtensions.cs" />
|
||||
<Compile Include="IEditorController.cs" />
|
||||
<Compile Include="IFlowDirectionController.cs" />
|
||||
<Compile Include="IGridController.cs" />
|
||||
<Compile Include="IWebViewController.cs" />
|
||||
<Compile Include="INavigationMenuController.cs" />
|
||||
|
@ -110,6 +112,8 @@
|
|||
<Compile Include="IElementConfiguration.cs" />
|
||||
<Compile Include="IPlatformElementConfiguration.cs" />
|
||||
<Compile Include="PlatformConfigurationRegistry.cs" />
|
||||
<Compile Include="EffectiveFlowDirection.cs" />
|
||||
<Compile Include="FlowDirection.cs" />
|
||||
<Compile Include="IFontElement.cs" />
|
||||
<Compile Include="DependencyAttribute.cs" />
|
||||
<Compile Include="DependencyFetchTarget.cs" />
|
||||
|
|
|
@ -153,6 +153,8 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
|
|||
UpdateMaster();
|
||||
UpdateDetail();
|
||||
|
||||
UpdateFlowDirection();
|
||||
|
||||
((IMasterDetailPageController)newElement).BackButtonPressed += OnBackButtonPressed;
|
||||
newElement.PropertyChanged += HandlePropertyChanged;
|
||||
newElement.Appearing += MasterDetailPageAppearing;
|
||||
|
@ -310,6 +312,8 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
|
|||
UpdateBackgroundImage(Element);
|
||||
else if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
|
||||
UpdateBackgroundColor(Element);
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
void MasterDetailPageAppearing(object sender, EventArgs e)
|
||||
|
@ -367,6 +371,11 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
|
|||
_detailLayout.ChildView = Element.Detail;
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
this.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
void UpdateIsPresented()
|
||||
{
|
||||
if (_isPresentingFromCore)
|
||||
|
|
|
@ -11,6 +11,7 @@ using AColor = Android.Graphics.Color;
|
|||
using AColorDraw = Android.Graphics.Drawables.ColorDrawable;
|
||||
using Xamarin.Forms.Internals;
|
||||
using Android.Support.V4.Widget;
|
||||
using Android.OS;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
|
@ -80,6 +81,12 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
SetMinimumHeight((int)context.ToPixels(DefaultMinHeight));
|
||||
_androidDefaultTextColor = Color.FromUint((uint)_mainText.CurrentTextColor);
|
||||
|
||||
if ((int)Build.VERSION.SdkInt > 16)
|
||||
{
|
||||
_mainText.TextAlignment = global::Android.Views.TextAlignment.ViewStart;
|
||||
_detailText.TextAlignment = global::Android.Views.TextAlignment.ViewStart;
|
||||
}
|
||||
}
|
||||
|
||||
public AView AccessoryView { get; private set; }
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateText();
|
||||
UpdateIsEnabled();
|
||||
UpdateHeight();
|
||||
UpdateFlowDirection();
|
||||
|
||||
_view.TextChanged = OnTextChanged;
|
||||
_view.EditingCompleted = OnEditingCompleted;
|
||||
|
@ -56,6 +57,11 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateIsEnabled();
|
||||
else if (e.PropertyName == "RenderHeight")
|
||||
UpdateHeight();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
{
|
||||
UpdateFlowDirection();
|
||||
UpdateHorizontalTextAlignment();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual NumberKeyListener GetDigitsKeyListener(InputTypes inputTypes)
|
||||
|
@ -86,7 +92,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
void UpdateHorizontalTextAlignment()
|
||||
{
|
||||
var entryCell = (EntryCell)Cell;
|
||||
_view.EditText.Gravity = entryCell.HorizontalTextAlignment.ToHorizontalGravityFlags();
|
||||
_view.EditText.UpdateHorizontalAlignment(entryCell.HorizontalTextAlignment);
|
||||
}
|
||||
|
||||
void UpdateIsEnabled()
|
||||
|
@ -117,6 +123,11 @@ namespace Xamarin.Forms.Platform.Android
|
|||
_view.SetLabelTextColor(((EntryCell)Cell).LabelColor, global::Android.Resource.Color.PrimaryTextDark);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
_view.UpdateFlowDirection(ParentView);
|
||||
}
|
||||
|
||||
void UpdatePlaceholder()
|
||||
{
|
||||
var entryCell = (EntryCell)Cell;
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
var result = (BaseCellView)base.GetCellCore(item, convertView, parent, context);
|
||||
|
||||
UpdateImage();
|
||||
UpdateFlowDirection();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -20,6 +21,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
base.OnCellPropertyChanged(sender, args);
|
||||
if (args.PropertyName == ImageCell.ImageSourceProperty.PropertyName)
|
||||
UpdateImage();
|
||||
else if (args.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
void UpdateImage()
|
||||
|
@ -33,5 +36,10 @@ namespace Xamarin.Forms.Platform.Android
|
|||
else
|
||||
View.SetImageVisible(false);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
View.UpdateFlowDirection(ParentView);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
public class SwitchCellRenderer : CellRenderer
|
||||
{
|
||||
const double DefaultHeight = 30;
|
||||
SwitchCellView _view;
|
||||
|
||||
protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context)
|
||||
|
@ -24,6 +23,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateChecked();
|
||||
UpdateHeight();
|
||||
UpdateIsEnabled(_view, cell);
|
||||
UpdateFlowDirection();
|
||||
|
||||
return _view;
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateHeight();
|
||||
else if (args.PropertyName == Cell.IsEnabledProperty.PropertyName)
|
||||
UpdateIsEnabled(_view, (SwitchCell)sender);
|
||||
else if (args.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
void UpdateChecked()
|
||||
|
@ -53,6 +55,11 @@ namespace Xamarin.Forms.Platform.Android
|
|||
aSwitch.Enabled = switchCell.IsEnabled;
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
_view.UpdateFlowDirection(ParentView);
|
||||
}
|
||||
|
||||
void UpdateHeight()
|
||||
{
|
||||
_view.SetRenderHeight(Cell.RenderHeight);
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Views;
|
||||
using AView = Android.Views.View;
|
||||
using AColor = Android.Graphics.Color;
|
||||
using Xamarin.Forms.Internals;
|
||||
using AView = Android.Views.View;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
|
@ -20,6 +19,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateDetailText();
|
||||
UpdateHeight();
|
||||
UpdateIsEnabled();
|
||||
UpdateFlowDirection();
|
||||
View.SetImageVisible(false);
|
||||
|
||||
return View;
|
||||
|
@ -35,6 +35,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateIsEnabled();
|
||||
else if (args.PropertyName == "RenderHeight")
|
||||
UpdateHeight();
|
||||
else if (args.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
void UpdateDetailText()
|
||||
|
@ -55,6 +57,11 @@ namespace Xamarin.Forms.Platform.Android
|
|||
View.SetIsEnabled(cell.IsEnabled);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
View.UpdateFlowDirection(ParentView);
|
||||
}
|
||||
|
||||
void UpdateMainText()
|
||||
{
|
||||
var cell = (TextCell)Cell;
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
using Android.OS;
|
||||
using Android.Widget;
|
||||
using Xamarin.Forms.Internals;
|
||||
using ALayoutDirection = Android.Views.LayoutDirection;
|
||||
using AView = Android.Views.View;
|
||||
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
internal static class FlowDirectionExtensions
|
||||
{
|
||||
internal static FlowDirection ToFlowDirection(this ALayoutDirection direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case ALayoutDirection.Ltr:
|
||||
return FlowDirection.LeftToRight;
|
||||
case ALayoutDirection.Rtl:
|
||||
return FlowDirection.RightToLeft;
|
||||
default:
|
||||
return FlowDirection.MatchParent;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UpdateFlowDirection(this AView view, IVisualElementController controller)
|
||||
{
|
||||
if (view == null || controller == null || (int)Build.VERSION.SdkInt < 17)
|
||||
return;
|
||||
|
||||
if (controller.EffectiveFlowDirection.IsRightToLeft())
|
||||
view.LayoutDirection = ALayoutDirection.Rtl;
|
||||
else if (controller.EffectiveFlowDirection.IsLeftToRight())
|
||||
view.LayoutDirection = ALayoutDirection.Ltr;
|
||||
}
|
||||
|
||||
internal static void UpdateHorizontalAlignment(this EditText view, TextAlignment alignment)
|
||||
{
|
||||
if ((int)Build.VERSION.SdkInt < 17)
|
||||
view.Gravity = alignment.ToHorizontalGravityFlags();
|
||||
else
|
||||
view.TextAlignment = alignment.ToTextAlignment();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ using System.ComponentModel;
|
|||
using Android.Views;
|
||||
using Xamarin.Forms.Internals;
|
||||
using AView = Android.Views.View;
|
||||
using Object = Java.Lang.Object;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android.FastRenderers
|
||||
{
|
||||
|
@ -14,7 +13,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
|
||||
IVisualElementRenderer _renderer;
|
||||
readonly GestureManager _gestureManager;
|
||||
readonly AutomationPropertiesProvider _automatiomPropertiesProvider;
|
||||
readonly AutomationPropertiesProvider _automationPropertiesProvider;
|
||||
readonly EffectControlProvider _effectControlProvider;
|
||||
|
||||
public VisualElementRenderer(IVisualElementRenderer renderer)
|
||||
|
@ -23,13 +22,13 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
_renderer.ElementPropertyChanged += OnElementPropertyChanged;
|
||||
_renderer.ElementChanged += OnElementChanged;
|
||||
_gestureManager = new GestureManager(_renderer);
|
||||
_automatiomPropertiesProvider = new AutomationPropertiesProvider(_renderer);
|
||||
_automationPropertiesProvider = new AutomationPropertiesProvider(_renderer);
|
||||
|
||||
_effectControlProvider = new EffectControlProvider(_renderer?.View);
|
||||
}
|
||||
|
||||
VisualElement Element => _renderer?.Element;
|
||||
|
||||
|
||||
AView Control => _renderer?.View;
|
||||
|
||||
void IEffectControlProvider.RegisterEffect(Effect effect)
|
||||
|
@ -45,7 +44,15 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
Control.SetBackgroundColor((color ?? Element.BackgroundColor).ToAndroid());
|
||||
}
|
||||
|
||||
public bool OnTouchEvent(MotionEvent e)
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
public bool OnTouchEvent(MotionEvent e)
|
||||
{
|
||||
return _gestureManager.OnTouchEvent(e);
|
||||
}
|
||||
|
@ -66,7 +73,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
if (disposing)
|
||||
{
|
||||
_gestureManager?.Dispose();
|
||||
_automatiomPropertiesProvider?.Dispose();
|
||||
_automationPropertiesProvider?.Dispose();
|
||||
|
||||
if (_renderer != null)
|
||||
{
|
||||
|
@ -88,6 +95,7 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
{
|
||||
e.NewElement.PropertyChanged += OnElementPropertyChanged;
|
||||
UpdateBackgroundColor();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
EffectUtilities.RegisterEffectControlProvider(this, e.OldElement, e.NewElement);
|
||||
|
@ -97,6 +105,8 @@ namespace Xamarin.Forms.Platform.Android.FastRenderers
|
|||
{
|
||||
if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
|
||||
UpdateBackgroundColor();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ using Xamarin.Forms.Internals;
|
|||
using Xamarin.Forms.Platform.Android;
|
||||
using Resource = Android.Resource;
|
||||
using Trace = System.Diagnostics.Trace;
|
||||
using ALayoutDirection = Android.Views.LayoutDirection;
|
||||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
|
@ -69,7 +70,7 @@ namespace Xamarin.Forms
|
|||
+ "Please use SetTitleBarVisibility(Activity, AndroidTitleBarVisibility) instead.")]
|
||||
public static void SetTitleBarVisibility(AndroidTitleBarVisibility visibility)
|
||||
{
|
||||
if((Activity)Context == null)
|
||||
if ((Activity)Context == null)
|
||||
throw new NullReferenceException("Must be called after Xamarin.Forms.Forms.Init() method");
|
||||
|
||||
if (visibility == AndroidTitleBarVisibility.Never)
|
||||
|
@ -138,7 +139,7 @@ namespace Xamarin.Forms
|
|||
// We want this to be updated when we have a new activity (e.g. on a configuration change)
|
||||
// because AndroidPlatformServices needs a current activity to launch URIs from
|
||||
Device.PlatformServices = new AndroidPlatformServices(activity);
|
||||
|
||||
|
||||
// use field and not property to avoid exception in getter
|
||||
if (Device.info != null)
|
||||
{
|
||||
|
@ -165,6 +166,7 @@ namespace Xamarin.Forms
|
|||
// This could change as a result of a config change, so we need to check it every time
|
||||
int minWidthDp = activity.Resources.Configuration.SmallestScreenWidthDp;
|
||||
Device.SetIdiom(minWidthDp >= TabletCrossover ? TargetIdiom.Tablet : TargetIdiom.Phone);
|
||||
Device.SetFlowDirection(activity.Resources.Configuration.LayoutDirection.ToFlowDirection());
|
||||
|
||||
if (ExpressionSearch.Default == null)
|
||||
ExpressionSearch.Default = new AndroidExpressionSearch();
|
||||
|
@ -198,11 +200,11 @@ namespace Xamarin.Forms
|
|||
Color rc;
|
||||
using (var value = new TypedValue())
|
||||
{
|
||||
if (context.Theme.ResolveAttribute(global::Android.Resource.Attribute.ColorAccent, value, true) && Forms.IsLollipopOrNewer) // Android 5.0+
|
||||
if (context.Theme.ResolveAttribute(global::Android.Resource.Attribute.ColorAccent, value, true) && Forms.IsLollipopOrNewer) // Android 5.0+
|
||||
{
|
||||
rc = Color.FromUint((uint)value.Data);
|
||||
}
|
||||
else if(context.Theme.ResolveAttribute(context.Resources.GetIdentifier("colorAccent", "attr", context.PackageName), value, true)) // < Android 5.0
|
||||
else if (context.Theme.ResolveAttribute(context.Resources.GetIdentifier("colorAccent", "attr", context.PackageName), value, true)) // < Android 5.0
|
||||
{
|
||||
rc = Color.FromUint((uint)value.Data);
|
||||
}
|
||||
|
@ -475,7 +477,7 @@ namespace Xamarin.Forms
|
|||
{
|
||||
global::Android.Net.Uri aUri = global::Android.Net.Uri.Parse(uri.ToString());
|
||||
var intent = new Intent(Intent.ActionView, aUri);
|
||||
|
||||
|
||||
// This seems to work fine even if the context has been destroyed (while another activity is in the
|
||||
// foreground). If we run into a situation where that's not the case, we'll have to do some work to
|
||||
// make sure this uses the active activity when launching the Intent
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
using Android.Views;
|
||||
using ATextAlignment = Android.Views.TextAlignment;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
internal static class AlignmentExtensions
|
||||
{
|
||||
internal static ATextAlignment ToTextAlignment(this TextAlignment alignment)
|
||||
{
|
||||
switch (alignment)
|
||||
{
|
||||
case TextAlignment.Center:
|
||||
return ATextAlignment.Center;
|
||||
case TextAlignment.End:
|
||||
return ATextAlignment.ViewEnd;
|
||||
default:
|
||||
return ATextAlignment.ViewStart;
|
||||
}
|
||||
}
|
||||
|
||||
internal static GravityFlags ToHorizontalGravityFlags(this TextAlignment alignment)
|
||||
{
|
||||
switch (alignment)
|
||||
|
@ -11,9 +25,9 @@ namespace Xamarin.Forms.Platform.Android
|
|||
case TextAlignment.Center:
|
||||
return GravityFlags.CenterHorizontal;
|
||||
case TextAlignment.End:
|
||||
return GravityFlags.Right;
|
||||
return GravityFlags.End;
|
||||
default:
|
||||
return GravityFlags.Left;
|
||||
return GravityFlags.Start;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.ComponentModel;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.OS;
|
||||
using Android.Text;
|
||||
using Android.Text.Method;
|
||||
using Android.Util;
|
||||
|
@ -28,7 +29,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
AutoPackage = false;
|
||||
}
|
||||
|
||||
IEditorController ElementController => Element;
|
||||
IEditorController ElementController => Element;
|
||||
|
||||
void ITextWatcher.AfterTextChanged(IEditable s)
|
||||
{
|
||||
|
@ -70,6 +71,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
edit.SetSingleLine(false);
|
||||
edit.Gravity = GravityFlags.Top;
|
||||
if ((int)Build.VERSION.SdkInt > 16)
|
||||
edit.TextAlignment = global::Android.Views.TextAlignment.ViewStart;
|
||||
edit.SetHorizontallyScrolling(false);
|
||||
|
||||
UpdateText();
|
||||
|
@ -127,7 +130,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
internal override void OnNativeFocusChanged(bool hasFocus)
|
||||
{
|
||||
if (Element.IsFocused && !hasFocus) // Editor has requested an unfocus, fire completed event
|
||||
ElementController.SendCompleted();
|
||||
ElementController.SendCompleted();
|
||||
}
|
||||
|
||||
void UpdateFont()
|
||||
|
|
|
@ -9,8 +9,6 @@ using Android.Views;
|
|||
using Android.Views.InputMethods;
|
||||
using Android.Widget;
|
||||
using Java.Lang;
|
||||
using Xamarin.Forms.Internals;
|
||||
using Xamarin.Forms.PlatformConfiguration.AndroidSpecific;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
|
@ -143,6 +141,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateFont();
|
||||
else if (e.PropertyName == Entry.PlaceholderColorProperty.PropertyName)
|
||||
UpdatePlaceholderColor();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
|
||||
void UpdateAlignment()
|
||||
{
|
||||
Control.Gravity = Element.HorizontalTextAlignment.ToHorizontalGravityFlags();
|
||||
Control.UpdateHorizontalAlignment(Element.HorizontalTextAlignment);
|
||||
}
|
||||
|
||||
void UpdateColor()
|
||||
|
|
|
@ -115,6 +115,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateTextColor();
|
||||
else if (e.PropertyName == SearchBar.PlaceholderColorProperty.PropertyName)
|
||||
UpdatePlaceholderColor();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
}
|
||||
|
||||
internal override void OnNativeFocusChanged(bool hasFocus)
|
||||
|
@ -130,7 +132,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
if (_editText == null)
|
||||
return;
|
||||
|
||||
_editText.Gravity = Element.HorizontalTextAlignment.ToHorizontalGravityFlags() | Xamarin.Forms.TextAlignment.Center.ToVerticalGravityFlags();
|
||||
_editText.UpdateHorizontalAlignment(Element.HorizontalTextAlignment);
|
||||
}
|
||||
|
||||
void UpdateCancelButtonColor()
|
||||
|
|
|
@ -8,6 +8,7 @@ using Android.Text.Format;
|
|||
using ADatePicker = Android.Widget.DatePicker;
|
||||
using ATimePicker = Android.Widget.TimePicker;
|
||||
using Object = Java.Lang.Object;
|
||||
using Android.OS;
|
||||
|
||||
namespace Xamarin.Forms.Platform.Android
|
||||
{
|
||||
|
@ -60,12 +61,15 @@ namespace Xamarin.Forms.Platform.Android
|
|||
textField.SetOnClickListener(TimePickerListener.Instance);
|
||||
SetNativeControl(textField);
|
||||
_textColorSwitcher = new TextColorSwitcher(textField.TextColors);
|
||||
_is24HourFormat = DateFormat.Is24HourFormat(Context);
|
||||
_is24HourFormat = DateFormat.Is24HourFormat(Context);
|
||||
_timeFormat = _is24HourFormat ? "HH:mm" : Element.Format;
|
||||
}
|
||||
|
||||
SetTime(e.NewElement.Time);
|
||||
UpdateTextColor();
|
||||
|
||||
if ((int)Build.VERSION.SdkInt > 16)
|
||||
Control.TextAlignment = global::Android.Views.TextAlignment.ViewStart;
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
|
@ -73,7 +77,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
base.OnElementPropertyChanged(sender, e);
|
||||
|
||||
if (e.PropertyName == TimePicker.TimeProperty.PropertyName ||
|
||||
e.PropertyName == TimePicker.FormatProperty.PropertyName)
|
||||
e.PropertyName == TimePicker.FormatProperty.PropertyName)
|
||||
SetTime(Element.Time);
|
||||
|
||||
if (e.PropertyName == TimePicker.TextColorProperty.PropertyName)
|
||||
|
@ -103,7 +107,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
{
|
||||
TimePicker view = Element;
|
||||
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
|
||||
|
||||
|
||||
_dialog = new TimePickerDialog(Context, this, view.Time.Hours, view.Time.Minutes, _is24HourFormat);
|
||||
|
||||
if (Forms.IsLollipopOrNewer)
|
||||
|
|
|
@ -147,6 +147,8 @@ namespace Xamarin.Forms.Platform.Android
|
|||
UpdateIsEnabled();
|
||||
else if (e.PropertyName == AutomationProperties.LabeledByProperty.PropertyName)
|
||||
SetLabeledBy();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
protected override void OnLayout(bool changed, int l, int t, int r, int b)
|
||||
|
@ -319,6 +321,7 @@ namespace Xamarin.Forms.Platform.Android
|
|||
Control.OnFocusChangeListener = this;
|
||||
|
||||
UpdateIsEnabled();
|
||||
UpdateFlowDirection();
|
||||
SetLabeledBy();
|
||||
}
|
||||
|
||||
|
@ -345,5 +348,10 @@ namespace Xamarin.Forms.Platform.Android
|
|||
if (Control != null)
|
||||
Control.Enabled = Element.IsEnabled;
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
<Compile Include="ExportCellAttribute.cs" />
|
||||
<Compile Include="ExportImageSourceHandlerAttribute.cs" />
|
||||
<Compile Include="ExportRendererAttribute.cs" />
|
||||
<Compile Include="Extensions\FlowDirectionExtensions.cs" />
|
||||
<Compile Include="GestureManager.cs" />
|
||||
<Compile Include="FastRenderers\LabelRenderer.cs" />
|
||||
<Compile Include="FastRenderers\VisualElementRenderer.cs" />
|
||||
|
@ -300,4 +301,4 @@
|
|||
<Import Project="..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.targets" Condition="Exists('..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.targets')" />
|
||||
<Import Project="..\packages\Xamarin.Android.Support.v7.AppCompat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.AppCompat.targets" Condition="Exists('..\packages\Xamarin.Android.Support.v7.AppCompat.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.AppCompat.targets')" />
|
||||
<Import Project="..\packages\Xamarin.Android.Support.Design.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Design.targets" Condition="Exists('..\packages\Xamarin.Android.Support.Design.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Design.targets')" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -80,6 +80,8 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateHorizontalTextAlignment(realCell, entryCell);
|
||||
else if (e.PropertyName == Cell.IsEnabledProperty.PropertyName)
|
||||
UpdateIsEnabled(realCell, entryCell);
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateHorizontalTextAlignment(realCell, entryCell);
|
||||
}
|
||||
|
||||
static void OnTextFieldTextChanged(object sender, EventArgs eventArgs)
|
||||
|
@ -101,9 +103,11 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
static void UpdateHorizontalTextAlignment(CellNSView cell, EntryCell entryCell)
|
||||
{
|
||||
IVisualElementController viewController = entryCell.Parent as VisualElement;
|
||||
|
||||
var nsTextField = cell.AccessoryView.Subviews[0] as NSTextField;
|
||||
if (nsTextField != null)
|
||||
nsTextField.Alignment = entryCell.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
nsTextField.Alignment = entryCell.HorizontalTextAlignment.ToNativeTextAlignment(viewController?.EffectiveFlowDirection ?? default(EffectiveFlowDirection));
|
||||
}
|
||||
|
||||
static void UpdateIsEnabled(CellNSView cell, EntryCell entryCell)
|
||||
|
|
|
@ -1,20 +1,28 @@
|
|||
using System;
|
||||
using AppKit;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Platform.MacOS
|
||||
{
|
||||
internal static class AlignmentExtensions
|
||||
{
|
||||
internal static NSTextAlignment ToNativeTextAlignment(this TextAlignment alignment)
|
||||
internal static NSTextAlignment ToNativeTextAlignment(this TextAlignment alignment, EffectiveFlowDirection flowDirection)
|
||||
{
|
||||
var isLtr = flowDirection.IsLeftToRight();
|
||||
switch (alignment)
|
||||
{
|
||||
case TextAlignment.Center:
|
||||
return NSTextAlignment.Center;
|
||||
case TextAlignment.End:
|
||||
return NSTextAlignment.Right;
|
||||
if (isLtr)
|
||||
return NSTextAlignment.Right;
|
||||
else
|
||||
return NSTextAlignment.Left;
|
||||
default:
|
||||
return NSTextAlignment.Left;
|
||||
if (isLtr)
|
||||
return NSTextAlignment.Left;
|
||||
else
|
||||
return NSTextAlignment.Natural;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
using AppKit;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Platform.MacOS
|
||||
{
|
||||
internal static class FlowDirectionExtensions
|
||||
{
|
||||
internal static FlowDirection ToFlowDirection(this NSApplicationLayoutDirection direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case NSApplicationLayoutDirection.LeftToRight:
|
||||
return FlowDirection.LeftToRight;
|
||||
case NSApplicationLayoutDirection.RightToLeft:
|
||||
return FlowDirection.RightToLeft;
|
||||
default:
|
||||
return FlowDirection.MatchParent;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UpdateFlowDirection(this NSView view, IVisualElementController controller)
|
||||
{
|
||||
if (controller == null || view == null)
|
||||
return;
|
||||
|
||||
if (controller.EffectiveFlowDirection.IsRightToLeft())
|
||||
view.UserInterfaceLayoutDirection = NSUserInterfaceLayoutDirection.RightToLeft;
|
||||
else if (controller.EffectiveFlowDirection.IsLeftToRight())
|
||||
view.UserInterfaceLayoutDirection = NSUserInterfaceLayoutDirection.LeftToRight;
|
||||
}
|
||||
|
||||
internal static void UpdateFlowDirection(this NSTextField control, IVisualElementController controller)
|
||||
{
|
||||
if (controller == null || control == null)
|
||||
return;
|
||||
|
||||
if (controller.EffectiveFlowDirection.IsRightToLeft())
|
||||
{
|
||||
control.Alignment = NSTextAlignment.Right;
|
||||
}
|
||||
else if (controller.EffectiveFlowDirection.IsLeftToRight())
|
||||
{
|
||||
control.Alignment = NSTextAlignment.Left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -98,6 +98,8 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateColor();
|
||||
UpdatePlaceholder();
|
||||
}
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
}
|
||||
|
@ -152,7 +154,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
void UpdateAlignment()
|
||||
{
|
||||
Control.Alignment = Element.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
Control.Alignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
|
||||
}
|
||||
|
||||
void UpdateColor()
|
||||
|
|
|
@ -83,6 +83,8 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateFont();
|
||||
else if (e.PropertyName == SearchBar.HorizontalTextAlignmentProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
}
|
||||
|
||||
protected override void SetBackgroundColor(Color color)
|
||||
|
@ -125,7 +127,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
void UpdateAlignment()
|
||||
{
|
||||
Control.Alignment = Element.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
Control.Alignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
|
||||
}
|
||||
|
||||
void UpdateCancelButton()
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
<Compile Include="..\Xamarin.Forms.Platform.iOS\Flags.cs">
|
||||
<Link>Flags.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Extensions\FlowDirectionExtensions.cs" />
|
||||
<Compile Include="FormsApplicationDelegate.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PlatformRenderer.cs" />
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Automation;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Media;
|
||||
|
@ -18,7 +17,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
bool _showTitle;
|
||||
|
||||
VisualElementTracker<Page, FrameworkElement> _tracker;
|
||||
|
||||
|
||||
public MasterDetailControl Control { get; private set; }
|
||||
|
||||
public MasterDetailPage Element { get; private set; }
|
||||
|
@ -169,6 +168,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
UpdateMode();
|
||||
else if(e.PropertyName == PlatformConfiguration.WindowsSpecific.Page.ToolbarPlacementProperty.PropertyName)
|
||||
UpdateToolbarPlacement();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
void ClearDetail()
|
||||
|
@ -208,6 +209,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
|
||||
Element.SendAppearing();
|
||||
UpdateBounds();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
void OnControlUnloaded(object sender, RoutedEventArgs routedEventArgs)
|
||||
|
@ -277,6 +279,11 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
(this as ITitleProvider).ShowTitle = !string.IsNullOrEmpty(Control.DetailTitle);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
void UpdateIsPresented()
|
||||
{
|
||||
// Ignore the IsPresented value being set to false for Split mode on desktop and allow the master
|
||||
|
|
|
@ -408,7 +408,7 @@
|
|||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="SwitchCell">
|
||||
<Grid HorizontalAlignment="Stretch">
|
||||
<Grid HorizontalAlignment="Stretch" x:Name="ParentGrid">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
|
@ -416,7 +416,7 @@
|
|||
|
||||
<TextBlock Grid.Column="0" Text="{Binding Text}" VerticalAlignment="Center" Style="{ThemeResource BaseTextBlockStyle}" />
|
||||
|
||||
<ToggleSwitch Grid.Column="1" IsOn="{Binding On, Mode=TwoWay}" OnContent="" OffContent="" VerticalAlignment="Center" />
|
||||
<ToggleSwitch Grid.Column="1" IsOn="{Binding On, Mode=TwoWay}" OnContent="" OffContent="" VerticalAlignment="Center" FlowDirection="{Binding FlowDirection, ElementName=ParentGrid }" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
UpdateTextColor();
|
||||
else if (e.PropertyName == SearchBar.PlaceholderColorProperty.PropertyName)
|
||||
UpdatePlaceholderColor();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
}
|
||||
|
||||
void OnControlLoaded(object sender, RoutedEventArgs routedEventArgs)
|
||||
|
@ -92,7 +94,7 @@ namespace Xamarin.Forms.Platform.UWP
|
|||
if (_queryTextBox == null)
|
||||
return;
|
||||
|
||||
_queryTextBox.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
_queryTextBox.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
|
||||
}
|
||||
|
||||
void UpdateCancelButtonColor()
|
||||
|
|
|
@ -134,6 +134,9 @@
|
|||
<Compile Include="..\Xamarin.Forms.Platform.WinRT\BrushHelpers.cs">
|
||||
<Link>BrushHelpers.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Xamarin.Forms.Platform.WinRT\FlowDirectionExtensions.cs">
|
||||
<Link>FlowDirectionExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Xamarin.Forms.Platform.WinRT\FormsProgressBar.cs">
|
||||
<Link>FormsProgressBar.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Diagnostics;
|
|||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.ApplicationModel.Resources.Core;
|
||||
using Windows.Foundation.Metadata;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Core;
|
||||
|
@ -48,6 +49,7 @@ namespace Xamarin.Forms
|
|||
Windows.UI.Xaml.Application.Current.Resources.MergedDictionaries.Add(GetTabletResources());
|
||||
|
||||
Device.SetIdiom(TargetIdiom.Tablet);
|
||||
Device.SetFlowDirection(GetFlowDirection());
|
||||
Device.PlatformServices = new WindowsPlatformServices(Window.Current.Dispatcher);
|
||||
#if WINDOWS_UWP
|
||||
Device.SetFlags(s_flags);
|
||||
|
@ -96,6 +98,17 @@ namespace Xamarin.Forms
|
|||
return Windows.Foundation.Metadata.Platform.Windows;
|
||||
}
|
||||
|
||||
static FlowDirection GetFlowDirection()
|
||||
{
|
||||
string resourceFlowDirection = ResourceContext.GetForCurrentView().QualifierValues["LayoutDirection"];
|
||||
if (resourceFlowDirection == "LTR")
|
||||
return FlowDirection.LeftToRight;
|
||||
else if (resourceFlowDirection == "RTL")
|
||||
return FlowDirection.RightToLeft;
|
||||
|
||||
return FlowDirection.MatchParent;
|
||||
}
|
||||
|
||||
static Windows.UI.Xaml.ResourceDictionary GetTabletResources()
|
||||
{
|
||||
return new Windows.UI.Xaml.ResourceDictionary {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Windows.UI.Xaml;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
#if WINDOWS_UWP
|
||||
|
||||
|
@ -10,16 +11,23 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
{
|
||||
internal static class AlignmentExtensions
|
||||
{
|
||||
internal static Windows.UI.Xaml.TextAlignment ToNativeTextAlignment(this TextAlignment alignment)
|
||||
internal static Windows.UI.Xaml.TextAlignment ToNativeTextAlignment(this TextAlignment alignment, EffectiveFlowDirection flowDirection = default(EffectiveFlowDirection))
|
||||
{
|
||||
var isLtr = flowDirection.IsLeftToRight();
|
||||
switch (alignment)
|
||||
{
|
||||
case TextAlignment.Center:
|
||||
return Windows.UI.Xaml.TextAlignment.Center;
|
||||
case TextAlignment.End:
|
||||
return Windows.UI.Xaml.TextAlignment.Right;
|
||||
if (isLtr)
|
||||
return Windows.UI.Xaml.TextAlignment.Right;
|
||||
else
|
||||
return Windows.UI.Xaml.TextAlignment.Left;
|
||||
default:
|
||||
return Windows.UI.Xaml.TextAlignment.Left;
|
||||
if (isLtr)
|
||||
return Windows.UI.Xaml.TextAlignment.Left;
|
||||
else
|
||||
return Windows.UI.Xaml.TextAlignment.Right;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,8 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
{
|
||||
SetupContextMenu();
|
||||
}
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection(Cell);
|
||||
}
|
||||
|
||||
void OnClick(object sender, PointerRoutedEventArgs e)
|
||||
|
@ -263,6 +265,7 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
newCell.SendAppearing();
|
||||
|
||||
UpdateContent(newCell);
|
||||
UpdateFlowDirection(newCell);
|
||||
SetupContextMenu();
|
||||
|
||||
newCell.PropertyChanged += _propertyChangedHandler;
|
||||
|
@ -316,5 +319,13 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
|
||||
((FrameworkElement)Content).DataContext = newCell;
|
||||
}
|
||||
|
||||
void UpdateFlowDirection(Cell newCell)
|
||||
{
|
||||
if (newCell is ViewCell)
|
||||
return;
|
||||
|
||||
this.UpdateFlowDirection(newCell.Parent as VisualElement);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,6 +43,7 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
UpdateMinimumDate();
|
||||
UpdateMaximumDate();
|
||||
UpdateDate(e.NewElement.Date);
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
base.OnElementChanged(e);
|
||||
|
@ -68,6 +69,8 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
UpdateMinimumDate();
|
||||
else if (e.PropertyName == DatePicker.TextColorProperty.PropertyName)
|
||||
UpdateTextColor();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
protected override bool PreventGestureBubbling { get; set; } = true;
|
||||
|
@ -87,6 +90,11 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
Control.Date = date;
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
void UpdateMaximumDate()
|
||||
{
|
||||
DateTime maxdate = Element.MaximumDate;
|
||||
|
|
|
@ -44,6 +44,8 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
UpdateInputScope();
|
||||
UpdateTextColor();
|
||||
UpdateFont();
|
||||
UpdateTextAlignment();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
base.OnElementChanged(e);
|
||||
|
@ -84,6 +86,11 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
{
|
||||
UpdateText();
|
||||
}
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
{
|
||||
UpdateTextAlignment();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
}
|
||||
|
||||
void OnLostFocus(object sender, RoutedEventArgs e)
|
||||
|
@ -174,6 +181,11 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
Control.SelectionStart = Control.Text.Length;
|
||||
}
|
||||
|
||||
void UpdateTextAlignment()
|
||||
{
|
||||
Control.UpdateTextAlignment(Element);
|
||||
}
|
||||
|
||||
void UpdateTextColor()
|
||||
{
|
||||
Color textColor = Element.TextColor;
|
||||
|
@ -184,5 +196,10 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
BrushHelpers.UpdateColor(textColor, ref _defaultTextColorFocusBrush,
|
||||
() => Control.ForegroundFocusBrush, brush => Control.ForegroundFocusBrush = brush);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -87,6 +87,8 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
UpdateAlignment();
|
||||
else if (e.PropertyName == Entry.PlaceholderColorProperty.PropertyName)
|
||||
UpdatePlaceholderColor();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
}
|
||||
|
||||
protected override void UpdateBackgroundColor()
|
||||
|
@ -126,7 +128,7 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
|
||||
void UpdateAlignment()
|
||||
{
|
||||
Control.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
Control.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
|
||||
}
|
||||
|
||||
void UpdateFont()
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using Windows.UI.Xaml;
|
||||
using WFlowDirection = Windows.UI.Xaml.FlowDirection;
|
||||
using WTextAlignment = Windows.UI.Xaml.TextAlignment;
|
||||
using Xamarin.Forms.Internals;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
#if WINDOWS_UWP
|
||||
namespace Xamarin.Forms.Platform.UWP
|
||||
#else
|
||||
namespace Xamarin.Forms.Platform.WinRT
|
||||
#endif
|
||||
{
|
||||
internal static class FlowDirectionExtensions
|
||||
{
|
||||
internal static void UpdateFlowDirection(this FrameworkElement control, IVisualElementController controller)
|
||||
{
|
||||
if (controller == null || control == null)
|
||||
return;
|
||||
|
||||
if (controller.EffectiveFlowDirection.IsRightToLeft())
|
||||
control.FlowDirection = WFlowDirection.RightToLeft;
|
||||
else if (controller.EffectiveFlowDirection.IsLeftToRight())
|
||||
control.FlowDirection = WFlowDirection.LeftToRight;
|
||||
}
|
||||
|
||||
internal static void UpdateTextAlignment(this TextBox control, IVisualElementController controller)
|
||||
{
|
||||
if (controller == null || control == null)
|
||||
return;
|
||||
|
||||
if (controller.EffectiveFlowDirection.IsRightToLeft())
|
||||
control.TextAlignment = WTextAlignment.Right;
|
||||
else if (controller.EffectiveFlowDirection.IsLeftToRight())
|
||||
control.TextAlignment = WTextAlignment.Left;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -147,6 +147,8 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
UpdateFont(Control);
|
||||
else if (e.PropertyName == Label.LineBreakModeProperty.PropertyName)
|
||||
UpdateLineBreakMode(Control);
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlign(Control);
|
||||
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
}
|
||||
|
@ -162,7 +164,7 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
if (label == null)
|
||||
return;
|
||||
|
||||
textBlock.TextAlignment = label.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
textBlock.TextAlignment = label.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
|
||||
textBlock.VerticalAlignment = label.VerticalTextAlignment.ToNativeVerticalAlignment();
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
}
|
||||
|
||||
Control.Value = e.NewElement.Progress;
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,11 +51,18 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
|
||||
if (e.PropertyName == ProgressBar.ProgressProperty.PropertyName)
|
||||
Control.Value = Element.Progress;
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
void ProgressBarOnValueChanged(object sender, RangeBaseValueChangedEventArgs rangeBaseValueChangedEventArgs)
|
||||
{
|
||||
((IVisualElementController)Element)?.InvalidateMeasure(InvalidationTrigger.MeasureChanged);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,6 +53,7 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
double stepping = Math.Min((e.NewElement.Maximum - e.NewElement.Minimum) / 10, 1);
|
||||
Control.StepFrequency = stepping;
|
||||
Control.SmallChange = stepping;
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,6 +70,8 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
if (Control.Value != Element.Value)
|
||||
Control.Value = Element.Value;
|
||||
}
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
protected override void UpdateBackgroundColor()
|
||||
|
@ -87,6 +90,11 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
}
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
protected override bool PreventGestureBubbling { get; set; } = true;
|
||||
|
||||
void OnNativeValueChanged(object sender, RangeBaseValueChangedEventArgs e)
|
||||
|
|
|
@ -26,7 +26,8 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
UpdateMaximum();
|
||||
UpdateMinimum();
|
||||
UpdateValue();
|
||||
UpdateIncrement();
|
||||
UpdateIncrement();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +45,8 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
UpdateIncrement();
|
||||
else if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
|
||||
UpdateBackgroundColor();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
protected override void UpdateBackgroundColor()
|
||||
|
@ -59,6 +62,11 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
Element.SetValueCore(Stepper.ValueProperty, Control.Value);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
void UpdateIncrement()
|
||||
{
|
||||
Control.Increment = Element.Increment;
|
||||
|
|
|
@ -29,6 +29,8 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
}
|
||||
|
||||
Control.IsOn = Element.IsToggled;
|
||||
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +42,10 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
{
|
||||
Control.IsOn = Element.IsToggled;
|
||||
}
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
{
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool PreventGestureBubbling { get; set; } = true;
|
||||
|
@ -48,5 +54,10 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
{
|
||||
((IElementController)Element).SetValueFromRenderer(Switch.IsToggledProperty, Control.IsOn);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,6 +43,7 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
}
|
||||
|
||||
UpdateTime();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +64,9 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
|
||||
if (e.PropertyName == TimePicker.TextColorProperty.PropertyName)
|
||||
UpdateTextColor();
|
||||
|
||||
if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
protected override bool PreventGestureBubbling { get; set; } = true;
|
||||
|
@ -73,6 +77,11 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
((IVisualElementController)Element)?.InvalidateMeasure(InvalidationTrigger.SizeRequestChanged);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
void UpdateTime()
|
||||
{
|
||||
Control.Time = Element.Time;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Automation;
|
||||
using Windows.UI.Xaml.Automation.Peers;
|
||||
|
||||
#if WINDOWS_UWP
|
||||
|
@ -24,6 +23,7 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
if (e.NewElement != null)
|
||||
{
|
||||
UpdateBackgroundColor();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,5 +131,10 @@ namespace Xamarin.Forms.Platform.WinRT
|
|||
else
|
||||
Control.SetValue(Windows.UI.Xaml.Automation.AutomationProperties.LabeledByProperty, _defaultAutomationPropertiesLabeledBy);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -66,10 +66,10 @@
|
|||
<Compile Include="..\Xamarin.Forms.Core\Properties\GlobalAssemblyInfo.cs">
|
||||
<Link>Properties\GlobalAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
|
||||
<Compile Include="FlowDirectionExtensions.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition=" '$(OS)' != 'Unix' ">
|
||||
<Compile Include="PageControl.cs" />
|
||||
<Compile Include="PageControl.cs" />
|
||||
<Compile Include="NavigationPageRendererWinRT.cs" />
|
||||
<Compile Include="PlatformWinRT.cs" />
|
||||
<Compile Include="BrushHelpers.cs" />
|
||||
|
|
|
@ -63,6 +63,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UpdateHorizontalTextAlignment(realCell, entryCell);
|
||||
else if (e.PropertyName == Cell.IsEnabledProperty.PropertyName)
|
||||
UpdateIsEnabled(realCell, entryCell);
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateHorizontalTextAlignment(realCell, entryCell);
|
||||
}
|
||||
|
||||
static void OnKeyBoardDoneButtonPressed(object sender, EventArgs e)
|
||||
|
@ -83,7 +85,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
static void UpdateHorizontalTextAlignment(EntryCellTableViewCell cell, EntryCell entryCell)
|
||||
{
|
||||
cell.TextField.TextAlignment = entryCell.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
IViewController viewController = entryCell.Parent as View;
|
||||
cell.TextField.TextAlignment = entryCell.HorizontalTextAlignment.ToNativeTextAlignment(viewController?.EffectiveFlowDirection ?? default(EffectiveFlowDirection));
|
||||
}
|
||||
|
||||
static void UpdateIsEnabled(EntryCellTableViewCell cell, EntryCell entryCell)
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
UpdateBackground(tvc, item);
|
||||
UpdateIsEnabled(tvc, boolCell);
|
||||
UpdateFlowDirection(tvc, boolCell);
|
||||
|
||||
return tvc;
|
||||
}
|
||||
|
@ -58,6 +59,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
realCell.TextLabel.Text = boolCell.Text;
|
||||
else if (e.PropertyName == Cell.IsEnabledProperty.PropertyName)
|
||||
UpdateIsEnabled(realCell, boolCell);
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection(realCell, boolCell);
|
||||
}
|
||||
|
||||
void OnSwitchValueChanged(object sender, EventArgs eventArgs)
|
||||
|
@ -76,6 +79,15 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
((SwitchCell)realCell.Cell).On = sw.On;
|
||||
}
|
||||
|
||||
void UpdateFlowDirection(CellTableViewCell cell, SwitchCell switchCell)
|
||||
{
|
||||
IVisualElementController controller = switchCell.Parent as View;
|
||||
|
||||
var uiSwitch = cell.AccessoryView as UISwitch;
|
||||
|
||||
uiSwitch.UpdateFlowDirection(controller);
|
||||
}
|
||||
|
||||
void UpdateIsEnabled(CellTableViewCell cell, SwitchCell switchCell)
|
||||
{
|
||||
cell.UserInteractionEnabled = switchCell.IsEnabled;
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
using UIKit;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
internal static class FlowDirectionExtensions
|
||||
{
|
||||
internal static FlowDirection ToFlowDirection(this UIUserInterfaceLayoutDirection direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case UIUserInterfaceLayoutDirection.LeftToRight:
|
||||
return FlowDirection.LeftToRight;
|
||||
case UIUserInterfaceLayoutDirection.RightToLeft:
|
||||
return FlowDirection.RightToLeft;
|
||||
default:
|
||||
return FlowDirection.MatchParent;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UpdateFlowDirection(this UIView view, IVisualElementController controller)
|
||||
{
|
||||
if (controller == null || view == null)
|
||||
return;
|
||||
|
||||
|
||||
if (controller.EffectiveFlowDirection.IsRightToLeft())
|
||||
view.SemanticContentAttribute = UISemanticContentAttribute.ForceRightToLeft;
|
||||
else if (controller.EffectiveFlowDirection.IsLeftToRight())
|
||||
view.SemanticContentAttribute = UISemanticContentAttribute.ForceLeftToRight;
|
||||
}
|
||||
|
||||
internal static void UpdateTextAlignment(this UITextField control, IVisualElementController controller)
|
||||
{
|
||||
if (controller == null || control == null)
|
||||
return;
|
||||
|
||||
if (controller.EffectiveFlowDirection.IsRightToLeft())
|
||||
{
|
||||
control.HorizontalAlignment = UIControlContentHorizontalAlignment.Right;
|
||||
control.TextAlignment = UITextAlignment.Right;
|
||||
}
|
||||
else if (controller.EffectiveFlowDirection.IsLeftToRight())
|
||||
{
|
||||
control.HorizontalAlignment = UIControlContentHorizontalAlignment.Left;
|
||||
control.TextAlignment = UITextAlignment.Left;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UpdateTextAlignment(this UITextView control, IVisualElementController controller)
|
||||
{
|
||||
if (controller == null || control == null)
|
||||
return;
|
||||
|
||||
if (controller.EffectiveFlowDirection.IsRightToLeft())
|
||||
control.TextAlignment = UITextAlignment.Right;
|
||||
else if (controller.EffectiveFlowDirection.IsLeftToRight())
|
||||
control.TextAlignment = UITextAlignment.Left;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -101,8 +101,10 @@ namespace Xamarin.Forms
|
|||
|
||||
#if __MOBILE__
|
||||
Device.SetIdiom(UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad ? TargetIdiom.Tablet : TargetIdiom.Phone);
|
||||
Device.SetFlowDirection(UIApplication.SharedApplication.UserInterfaceLayoutDirection.ToFlowDirection());
|
||||
#else
|
||||
Device.SetIdiom(TargetIdiom.Desktop);
|
||||
Device.SetFlowDirection(NSApplication.SharedApplication.UserInterfaceLayoutDirection.ToFlowDirection());
|
||||
#endif
|
||||
Device.SetFlags(s_flags);
|
||||
Device.PlatformServices = new IOSPlatformServices();
|
||||
|
|
|
@ -1,19 +1,27 @@
|
|||
using UIKit;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
internal static class AlignmentExtensions
|
||||
{
|
||||
internal static UITextAlignment ToNativeTextAlignment(this TextAlignment alignment)
|
||||
internal static UITextAlignment ToNativeTextAlignment(this TextAlignment alignment, EffectiveFlowDirection flowDirection)
|
||||
{
|
||||
var isLtr = flowDirection.IsLeftToRight();
|
||||
switch (alignment)
|
||||
{
|
||||
case TextAlignment.Center:
|
||||
return UITextAlignment.Center;
|
||||
case TextAlignment.End:
|
||||
return UITextAlignment.Right;
|
||||
if (isLtr)
|
||||
return UITextAlignment.Right;
|
||||
else
|
||||
return UITextAlignment.Left;
|
||||
default:
|
||||
return UITextAlignment.Left;
|
||||
if (isLtr)
|
||||
return UITextAlignment.Left;
|
||||
else
|
||||
return UITextAlignment.Natural;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UpdateMaximumDate();
|
||||
UpdateMinimumDate();
|
||||
UpdateTextColor();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
|
@ -77,6 +78,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UpdateMaximumDate();
|
||||
else if (e.PropertyName == DatePicker.TextColorProperty.PropertyName || e.PropertyName == VisualElement.IsEnabledProperty.PropertyName)
|
||||
UpdateTextColor();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
void HandleValueChanged(object sender, EventArgs e)
|
||||
|
@ -102,6 +105,11 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
Control.Text = Element.Date.ToString(Element.Format);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
(Control as UITextField).UpdateTextAlignment(Element);
|
||||
}
|
||||
|
||||
void UpdateMaximumDate()
|
||||
{
|
||||
_picker.MaximumDate = Element.MaximumDate.ToNSDate();
|
||||
|
|
|
@ -8,9 +8,9 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
public class EditorRenderer : ViewRenderer<Editor, UITextView>
|
||||
{
|
||||
bool _disposed;
|
||||
IEditorController ElementController => Element;
|
||||
IEditorController ElementController => Element;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
@ -51,7 +51,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
var doneButton = new UIBarButtonItem(UIBarButtonSystemItem.Done, (o, a) =>
|
||||
{
|
||||
Control.ResignFirstResponder();
|
||||
ElementController.SendCompleted();
|
||||
ElementController.SendCompleted();
|
||||
});
|
||||
accessoryView.SetItems(new[] { spacer, doneButton }, false);
|
||||
Control.InputAccessoryView = accessoryView;
|
||||
|
@ -67,6 +67,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UpdateTextColor();
|
||||
UpdateKeyboard();
|
||||
UpdateEditable();
|
||||
UpdateTextAlignment();
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
|
@ -87,6 +88,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UpdateFont();
|
||||
else if (e.PropertyName == Editor.FontSizeProperty.PropertyName)
|
||||
UpdateFont();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateTextAlignment();
|
||||
}
|
||||
|
||||
void HandleChanged(object sender, EventArgs e)
|
||||
|
@ -135,6 +138,11 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
Control.Text = Element.Text;
|
||||
}
|
||||
|
||||
void UpdateTextAlignment()
|
||||
{
|
||||
Control.UpdateTextAlignment(Element);
|
||||
}
|
||||
|
||||
void UpdateTextColor()
|
||||
{
|
||||
var textColor = Element.TextColor;
|
||||
|
|
|
@ -114,6 +114,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
}
|
||||
else if (e.PropertyName == PlatformConfiguration.iOSSpecific.Entry.AdjustsFontSizeToFitWidthProperty.PropertyName)
|
||||
UpdateAdjustsFontSizeToFitWidth();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
}
|
||||
|
@ -148,7 +150,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
void UpdateAlignment()
|
||||
{
|
||||
Control.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
Control.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
|
||||
}
|
||||
|
||||
void UpdateColor()
|
||||
|
|
|
@ -152,6 +152,8 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateText();
|
||||
else if (e.PropertyName == Label.LineBreakModeProperty.PropertyName)
|
||||
UpdateLineBreakMode();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
}
|
||||
|
||||
#if __MOBILE__
|
||||
|
@ -190,9 +192,9 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
void UpdateAlignment()
|
||||
{
|
||||
#if __MOBILE__
|
||||
Control.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
Control.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
|
||||
#else
|
||||
Control.Alignment = Element.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
Control.Alignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using UIKit;
|
||||
using Xamarin.Forms.Internals;
|
||||
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
|
||||
using PointF = CoreGraphics.CGPoint;
|
||||
|
||||
|
@ -25,6 +26,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
VisualElementTracker _tracker;
|
||||
|
||||
Page Page => Element as Page;
|
||||
|
||||
|
||||
public PhoneMasterDetailRenderer()
|
||||
{
|
||||
|
@ -241,12 +243,23 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
var masterFrame = frame;
|
||||
masterFrame.Width = (int)(Math.Min(masterFrame.Width, masterFrame.Height) * 0.8);
|
||||
|
||||
var isRTL = (Element as IVisualElementController)?.EffectiveFlowDirection.IsRightToLeft() == true;
|
||||
if (isRTL)
|
||||
{
|
||||
masterFrame.X = (int)(masterFrame.Width * .25);
|
||||
}
|
||||
|
||||
_masterController.View.Frame = masterFrame;
|
||||
|
||||
var target = frame;
|
||||
if (Presented)
|
||||
target.X += masterFrame.Width;
|
||||
|
||||
if (isRTL)
|
||||
{
|
||||
target.X = target.X * -1;
|
||||
}
|
||||
|
||||
if (animated)
|
||||
{
|
||||
UIView.BeginAnimations("Flyout");
|
||||
|
@ -259,7 +272,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
else
|
||||
_detailController.View.Frame = target;
|
||||
|
||||
MasterDetailPage.MasterBounds = new Rectangle(0, 0, masterFrame.Width, masterFrame.Height);
|
||||
MasterDetailPage.MasterBounds = new Rectangle(masterFrame.X, 0, masterFrame.Width, masterFrame.Height);
|
||||
MasterDetailPage.DetailBounds = new Rectangle(0, 0, frame.Width, frame.Height);
|
||||
|
||||
if (Presented)
|
||||
|
@ -341,7 +354,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
else
|
||||
return base.ChildViewControllerForStatusBarHidden();
|
||||
}
|
||||
|
||||
|
||||
void UpdatePanGesture()
|
||||
{
|
||||
var model = (MasterDetailPage)Element;
|
||||
|
@ -358,10 +371,14 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
return;
|
||||
}
|
||||
|
||||
UITouchEventArgs shouldRecieve = (g, t) => !(t.View is UISlider);
|
||||
UITouchEventArgs shouldReceive = (g, t) => !(t.View is UISlider);
|
||||
var center = new PointF();
|
||||
_panGesture = new UIPanGestureRecognizer(g =>
|
||||
{
|
||||
var isRTL = (Element as IVisualElementController)?.EffectiveFlowDirection.IsRightToLeft() == true;
|
||||
|
||||
int directionModifier = isRTL ? -1 : 1;
|
||||
|
||||
switch (g.State)
|
||||
{
|
||||
case UIGestureRecognizerState.Began:
|
||||
|
@ -370,12 +387,18 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
case UIGestureRecognizerState.Changed:
|
||||
var currentPosition = g.LocationInView(g.View);
|
||||
var motion = currentPosition.X - center.X;
|
||||
|
||||
motion = motion * directionModifier;
|
||||
|
||||
var detailView = _detailController.View;
|
||||
var targetFrame = detailView.Frame;
|
||||
if (Presented)
|
||||
targetFrame.X = (nfloat)Math.Max(0, _masterController.View.Frame.Width + Math.Min(0, motion));
|
||||
else
|
||||
targetFrame.X = (nfloat)Math.Min(_masterController.View.Frame.Width, Math.Max(0, motion));
|
||||
|
||||
targetFrame.X = targetFrame.X * directionModifier;
|
||||
|
||||
detailView.Frame = targetFrame;
|
||||
break;
|
||||
case UIGestureRecognizerState.Ended:
|
||||
|
@ -383,14 +406,14 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
var masterFrame = _masterController.View.Frame;
|
||||
if (Presented)
|
||||
{
|
||||
if (detailFrame.X < masterFrame.Width * .75)
|
||||
if (detailFrame.X * directionModifier < masterFrame.Width * .75)
|
||||
Presented = false;
|
||||
else
|
||||
LayoutChildren(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (detailFrame.X > masterFrame.Width * .25)
|
||||
if (detailFrame.X * directionModifier > masterFrame.Width * .25)
|
||||
Presented = true;
|
||||
else
|
||||
LayoutChildren(true);
|
||||
|
@ -398,7 +421,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
break;
|
||||
}
|
||||
});
|
||||
_panGesture.ShouldReceiveTouch = shouldRecieve;
|
||||
_panGesture.ShouldReceiveTouch = shouldReceive;
|
||||
_panGesture.MaximumNumberOfTouches = 2;
|
||||
View.AddGestureRecognizer(_panGesture);
|
||||
}
|
||||
|
|
|
@ -96,6 +96,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
UpdateFont();
|
||||
else if (e.PropertyName == SearchBar.HorizontalTextAlignmentProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateAlignment();
|
||||
}
|
||||
|
||||
protected override void SetBackgroundColor(Color color)
|
||||
|
@ -161,7 +163,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
if (_textField == null)
|
||||
return;
|
||||
|
||||
_textField.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment();
|
||||
_textField.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
|
||||
}
|
||||
|
||||
void UpdateCancelButton()
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using UIKit;
|
||||
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
|
||||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
{
|
||||
|
@ -46,7 +45,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
bool _disposed;
|
||||
EventTracker _events;
|
||||
InnerDelegate _innerDelegate;
|
||||
|
||||
nfloat _masterWidth = 0;
|
||||
EventedViewController _masterController;
|
||||
|
||||
MasterDetailPage _masterDetailPage;
|
||||
|
@ -184,8 +183,10 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
var detailsBounds = _detailController.View.Frame;
|
||||
var masterBounds = _masterController.View.Frame;
|
||||
|
||||
_masterWidth = (nfloat)Math.Max(_masterWidth, masterBounds.Width);
|
||||
|
||||
if (!masterBounds.IsEmpty)
|
||||
MasterDetailPage.MasterBounds = new Rectangle(0, 0, masterBounds.Width, masterBounds.Height);
|
||||
MasterDetailPage.MasterBounds = new Rectangle(_masterWidth, 0, _masterWidth, masterBounds.Height);
|
||||
|
||||
if (!detailsBounds.IsEmpty)
|
||||
MasterDetailPage.DetailBounds = new Rectangle(0, 0, detailsBounds.Width, detailsBounds.Height);
|
||||
|
@ -195,6 +196,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
{
|
||||
base.ViewDidLoad();
|
||||
UpdateBackground();
|
||||
UpdateFlowDirection();
|
||||
_tracker = new VisualElementTracker(this);
|
||||
_events = new EventTracker(this);
|
||||
_events.LoadEvents(NativeView);
|
||||
|
@ -249,6 +251,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
var changed = ElementChanged;
|
||||
if (changed != null)
|
||||
changed(this, e);
|
||||
|
||||
_masterWidth = 0;
|
||||
}
|
||||
|
||||
void ClearControllers()
|
||||
|
@ -283,6 +287,8 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
ToggleMaster();
|
||||
else if (e.PropertyName == Xamarin.Forms.MasterDetailPage.IsGestureEnabledProperty.PropertyName)
|
||||
base.PresentsWithGesture = this.MasterDetailPage.IsGestureEnabled;
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
MessagingCenter.Send<IVisualElementRenderer>(this, NavigationRenderer.UpdateToolbarButtons);
|
||||
}
|
||||
|
||||
|
@ -346,6 +352,11 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
_detailController.AddChildViewController(detail);
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
NativeView.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
class InnerDelegate : UISplitViewControllerDelegate
|
||||
{
|
||||
readonly MasterBehavior _masterPresentedDefaultState;
|
||||
|
|
|
@ -75,6 +75,7 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
UpdateTime();
|
||||
UpdateTextColor();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
base.OnElementChanged(e);
|
||||
|
@ -89,6 +90,9 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
|
||||
if (e.PropertyName == TimePicker.TextColorProperty.PropertyName || e.PropertyName == VisualElement.IsEnabledProperty.PropertyName)
|
||||
UpdateTextColor();
|
||||
|
||||
if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
void OnEnded(object sender, EventArgs eventArgs)
|
||||
|
@ -106,6 +110,11 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
ElementController.SetValueFromRenderer(TimePicker.TimeProperty, _picker.Date.ToDateTime() - new DateTime(1, 1, 1));
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
(Control as UITextField).UpdateTextAlignment(Element);
|
||||
}
|
||||
|
||||
void UpdateTextColor()
|
||||
{
|
||||
var textColor = Element.TextColor;
|
||||
|
|
|
@ -5,10 +5,9 @@ using RectangleF = CoreGraphics.CGRect;
|
|||
using SizeF = CoreGraphics.CGSize;
|
||||
|
||||
#if __MOBILE__
|
||||
using UIKit;
|
||||
using NativeView = UIKit.UIView;
|
||||
using NativeColor = UIKit.UIColor;
|
||||
using NativeControl = UIKit.UIControl;
|
||||
using NativeView = UIKit.UIView;
|
||||
|
||||
namespace Xamarin.Forms.Platform.iOS
|
||||
#else
|
||||
|
@ -96,6 +95,7 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
}
|
||||
|
||||
UpdateIsEnabled();
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
|
@ -106,6 +106,8 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
UpdateIsEnabled();
|
||||
else if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
|
||||
SetBackgroundColor(Element.BackgroundColor);
|
||||
else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName)
|
||||
UpdateFlowDirection();
|
||||
}
|
||||
|
||||
base.OnElementPropertyChanged(sender, e);
|
||||
|
@ -209,6 +211,8 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
|
||||
UpdateIsEnabled();
|
||||
|
||||
UpdateFlowDirection();
|
||||
|
||||
AddSubview(uiview);
|
||||
}
|
||||
|
||||
|
@ -230,6 +234,11 @@ namespace Xamarin.Forms.Platform.MacOS
|
|||
uiControl.Enabled = Element.IsEnabled;
|
||||
}
|
||||
|
||||
void UpdateFlowDirection()
|
||||
{
|
||||
Control.UpdateFlowDirection(Element);
|
||||
}
|
||||
|
||||
void ViewOnFocusChangeRequested(object sender, VisualElement.FocusRequestArgs focusRequestArgs)
|
||||
{
|
||||
if (Control == null)
|
||||
|
|
|
@ -120,6 +120,7 @@
|
|||
<Compile Include="ExportImageSourceHandlerAttribute.cs" />
|
||||
<Compile Include="ExportRendererAttribute.cs" />
|
||||
<Compile Include="Extensions\ArrayExtensions.cs" />
|
||||
<Compile Include="Extensions\FlowDirectionExtensions.cs" />
|
||||
<Compile Include="Extensions\PlatformConfigurationExtensions.cs" />
|
||||
<Compile Include="Flags.cs" />
|
||||
<Compile Include="NativeViewWrapper.cs" />
|
||||
|
@ -195,4 +196,4 @@
|
|||
<Link>Properties\GlobalAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -92,6 +92,22 @@ Device.BeginInvokeOnMainThread (() => {
|
|||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="FlowDirection">
|
||||
<MemberSignature Language="C#" Value="public static Xamarin.Forms.FlowDirection FlowDirection { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property valuetype Xamarin.Forms.FlowDirection FlowDirection" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.FlowDirection</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="GetAssemblies">
|
||||
<MemberSignature Language="C#" Value="public static System.Reflection.Assembly[] GetAssemblies ();" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig class System.Reflection.Assembly[] GetAssemblies() cil managed" />
|
||||
|
@ -513,6 +529,30 @@ button.HeightRequest = Device.OnPlatform (20,30,30);
|
|||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="SetFlowDirection">
|
||||
<MemberSignature Language="C#" Value="public static void SetFlowDirection (Xamarin.Forms.FlowDirection value);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig void SetFlowDirection(valuetype Xamarin.Forms.FlowDirection value) cil managed" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<AttributeName>System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)</AttributeName>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Void</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="value" Type="Xamarin.Forms.FlowDirection" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="value">To be added.</param>
|
||||
<summary>To be added.</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="SetIdiom">
|
||||
<MemberSignature Language="C#" Value="public static void SetIdiom (Xamarin.Forms.TargetIdiom value);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig void SetIdiom(valuetype Xamarin.Forms.TargetIdiom value) cil managed" />
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<Type Name="EffectiveFlowDirection" FullName="Xamarin.Forms.EffectiveFlowDirection">
|
||||
<TypeSignature Language="C#" Value="public enum EffectiveFlowDirection" />
|
||||
<TypeSignature Language="ILAsm" Value=".class public auto ansi sealed EffectiveFlowDirection extends System.Enum" />
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Forms.Core</AssemblyName>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Base>
|
||||
<BaseTypeName>System.Enum</BaseTypeName>
|
||||
</Base>
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<AttributeName>System.Flags</AttributeName>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
<Members>
|
||||
<Member MemberName="Explicit">
|
||||
<MemberSignature Language="C#" Value="Explicit" />
|
||||
<MemberSignature Language="ILAsm" Value=".field public static literal valuetype Xamarin.Forms.EffectiveFlowDirection Explicit = int32(2)" />
|
||||
<MemberType>Field</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.EffectiveFlowDirection</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="RightToLeft">
|
||||
<MemberSignature Language="C#" Value="RightToLeft" />
|
||||
<MemberSignature Language="ILAsm" Value=".field public static literal valuetype Xamarin.Forms.EffectiveFlowDirection RightToLeft = int32(1)" />
|
||||
<MemberType>Field</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.EffectiveFlowDirection</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
</Docs>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
|
@ -0,0 +1,103 @@
|
|||
<Type Name="EffectiveFlowDirectionExtensions" FullName="Xamarin.Forms.EffectiveFlowDirectionExtensions">
|
||||
<TypeSignature Language="C#" Value="public static class EffectiveFlowDirectionExtensions" />
|
||||
<TypeSignature Language="ILAsm" Value=".class public auto ansi abstract sealed beforefieldinit EffectiveFlowDirectionExtensions extends System.Object" />
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Forms.Core</AssemblyName>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Base>
|
||||
<BaseTypeName>System.Object</BaseTypeName>
|
||||
</Base>
|
||||
<Interfaces />
|
||||
<Attributes>
|
||||
<Attribute>
|
||||
<AttributeName>System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)</AttributeName>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
<Members>
|
||||
<Member MemberName="IsExplicit">
|
||||
<MemberSignature Language="C#" Value="public static bool IsExplicit (this Xamarin.Forms.EffectiveFlowDirection self);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsExplicit(valuetype Xamarin.Forms.EffectiveFlowDirection self) cil managed" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="self" Type="Xamarin.Forms.EffectiveFlowDirection" RefType="this" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="self">To be added.</param>
|
||||
<summary>To be added.</summary>
|
||||
<returns>To be added.</returns>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IsImplicit">
|
||||
<MemberSignature Language="C#" Value="public static bool IsImplicit (this Xamarin.Forms.EffectiveFlowDirection self);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsImplicit(valuetype Xamarin.Forms.EffectiveFlowDirection self) cil managed" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="self" Type="Xamarin.Forms.EffectiveFlowDirection" RefType="this" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="self">To be added.</param>
|
||||
<summary>To be added.</summary>
|
||||
<returns>To be added.</returns>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IsLeftToRight">
|
||||
<MemberSignature Language="C#" Value="public static bool IsLeftToRight (this Xamarin.Forms.EffectiveFlowDirection self);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsLeftToRight(valuetype Xamarin.Forms.EffectiveFlowDirection self) cil managed" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="self" Type="Xamarin.Forms.EffectiveFlowDirection" RefType="this" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="self">To be added.</param>
|
||||
<summary>To be added.</summary>
|
||||
<returns>To be added.</returns>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IsRightToLeft">
|
||||
<MemberSignature Language="C#" Value="public static bool IsRightToLeft (this Xamarin.Forms.EffectiveFlowDirection self);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsRightToLeft(valuetype Xamarin.Forms.EffectiveFlowDirection self) cil managed" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="self" Type="Xamarin.Forms.EffectiveFlowDirection" RefType="this" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="self">To be added.</param>
|
||||
<summary>To be added.</summary>
|
||||
<returns>To be added.</returns>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
|
@ -0,0 +1,59 @@
|
|||
<Type Name="FlowDirection" FullName="Xamarin.Forms.FlowDirection">
|
||||
<TypeSignature Language="C#" Value="public enum FlowDirection" />
|
||||
<TypeSignature Language="ILAsm" Value=".class public auto ansi sealed FlowDirection extends System.Enum" />
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Forms.Core</AssemblyName>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Base>
|
||||
<BaseTypeName>System.Enum</BaseTypeName>
|
||||
</Base>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
<Members>
|
||||
<Member MemberName="LeftToRight">
|
||||
<MemberSignature Language="C#" Value="LeftToRight" />
|
||||
<MemberSignature Language="ILAsm" Value=".field public static literal valuetype Xamarin.Forms.FlowDirection LeftToRight = int32(1)" />
|
||||
<MemberType>Field</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.FlowDirection</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="MatchParent">
|
||||
<MemberSignature Language="C#" Value="MatchParent" />
|
||||
<MemberSignature Language="ILAsm" Value=".field public static literal valuetype Xamarin.Forms.FlowDirection MatchParent = int32(0)" />
|
||||
<MemberType>Field</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.FlowDirection</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="RightToLeft">
|
||||
<MemberSignature Language="C#" Value="RightToLeft" />
|
||||
<MemberSignature Language="ILAsm" Value=".field public static literal valuetype Xamarin.Forms.FlowDirection RightToLeft = int32(2)" />
|
||||
<MemberType>Field</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.FlowDirection</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
</Docs>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
|
@ -65,6 +65,22 @@
|
|||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="EffectiveFlowDirection">
|
||||
<MemberSignature Language="C#" Value="public Xamarin.Forms.EffectiveFlowDirection EffectiveFlowDirection { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance valuetype Xamarin.Forms.EffectiveFlowDirection EffectiveFlowDirection" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.EffectiveFlowDirection</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="FocusChangeRequested">
|
||||
<MemberSignature Language="C#" Value="public event EventHandler<Xamarin.Forms.VisualElement.FocusRequestArgs> FocusChangeRequested;" />
|
||||
<MemberSignature Language="ILAsm" Value=".event class System.EventHandler`1<class Xamarin.Forms.VisualElement/FocusRequestArgs> FocusChangeRequested" />
|
||||
|
|
|
@ -352,6 +352,37 @@
|
|||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="FlowDirection">
|
||||
<MemberSignature Language="C#" Value="public Xamarin.Forms.FlowDirection FlowDirection { get; set; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance valuetype Xamarin.Forms.FlowDirection FlowDirection" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.FlowDirection</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="FlowDirectionProperty">
|
||||
<MemberSignature Language="C#" Value="public static readonly Xamarin.Forms.BindableProperty FlowDirectionProperty;" />
|
||||
<MemberSignature Language="ILAsm" Value=".field public static initonly class Xamarin.Forms.BindableProperty FlowDirectionProperty" />
|
||||
<MemberType>Field</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.BindableProperty</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="Focus">
|
||||
<MemberSignature Language="C#" Value="public bool Focus ();" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance bool Focus() cil managed" />
|
||||
|
@ -2062,6 +2093,22 @@
|
|||
<remarks>The x value of an element is set during the Layout phase.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="Xamarin.Forms.IVisualElementController.EffectiveFlowDirection">
|
||||
<MemberSignature Language="C#" Value="Xamarin.Forms.EffectiveFlowDirection Xamarin.Forms.IVisualElementController.EffectiveFlowDirection { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance valuetype Xamarin.Forms.EffectiveFlowDirection Xamarin.Forms.IVisualElementController.EffectiveFlowDirection" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>Xamarin.Forms.EffectiveFlowDirection</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>To be added.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="Xamarin.Forms.IVisualElementController.InvalidateMeasure">
|
||||
<MemberSignature Language="C#" Value="void IVisualElementController.InvalidateMeasure (Xamarin.Forms.Internals.InvalidationTrigger trigger);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method hidebysig newslot virtual instance void Xamarin.Forms.IVisualElementController.InvalidateMeasure(valuetype Xamarin.Forms.Internals.InvalidationTrigger trigger) cil managed" />
|
||||
|
|
|
@ -213,6 +213,8 @@
|
|||
<Type Name="Easing" Kind="Class" />
|
||||
<Type Name="Editor" Kind="Class" />
|
||||
<Type Name="Effect" Kind="Class" />
|
||||
<Type Name="EffectiveFlowDirection" Kind="Enumeration" />
|
||||
<Type Name="EffectiveFlowDirectionExtensions" Kind="Class" />
|
||||
<Type Name="Element" Kind="Class" />
|
||||
<Type Name="ElementEventArgs" Kind="Class" />
|
||||
<Type Name="ElementTemplate" Kind="Class" />
|
||||
|
@ -222,6 +224,7 @@
|
|||
<Type Name="ExportEffectAttribute" Kind="Class" />
|
||||
<Type Name="FileImageSource" Kind="Class" />
|
||||
<Type Name="FileImageSourceConverter" Kind="Class" />
|
||||
<Type Name="FlowDirection" Kind="Enumeration" />
|
||||
<Type Name="FocusEventArgs" Kind="Class" />
|
||||
<Type Name="Font" Kind="Structure" />
|
||||
<Type Name="FontAttributes" Kind="Enumeration" />
|
||||
|
@ -857,6 +860,90 @@
|
|||
<Link Type="Xamarin.Forms.BindableObjectExtensions" Member="M:Xamarin.Forms.BindableObjectExtensions.SetBinding``1(Xamarin.Forms.BindableObject,Xamarin.Forms.BindableProperty,System.Linq.Expressions.Expression{System.Func{``0,System.Object}},Xamarin.Forms.BindingMode,Xamarin.Forms.IValueConverter,System.String)" />
|
||||
</Member>
|
||||
</ExtensionMethod>
|
||||
<ExtensionMethod>
|
||||
<Targets>
|
||||
<Target Type="T:Xamarin.Forms.EffectiveFlowDirection" />
|
||||
</Targets>
|
||||
<Member MemberName="IsExplicit">
|
||||
<MemberSignature Language="C#" Value="public static bool IsExplicit (this Xamarin.Forms.EffectiveFlowDirection self);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsExplicit(valuetype Xamarin.Forms.EffectiveFlowDirection self) cil managed" />
|
||||
<MemberType>ExtensionMethod</MemberType>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="self" Type="Xamarin.Forms.EffectiveFlowDirection" RefType="this" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="self">To be added.</param>
|
||||
<summary>To be added.</summary>
|
||||
</Docs>
|
||||
<Link Type="Xamarin.Forms.EffectiveFlowDirectionExtensions" Member="M:Xamarin.Forms.EffectiveFlowDirectionExtensions.IsExplicit(Xamarin.Forms.EffectiveFlowDirection)" />
|
||||
</Member>
|
||||
</ExtensionMethod>
|
||||
<ExtensionMethod>
|
||||
<Targets>
|
||||
<Target Type="T:Xamarin.Forms.EffectiveFlowDirection" />
|
||||
</Targets>
|
||||
<Member MemberName="IsImplicit">
|
||||
<MemberSignature Language="C#" Value="public static bool IsImplicit (this Xamarin.Forms.EffectiveFlowDirection self);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsImplicit(valuetype Xamarin.Forms.EffectiveFlowDirection self) cil managed" />
|
||||
<MemberType>ExtensionMethod</MemberType>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="self" Type="Xamarin.Forms.EffectiveFlowDirection" RefType="this" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="self">To be added.</param>
|
||||
<summary>To be added.</summary>
|
||||
</Docs>
|
||||
<Link Type="Xamarin.Forms.EffectiveFlowDirectionExtensions" Member="M:Xamarin.Forms.EffectiveFlowDirectionExtensions.IsImplicit(Xamarin.Forms.EffectiveFlowDirection)" />
|
||||
</Member>
|
||||
</ExtensionMethod>
|
||||
<ExtensionMethod>
|
||||
<Targets>
|
||||
<Target Type="T:Xamarin.Forms.EffectiveFlowDirection" />
|
||||
</Targets>
|
||||
<Member MemberName="IsLeftToRight">
|
||||
<MemberSignature Language="C#" Value="public static bool IsLeftToRight (this Xamarin.Forms.EffectiveFlowDirection self);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsLeftToRight(valuetype Xamarin.Forms.EffectiveFlowDirection self) cil managed" />
|
||||
<MemberType>ExtensionMethod</MemberType>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="self" Type="Xamarin.Forms.EffectiveFlowDirection" RefType="this" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="self">To be added.</param>
|
||||
<summary>To be added.</summary>
|
||||
</Docs>
|
||||
<Link Type="Xamarin.Forms.EffectiveFlowDirectionExtensions" Member="M:Xamarin.Forms.EffectiveFlowDirectionExtensions.IsLeftToRight(Xamarin.Forms.EffectiveFlowDirection)" />
|
||||
</Member>
|
||||
</ExtensionMethod>
|
||||
<ExtensionMethod>
|
||||
<Targets>
|
||||
<Target Type="T:Xamarin.Forms.EffectiveFlowDirection" />
|
||||
</Targets>
|
||||
<Member MemberName="IsRightToLeft">
|
||||
<MemberSignature Language="C#" Value="public static bool IsRightToLeft (this Xamarin.Forms.EffectiveFlowDirection self);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsRightToLeft(valuetype Xamarin.Forms.EffectiveFlowDirection self) cil managed" />
|
||||
<MemberType>ExtensionMethod</MemberType>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="self" Type="Xamarin.Forms.EffectiveFlowDirection" RefType="this" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="self">To be added.</param>
|
||||
<summary>To be added.</summary>
|
||||
</Docs>
|
||||
<Link Type="Xamarin.Forms.EffectiveFlowDirectionExtensions" Member="M:Xamarin.Forms.EffectiveFlowDirectionExtensions.IsRightToLeft(Xamarin.Forms.EffectiveFlowDirection)" />
|
||||
</Member>
|
||||
</ExtensionMethod>
|
||||
<ExtensionMethod>
|
||||
<Targets>
|
||||
<Target Type="T:Xamarin.Forms.BindableObject" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче