* do not throw exeption when target of WeakReference was collected (#9542) fixes #6698
- in TypedBinding.Apply return instead of throwing an InvalidOperationException
- add a null-check in BindingExpression
- add a ControlGallery page to reproduce the issue
- fix #6698
Co-authored-by: Stephane Delcroix <stephane@delcroix.org>
* Fix ObjectDisposedException issues for renderers OnElementPropertyChanged (#9764)
* Update GitInfo.txt
* Fix ObjectDisposedException issues for renderers when they are saved
from garbage collection by a weak referenced property changed handler
Fixes #9431; Fixes #5560; Fixes #8607; Fixes #6587; Fixes #9412;
* Add disposed check for legacy renderers
* Add visual indication that the app is running with legacy renderers
* Revert gitinfo
* Add disposed check to VisualElementTracker
* Asyncify double dispose test
Co-authored-by: Samantha Houts <samhouts@users.noreply.github.com>
* [X] consume trailing spaces in markup (#9850)
- fixes #9212
* [iOS|Android] Fix screen reader order (#9702)
* add nifty test page
* TabIndexes will not skip layouts; will skip disabled/unfocusable views
* [iOS|Android] Standardize logic, don't duplicate TabIndex logic
* fix test case
* [iOS] Make Frame a tab stop
* Update ShellFlyoutRenderer.cs
* [iOS] Hide Master page from Accessibilty when not presented
fixes #4220
* final test case should work without so much explict tabindexing!
* [iOS] Single or no TabIndex = default page order
* No tabindex? No problem!
* [Android] Single or no TabIndex = default page order
* [iOS] Return elements depth first
* copypastestackoverflowofshame
* review comments
* [Android] Let OS handle FocusSearch if we haven't specified more than one TabIndex group
* [Android] Let OS handle FocusSearch if we haven't specified more than one TabIndex group
fixes #9653
fixes #4220
fixes #9191
fixes #8613
fixes #9137
fixes #8691
fixes #7606
fixes #4270
fixes #5879
* [XamlC] use XmlReader for detecting XAML and x:Class (#9922)
Context: https://www.jetbrains.com/profiler/
I was profiling Xamarin.Android project builds with `dotTrace`, and
noticed an `IsXaml` method from XamlC taking time:
0.07% IsXaml • 40/0 ms • Xamarin.Forms.Build.Tasks.CecilExtensions.IsXaml(EmbeddedResource, ModuleDefinition, out String)
0.07% Execute • Xamarin.Forms.Build.Tasks.XamlCTask.Execute(out IList)
0.07% Execute • Xamarin.Forms.Build.Tasks.XamlTask.Execute
In this build, I had changed only XAML and the netstandard project was
using `<ProduceReferenceAssembly>True</ProduceReferenceAssembly>`.
The project is here:
https://github.com/xamarin/xamarin-android/tree/master/tests/Xamarin.Forms-Performance-Integration
Reviewing `IsXaml`, it uses `XmlDocument` to parse every
`EmbeddedResource` with a `.xaml` extension. The problem with this, is
that `XmlDocument` loads the entire XML file into memory and parses
it. This is a step before the actual work of XamlC, so it is currently
parsing every file twice.
If we switch this code to use `XmlReader` instead, we can read to the
first XML element and stop there to get the information needed. We
don't need to parse the entire file at this step.
The results of building the Xamarin.Forms.Controls project on
Windows:
Before:
1973 ms XamlCTask 1 calls
After:
1917 ms XamlCTask 1 calls
The same project running on Mono / macOS:
Before:
6785 ms XamlCTask 1 calls
After:
6224 ms XamlCTask 1 calls
My Mac is a slightly slower machine than my PC, but the big difference
is Mono vs .NET Framework.
* Apply fix from #9195 to Style.cs (#9921) Fixes #9656
Fixes #9656
* Fix SwipeItem cast issue on SwipeView (#9907)
* Fixed SwipeItem parent casting issue
* Recover unnecessary removed line in ControlGallery project
* Added missing onproperty changed
* Add a way to open SwipeView programmatically (#9635)
- fixes #9413
* Implemented programmatically Open method in SwipeView
* Fixed direction validation programmatically opening the SwipeView
* Hide internal SwipeView OpenRequested event
* * #8183 Fix Base Class Selector with Descendent Selection
* #8183 Unit Tests
* #8183 Additional Base Class Selector Tests
* [X] register asm in sourceinfo for xamlc (#10001)
see #9294
* [iOS,Android, UWP] Set Position and CurrentItem when ItemsSource items change (#9854) fixes #9322 fixes #9401 fixes #9432 fixes #9771
* [Android] Update CurrentItem on CarouselView when the ItemSource changed
* Fix sample
* [iOS] Update CurrentItem when ItemSource changess
* [Controls] Fix sample
* [iOS] Fix setting initial CurrentItem
* [UITests] Add UITest for CurrentItem change
* [UItests] Fix iOS test
* [Core] If we keep in the same item we still might need to update the position
* [Controls] Add repo for issue #9322
* [Controls] Fix tests
* [iOS,Android] Use NotifyCollectionChangedEventHandler
* [iOS,Android,Controls] Fix rebase
* [Controls] Fix tests
* [iOS] Fix scrolling to initial position
* [Android] Fix set Currentitem
* [Android] Don't try set a current item if we cleared the collection
* [Controls] Updata sample for issue #9401
* [Android] Reset the ItemDecorations when adding/removing the last index
* [Android] UpdateVisualStates when updating CurrentItem
* [Core] If the position of CurrentItem is the same no need to scroll
* [Controls] Update sample
* [Android] Set new currentitem e position from renderer
* [iOS] Update position from renderer
* [iOS] Add hack for position
* [Tests] Comment test for position, this is done on the platform now
* Set correct content offset when removing previous Carousel slides (#9828)
Co-authored-by: E.Z. Hart <hartez@users.noreply.github.com>
* [Controls] Fix sample
* [iOS] Update CurrentItem
* [UWP] Set Item/position from renderer
* [UWP] Fix NRE when disposing IndicatorView
* [UWP] Fix CurrentItem on collection changes
* Update App.cs
* [Android] Move to internal the NotifyCollectionChangedEventHandler
* [iOS] Fix rebase
* [Android] Don't try set position if no items
* [Controls] Add sample for #9771
* [iOS] Fix issue when collection is empty
* [Controls] Update sample to fix uitests on API19
* [Tests] Remove old unit tests
* [Android] Recycler extension method for center item
* [UWP] Fix extra padding on items
* [UWP] Refactor validate position
{UWP] Don't set position if there's no items
* [Controls] Update samples for CarouselView
* [Android] Fix set position on collection reset
* [iOS] Fix set position on collection reset
* [Android] Fix visual states on android
* [UITests] Wait for gallery button
* [UWP] Handle Scrolled event on CarouselViewRenderer
* [Android] Validate set position out of bounds
[Android] Reset _goToPostio flag when reset source
* [Android] Reset snap when item count changes
* [Android] If we request ScrollTo we should reset the CurrentTargetPosition
* [Android] Small refactor, reset _goToPosition when ItemsSource changes
* [Android] Better fix for issue with SingleSnapHelper
* [Core] Add AnimatePositionChanges and AnimateCurrentItemChanges to CarouselView
* [Android] Add AnimateChanges usage to CarouselViewRenderer
* [UWP] Add AnimateChanges usage to CarouselViewRenderer
* [iOS] Add AnimateChanges to CarouselViewController
Co-authored-by: E.Z. Hart <hartez@users.noreply.github.com>
* [Core] Adds Color.FromHsva (#10054)
* Fixed SwipeView regression issue on iOS (#9464) fixes #9417
* Remove all uses of md5 (#10028)
* Remove all uses of md5
* - fix unit tests
* - fix dualscreen tests
* Update ColorTypeConverter to support HSVA (#10065)
* [Tizen] Provides global Circle Surface for wearable (#10083)
* Embedded fonts fix (#9194)
* Android should use the new FontStuff
* iOS font loading is now more resilant. It returns the loaded font name from the embedded resource!
* iOS now loads any font!
* Font Aliases now work on iOS, Android
* Optimized for Alias, making all the lookups faster
* UWP now works with Font Aliases
* Enable Scrolled event on ListView (#399)
* Enable Scrolled event on ListView
* Fixing logic to get current region
* Applying DIP convert to Scrolled event arguments
* Update syntax
* Removing unnecessary property
* Fix CirclePage.BackgroundImageSource (#214)
* Change protection level for CircleScrollViewRenderer (#222)
* Add IsWrapEnabled Property in CircleStepper (#224)
* Add IsWrapEnabled Property in CircleStepper
* change CreateAttached() to create()
yield return Create(Ldloc, context.Variables[elementNode]); //target
yield return Create(Ldstr, context.XamlFilePath);
+ yield return Create(Ldstr, ";assembly=");
+ yield return Create(Ldstr, context.Module.Assembly.Name.Name);
+ yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "String"),
+ methodName: "Concat",
+ parameterTypes: new[] {
+ ("mscorlib", "System", "String"),
+ ("mscorlib", "System", "String"),
+ ("mscorlib", "System", "String"),
+ },
+ isStatic: true));
+
+
yield return Create(Ldc_I4, (int)UriKind.RelativeOrAbsolute);
yield return Create(Newobj, module.ImportCtorReference(("System", "System", "Uri"),
parameterTypes: new[] {
if (!resource.Name.EndsWith(".xaml", StringComparison.InvariantCulture))
return false;
- using (var resourceStream = resource.GetResourceStream()) {
- var xmlDoc = new XmlDocument();
- xmlDoc.Load(resourceStream);
+ using (var resourceStream = resource.GetResourceStream())
+ using (var reader = XmlReader.Create(resourceStream))
+ {
+ // Read to the first Element
+ while (reader.Read() && reader.NodeType != XmlNodeType.Element) ;
- var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
-
- var root = xmlDoc.SelectSingleNode("/*", nsmgr);
- if (root == null)
+ if (reader.NodeType != XmlNodeType.Element)
return false;
- var rootClass = root.Attributes["Class", XamlParser.X2006Uri] ??
- root.Attributes["Class", XamlParser.X2009Uri];
- if (rootClass != null) {
- classname = rootClass.Value;
+ classname = reader.GetAttribute("Class", XamlParser.X2009Uri) ??
+ reader.GetAttribute("Class", XamlParser.X2006Uri);
+ if (classname != null)
return true;
- }
//no x:Class, but it might be a RD without x:Class and with <?xaml-comp compile="true" ?>
//in that case, it has a XamlResourceIdAttribute
RegisterPropertyHandler(Stepper.MaximumProperty, UpdateMaximum);
RegisterPropertyHandler(Stepper.ValueProperty, UpdateValue);
RegisterPropertyHandler(Stepper.IncrementProperty, UpdateIncrement);
+ RegisterPropertyHandler(CircleStepper.IsWrapEnabledProperty, UpdateWrapEnabled);
}
protected override void OnElementChanged(ElementChangedEventArgs<CircleStepper> e)
Control.Step = Element.Increment;
}
}
+
+ void UpdateWrapEnabled()
+ {
+ if (null != Control && null != Element)
+ {
+ Control.IsWrapEnabled = Element.IsWrapEnabled;
+ }
+ }
}
}
\ No newline at end of file
}
else
{
+ _bgImageObject.IsFilled = true;
_bgImageObject.File = ResourcePath.GetPath(bgImageSource);
_bgImage = BackgroundImageSource;
}
public static readonly BindableProperty TitleProperty = BindableProperty.Create(nameof(Title), typeof(string), typeof(CircleStepper), null);
/// <summary>
+ /// BindableProperty. Identifies whether min/max value is wrapped or not.
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public static readonly BindableProperty IsWrapEnabledProperty = BindableProperty.Create(nameof(IsWrapEnabled), typeof(bool), typeof(CircleStepper), true);
+
+ /// <summary>
/// Gets or sets Marker color
/// </summary>
/// <since_tizen> 4 </since_tizen>
[Obsolete("MarkerColor is obsolete as of Tizen.NET version 4.0.0 and is no longer supported")]
- public Color MarkerColor { get => (Color)GetValue(MarkerColorProperty); set => SetValue(MarkerColorProperty, value); }
+ public Color MarkerColor
+ {
+ get => (Color)GetValue(MarkerColorProperty);
+ set => SetValue(MarkerColorProperty, value);
+ }
+
/// <summary>
/// Gets or sets length of Marker
/// </summary>
/// <since_tizen> 4 </since_tizen>
[Obsolete("MarkerLineWidth is obsolete as of Tizen.NET version 4.0.0 and is no longer supported")]
- public int MarkerLineWidth { get => (int)GetValue(MarkerLineWidthProperty); set => SetValue(MarkerLineWidthProperty, value); }
+ public int MarkerLineWidth
+ {
+ get => (int)GetValue(MarkerLineWidthProperty);
+ set => SetValue(MarkerLineWidthProperty, value);
+ }
+
/// <summary>
/// Gets or sets format in which Value is shown
/// </summary>
/// <since_tizen> 4 </since_tizen>
- public string LabelFormat { get => (string)GetValue(LabelFormatProperty); set => SetValue(LabelFormatProperty, value); }
+ public string LabelFormat
+ {
+ get => (string)GetValue(LabelFormatProperty);
+ set => SetValue(LabelFormatProperty, value);
+ }
+
/// <summary>
/// Gets or sets title
/// </summary>
/// <since_tizen> 4 </since_tizen>
- public string Title { get => (string)GetValue(TitleProperty); set => SetValue(TitleProperty, value); }
+ public string Title
+ {
+ get => (string)GetValue(TitleProperty);
+ set => SetValue(TitleProperty, value);
+ }
+
+ /// <summary>
+ /// Gets or sets a status of Value is wrapped.
+ /// </summary>
+ /// <since_tizen> 4 </since_tizen>
+ public bool IsWrapEnabled
+ {
+ get => (bool)GetValue(IsWrapEnabledProperty);
+ set => SetValue(IsWrapEnabledProperty, value);
+ }
}
}
\ No newline at end of file
}
Action action = () => _expression.Apply();
- if (_expression._weakTarget.TryGetTarget(out BindableObject obj) && obj.Dispatcher != null && obj.Dispatcher.IsInvokeRequired)
+ if (_expression._weakTarget != null && _expression._weakTarget.TryGetTarget(out BindableObject obj) && obj.Dispatcher != null && obj.Dispatcher.IsInvokeRequired)
{
obj.Dispatcher.BeginInvokeOnMainThread(action);
}
set => SetValue(ColorProperty, value);
}
-
public CheckBox() => _platformConfigurationRegistry = new Lazy<PlatformConfigurationRegistry<CheckBox>>(() => new PlatformConfigurationRegistry<CheckBox>(this));
public bool IsChecked
{
return new Color(h, s, l, a, Mode.Hsl);
}
+
+ public static Color FromHsva(double h, double s, double v, double a)
+ {
+ h = h.Clamp(0, 1);
+ s = s.Clamp(0, 1);
+ v = v.Clamp(0, 1);
+ var range = (int)(Math.Floor(h * 6)) % 6;
+ var f = h * 6 - Math.Floor(h * 6);
+ var p = v * (1 - s);
+ var q = v * (1 - f * s);
+ var t = v * (1 - (1 - f) * s);
+
+ switch (range)
+ {
+ case 0:
+ return FromRgba(v, t, p, a);
+ case 1:
+ return FromRgba(q, v, p, a);
+ case 2:
+ return FromRgba(p, v, t, a);
+ case 3:
+ return FromRgba(p, q, v, a);
+ case 4:
+ return FromRgba(t, p, v, a);
+ }
+ return FromRgba(v, p, q, a);
+ }
+
+ public static Color FromHsv(double h, double s, double v)
+ {
+ return FromHsva(h, s, v, 1d);
+ }
+
+ public static Color FromHsva(int h, int s, int v, int a)
+ {
+ return FromHsva(h / 360d, s / 100d, v / 100d, a / 100d);
+ }
+
+ public static Color FromHsv(int h, int s, int v)
+ {
+ return FromHsva(h / 360d, s / 100d, v / 100d, 1d);
+ }
+
#if !NETSTANDARD1_0
public static implicit operator System.Drawing.Color(Color color)
{
// RGBA rgba(255, 0, 0, 0.8), rgba(100%, 0%, 0%, 0.8) opacity is 0.0-1.0
// HSL hsl(120, 100%, 50%) h is 0-360, s and l are 0%-100%
// HSLA hsla(120, 100%, 50%, .8) opacity is 0.0-1.0
+ // HSV hsv(120, 100%, 50%) h is 0-360, s and v are 0%-100%
+ // HSVA hsva(120, 100%, 50%, .8) opacity is 0.0-1.0
// Predefined color case insensitive
public override object ConvertFromInvariantString(string value)
{
return Color.FromHsla(h, s, l);
}
+ if (value.StartsWith("hsva", StringComparison.OrdinalIgnoreCase))
+ {
+ var op = value.IndexOf('(');
+ var cp = value.LastIndexOf(')');
+ if (op < 0 || cp < 0 || cp < op)
+ throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(Color)}");
+ var quad = value.Substring(op + 1, cp - op - 1).Split(',');
+ if (quad.Length != 4)
+ throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(Color)}");
+ var h = ParseColorValue(quad[0], 360, acceptPercent: false);
+ var s = ParseColorValue(quad[1], 100, acceptPercent: true);
+ var v = ParseColorValue(quad[2], 100, acceptPercent: true);
+ var a = ParseOpacity(quad[3]);
+ return Color.FromHsva(h, s, v, a);
+ }
+
+ if (value.StartsWith("hsv", StringComparison.OrdinalIgnoreCase))
+ {
+ var op = value.IndexOf('(');
+ var cp = value.LastIndexOf(')');
+ if (op < 0 || cp < 0 || cp < op)
+ throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(Color)}");
+ var triplet = value.Substring(op + 1, cp - op - 1).Split(',');
+ if (triplet.Length != 3)
+ throw new InvalidOperationException($"Cannot convert \"{value}\" into {typeof(Color)}");
+ var h = ParseColorValue(triplet[0], 360, acceptPercent: false);
+ var s = ParseColorValue(triplet[1], 100, acceptPercent: true);
+ var v = ParseColorValue(triplet[2], 100, acceptPercent: true);
+ return Color.FromHsv(h, s, v);
+ }
+
string[] parts = value.Split('.');
if (parts.Length == 1 || (parts.Length == 2 && parts[0] == "Color"))
{
--- /dev/null
+#if !NETSTANDARD1_0
+
+using System;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using System.Text;
+
+/// <summary>
+/// https://github.com/xamarin/java.interop/blob/master/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.cs
+/// </summary>
+namespace Xamarin.Forms.Internals
+{
+ /// <summary>
+ /// CRC64 variant: crc-64-jones 64-bit
+ /// * Poly: 0xad93d23594c935a9
+ /// Changes beyond initial implementation:
+ /// * Starting Value: ulong.MaxValue
+ /// * XOR length in HashFinal()
+ /// </summary>
+ internal class Crc64 : HashAlgorithm
+ {
+ static Crc64 _instance;
+ public static Crc64 Instance
+ {
+ get
+ {
+ if (_instance == null)
+ _instance = new Crc64();
+
+ return _instance;
+ }
+ }
+
+ Crc64() { }
+
+ static readonly ulong[] Table = {
+ 0x0000000000000000, 0x7ad870c830358979,
+ 0xf5b0e190606b12f2, 0x8f689158505e9b8b,
+ 0xc038e5739841b68f, 0xbae095bba8743ff6,
+ 0x358804e3f82aa47d, 0x4f50742bc81f2d04,
+ 0xab28ecb46814fe75, 0xd1f09c7c5821770c,
+ 0x5e980d24087fec87, 0x24407dec384a65fe,
+ 0x6b1009c7f05548fa, 0x11c8790fc060c183,
+ 0x9ea0e857903e5a08, 0xe478989fa00bd371,
+ 0x7d08ff3b88be6f81, 0x07d08ff3b88be6f8,
+ 0x88b81eabe8d57d73, 0xf2606e63d8e0f40a,
+ 0xbd301a4810ffd90e, 0xc7e86a8020ca5077,
+ 0x4880fbd87094cbfc, 0x32588b1040a14285,
+ 0xd620138fe0aa91f4, 0xacf86347d09f188d,
+ 0x2390f21f80c18306, 0x594882d7b0f40a7f,
+ 0x1618f6fc78eb277b, 0x6cc0863448deae02,
+ 0xe3a8176c18803589, 0x997067a428b5bcf0,
+ 0xfa11fe77117cdf02, 0x80c98ebf2149567b,
+ 0x0fa11fe77117cdf0, 0x75796f2f41224489,
+ 0x3a291b04893d698d, 0x40f16bccb908e0f4,
+ 0xcf99fa94e9567b7f, 0xb5418a5cd963f206,
+ 0x513912c379682177, 0x2be1620b495da80e,
+ 0xa489f35319033385, 0xde51839b2936bafc,
+ 0x9101f7b0e12997f8, 0xebd98778d11c1e81,
+ 0x64b116208142850a, 0x1e6966e8b1770c73,
+ 0x8719014c99c2b083, 0xfdc17184a9f739fa,
+ 0x72a9e0dcf9a9a271, 0x08719014c99c2b08,
+ 0x4721e43f0183060c, 0x3df994f731b68f75,
+ 0xb29105af61e814fe, 0xc849756751dd9d87,
+ 0x2c31edf8f1d64ef6, 0x56e99d30c1e3c78f,
+ 0xd9810c6891bd5c04, 0xa3597ca0a188d57d,
+ 0xec09088b6997f879, 0x96d1784359a27100,
+ 0x19b9e91b09fcea8b, 0x636199d339c963f2,
+ 0xdf7adabd7a6e2d6f, 0xa5a2aa754a5ba416,
+ 0x2aca3b2d1a053f9d, 0x50124be52a30b6e4,
+ 0x1f423fcee22f9be0, 0x659a4f06d21a1299,
+ 0xeaf2de5e82448912, 0x902aae96b271006b,
+ 0x74523609127ad31a, 0x0e8a46c1224f5a63,
+ 0x81e2d7997211c1e8, 0xfb3aa75142244891,
+ 0xb46ad37a8a3b6595, 0xceb2a3b2ba0eecec,
+ 0x41da32eaea507767, 0x3b024222da65fe1e,
+ 0xa2722586f2d042ee, 0xd8aa554ec2e5cb97,
+ 0x57c2c41692bb501c, 0x2d1ab4dea28ed965,
+ 0x624ac0f56a91f461, 0x1892b03d5aa47d18,
+ 0x97fa21650afae693, 0xed2251ad3acf6fea,
+ 0x095ac9329ac4bc9b, 0x7382b9faaaf135e2,
+ 0xfcea28a2faafae69, 0x8632586aca9a2710,
+ 0xc9622c4102850a14, 0xb3ba5c8932b0836d,
+ 0x3cd2cdd162ee18e6, 0x460abd1952db919f,
+ 0x256b24ca6b12f26d, 0x5fb354025b277b14,
+ 0xd0dbc55a0b79e09f, 0xaa03b5923b4c69e6,
+ 0xe553c1b9f35344e2, 0x9f8bb171c366cd9b,
+ 0x10e3202993385610, 0x6a3b50e1a30ddf69,
+ 0x8e43c87e03060c18, 0xf49bb8b633338561,
+ 0x7bf329ee636d1eea, 0x012b592653589793,
+ 0x4e7b2d0d9b47ba97, 0x34a35dc5ab7233ee,
+ 0xbbcbcc9dfb2ca865, 0xc113bc55cb19211c,
+ 0x5863dbf1e3ac9dec, 0x22bbab39d3991495,
+ 0xadd33a6183c78f1e, 0xd70b4aa9b3f20667,
+ 0x985b3e827bed2b63, 0xe2834e4a4bd8a21a,
+ 0x6debdf121b863991, 0x1733afda2bb3b0e8,
+ 0xf34b37458bb86399, 0x8993478dbb8deae0,
+ 0x06fbd6d5ebd3716b, 0x7c23a61ddbe6f812,
+ 0x3373d23613f9d516, 0x49aba2fe23cc5c6f,
+ 0xc6c333a67392c7e4, 0xbc1b436e43a74e9d,
+ 0x95ac9329ac4bc9b5, 0xef74e3e19c7e40cc,
+ 0x601c72b9cc20db47, 0x1ac40271fc15523e,
+ 0x5594765a340a7f3a, 0x2f4c0692043ff643,
+ 0xa02497ca54616dc8, 0xdafce7026454e4b1,
+ 0x3e847f9dc45f37c0, 0x445c0f55f46abeb9,
+ 0xcb349e0da4342532, 0xb1eceec59401ac4b,
+ 0xfebc9aee5c1e814f, 0x8464ea266c2b0836,
+ 0x0b0c7b7e3c7593bd, 0x71d40bb60c401ac4,
+ 0xe8a46c1224f5a634, 0x927c1cda14c02f4d,
+ 0x1d148d82449eb4c6, 0x67ccfd4a74ab3dbf,
+ 0x289c8961bcb410bb, 0x5244f9a98c8199c2,
+ 0xdd2c68f1dcdf0249, 0xa7f41839ecea8b30,
+ 0x438c80a64ce15841, 0x3954f06e7cd4d138,
+ 0xb63c61362c8a4ab3, 0xcce411fe1cbfc3ca,
+ 0x83b465d5d4a0eece, 0xf96c151de49567b7,
+ 0x76048445b4cbfc3c, 0x0cdcf48d84fe7545,
+ 0x6fbd6d5ebd3716b7, 0x15651d968d029fce,
+ 0x9a0d8ccedd5c0445, 0xe0d5fc06ed698d3c,
+ 0xaf85882d2576a038, 0xd55df8e515432941,
+ 0x5a3569bd451db2ca, 0x20ed197575283bb3,
+ 0xc49581ead523e8c2, 0xbe4df122e51661bb,
+ 0x3125607ab548fa30, 0x4bfd10b2857d7349,
+ 0x04ad64994d625e4d, 0x7e7514517d57d734,
+ 0xf11d85092d094cbf, 0x8bc5f5c11d3cc5c6,
+ 0x12b5926535897936, 0x686de2ad05bcf04f,
+ 0xe70573f555e26bc4, 0x9ddd033d65d7e2bd,
+ 0xd28d7716adc8cfb9, 0xa85507de9dfd46c0,
+ 0x273d9686cda3dd4b, 0x5de5e64efd965432,
+ 0xb99d7ed15d9d8743, 0xc3450e196da80e3a,
+ 0x4c2d9f413df695b1, 0x36f5ef890dc31cc8,
+ 0x79a59ba2c5dc31cc, 0x037deb6af5e9b8b5,
+ 0x8c157a32a5b7233e, 0xf6cd0afa9582aa47,
+ 0x4ad64994d625e4da, 0x300e395ce6106da3,
+ 0xbf66a804b64ef628, 0xc5bed8cc867b7f51,
+ 0x8aeeace74e645255, 0xf036dc2f7e51db2c,
+ 0x7f5e4d772e0f40a7, 0x05863dbf1e3ac9de,
+ 0xe1fea520be311aaf, 0x9b26d5e88e0493d6,
+ 0x144e44b0de5a085d, 0x6e963478ee6f8124,
+ 0x21c640532670ac20, 0x5b1e309b16452559,
+ 0xd476a1c3461bbed2, 0xaeaed10b762e37ab,
+ 0x37deb6af5e9b8b5b, 0x4d06c6676eae0222,
+ 0xc26e573f3ef099a9, 0xb8b627f70ec510d0,
+ 0xf7e653dcc6da3dd4, 0x8d3e2314f6efb4ad,
+ 0x0256b24ca6b12f26, 0x788ec2849684a65f,
+ 0x9cf65a1b368f752e, 0xe62e2ad306bafc57,
+ 0x6946bb8b56e467dc, 0x139ecb4366d1eea5,
+ 0x5ccebf68aecec3a1, 0x2616cfa09efb4ad8,
+ 0xa97e5ef8cea5d153, 0xd3a62e30fe90582a,
+ 0xb0c7b7e3c7593bd8, 0xca1fc72bf76cb2a1,
+ 0x45775673a732292a, 0x3faf26bb9707a053,
+ 0x70ff52905f188d57, 0x0a2722586f2d042e,
+ 0x854fb3003f739fa5, 0xff97c3c80f4616dc,
+ 0x1bef5b57af4dc5ad, 0x61372b9f9f784cd4,
+ 0xee5fbac7cf26d75f, 0x9487ca0fff135e26,
+ 0xdbd7be24370c7322, 0xa10fceec0739fa5b,
+ 0x2e675fb4576761d0, 0x54bf2f7c6752e8a9,
+ 0xcdcf48d84fe75459, 0xb71738107fd2dd20,
+ 0x387fa9482f8c46ab, 0x42a7d9801fb9cfd2,
+ 0x0df7adabd7a6e2d6, 0x772fdd63e7936baf,
+ 0xf8474c3bb7cdf024, 0x829f3cf387f8795d,
+ 0x66e7a46c27f3aa2c, 0x1c3fd4a417c62355,
+ 0x935745fc4798b8de, 0xe98f353477ad31a7,
+ 0xa6df411fbfb21ca3, 0xdc0731d78f8795da,
+ 0x536fa08fdfd90e51, 0x29b7d047efec8728,
+ };
+
+ ulong crc = ulong.MaxValue;
+ ulong length = 0;
+
+ public override void Initialize()
+ {
+ crc = ulong.MaxValue;
+ length = 0;
+ }
+
+ protected override void HashCore(byte[] array, int ibStart, int cbSize)
+ {
+ for (int i = ibStart; i < cbSize; i++)
+ {
+ crc = Table[(byte)(crc ^ array[i])] ^ (crc >> 8);
+ }
+ length += (ulong)cbSize;
+ }
+
+ protected override byte[] HashFinal() => BitConverter.GetBytes(crc ^ length);
+
+
+
+ // https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa/24343727#24343727
+ static readonly uint[] _lookup32 = CreateLookup32();
+
+ static uint[] CreateLookup32()
+ {
+ var result = new uint[256];
+ for (int i = 0; i < 256; i++)
+ {
+ string s = i.ToString("X2");
+ result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
+ }
+ return result;
+ }
+
+ static string ByteArrayToHexViaLookup32(byte[] bytes)
+ {
+ var lookup32 = _lookup32;
+ var result = new char[bytes.Length * 2];
+ for (int i = 0; i < bytes.Length; i++)
+ {
+ var val = lookup32[bytes[i]];
+ result[2 * i] = (char)val;
+ result[2 * i + 1] = (char)(val >> 16);
+ }
+ return new string(result);
+ }
+
+ public static string GetHash(string input)
+ {
+ byte[] bytes = Instance.ComputeHash(Encoding.UTF8.GetBytes(input));
+ return ByteArrayToHexViaLookup32(bytes);
+ }
+
+ }
+}
+#endif
\ No newline at end of file
public static void Register(ExportFontAttribute fontAttribute, Assembly assembly)
{
EmbeddedFonts[fontAttribute.FontFileName] = (fontAttribute, assembly);
+ if (!string.IsNullOrWhiteSpace(fontAttribute.Alias))
+ EmbeddedFonts[fontAttribute.Alias] = (fontAttribute, assembly);
}
//TODO: Investigate making this Async
return (false, null);
}
- var fontStream = GetEmbeddedResourceStream(foundFont.assembly, font);
+ var fontStream = GetEmbeddedResourceStream(foundFont.assembly, foundFont.attribute.FontFileName);
var type = Registrar.Registered.GetHandlerType(typeof(EmbeddedFont));
var fontHandler = (IEmbeddedFontLoader)Activator.CreateInstance(type);
- return fontHandler.LoadFont(new EmbeddedFont { FontName = font, ResourceStream = fontStream });
+ return fontHandler.LoadFont(new EmbeddedFont { FontName = foundFont.attribute.FontFileName, ResourceStream = fontStream });
}
catch (Exception ex)
Assembly[] GetAssemblies();
+ string GetHash(string input);
+
+ [Obsolete("GetMD5Hash is obsolete as of version 4.7.0")]
string GetMD5Hash(string input);
double GetNamedSize(NamedSize size, Type targetElementType, bool useOldSizes);
public const string PreviousItemVisualState = "PreviousItem";
public const string DefaultItemVisualState = "DefaultItem";
- bool _isInitialized;
- int _gotoPosition = -1;
-
public static readonly BindableProperty PeekAreaInsetsProperty = BindableProperty.Create(nameof(PeekAreaInsets), typeof(Thickness), typeof(CarouselView), default(Thickness));
public Thickness PeekAreaInsets
}
}
- var positionItem = GetPositionForItem(carouselView, newValue);
- var gotoPosition = carouselView._gotoPosition;
-
- if (positionItem == gotoPosition || gotoPosition == -1)
- {
- carouselView._gotoPosition = -1;
- carouselView.SetValueCore(PositionProperty, positionItem);
- }
-
carouselView.CurrentItemChanged?.Invoke(carouselView, args);
carouselView.OnCurrentItemChanged(args);
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsScrolling { get; set; }
- [EditorBrowsable(EditorBrowsableState.Never)]
- public Queue<Action> ScrollToActions = new Queue<Action>();
-
public event EventHandler<CurrentItemChangedEventArgs> CurrentItemChanged;
public event EventHandler<PositionChangedEventArgs> PositionChanged;
{
}
- protected override void OnScrolled(ItemsViewScrolledEventArgs e)
- {
- SetCurrentItem(GetItemForPosition(this, e.CenterItemIndex));
-
- base.OnScrolled(e);
- }
-
static void PositionPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
-
var carousel = (CarouselView)bindable;
var args = new PositionChangedEventArgs((int)oldValue, (int)newValue);
carousel.PositionChanged?.Invoke(carousel, args);
- if (args.CurrentPosition == carousel._gotoPosition)
- carousel._gotoPosition = -1;
-
- // User is interacting with the carousel we don't need to scroll to item
- if (!carousel.IsDragging && !carousel.IsScrolling)
- {
- carousel._gotoPosition = args.CurrentPosition;
-
- Action actionSCroll = () =>
- {
- carousel.ScrollTo(args.CurrentPosition, position: ScrollToPosition.Center, animate: carousel.IsScrollAnimated);
- };
-
- if (!carousel._isInitialized)
- carousel.ScrollToActions.Enqueue(actionSCroll);
- else
- actionSCroll();
- }
-
carousel.OnPositionChanged(args);
}
-
- static object GetItemForPosition(CarouselView carouselView, int index)
- {
- if (!(carouselView?.ItemsSource is IList itemSource))
- return null;
-
- if (itemSource.Count == 0)
- return null;
-
- return itemSource[index];
- }
-
- static int GetPositionForItem(CarouselView carouselView, object item)
- {
- var itemSource = carouselView?.ItemsSource as IList;
-
- for (int n = 0; n < itemSource?.Count; n++)
- {
- if (itemSource[n] == item)
- {
- return n;
- }
- }
- return 0;
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void SetCurrentItem(object item)
- {
- SetValueFromRenderer(CurrentItemProperty, item);
- }
-
[EditorBrowsable(EditorBrowsableState.Never)]
public void SetIsDragging(bool value)
{
}
[EditorBrowsable(EditorBrowsableState.Never)]
- public void PlatformInitialized()
- {
- _isInitialized = true;
- }
+ public virtual bool AnimatePositionChanges => IsScrollAnimated;
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public virtual bool AnimateCurrentItemChanges => IsScrollAnimated;
+
}
}
\ No newline at end of file
--- /dev/null
+namespace Xamarin.Forms.PlatformConfiguration.TizenSpecific
+{
+ using FormsElement = Xamarin.Forms.Application;
+
+ public static class Application
+ {
+ public static readonly BindableProperty UseBezelInteractionProperty = BindableProperty.Create("UseBezelInteraction", typeof(bool), typeof(FormsElement), true);
+
+ public static bool GetUseBezelInteraction(BindableObject element)
+ {
+ return (bool)element.GetValue(UseBezelInteractionProperty);
+ }
+
+ public static void SetUseBezelInteraction(BindableObject element, bool value)
+ {
+ element.SetValue(UseBezelInteractionProperty, value);
+ }
+
+ public static bool GetUseBezelInteraction(this IPlatformElementConfiguration<Tizen, FormsElement> config)
+ {
+ return GetUseBezelInteraction(config.Element);
+ }
+
+ public static IPlatformElementConfiguration<Tizen, FormsElement> SetUseBezelInteraction(this IPlatformElementConfiguration<Tizen, FormsElement> config, bool value)
+ {
+ SetUseBezelInteraction(config.Element, value);
+ return config;
+ }
+ }
+}
return;
}
- _targets.RemoveAll(t => !t.TryGetTarget(out _));
+ _targets.RemoveAll(t => t == null || !t.TryGetTarget(out _));
_cleanupThreshold = _targets.Count + CleanupTrigger;
}
}
&& c != '>'
&& c != ','
&& c != '~'
- && c != '^'
&& c != stopChar);
break;
}
}
}
}
-}
\ No newline at end of file
+}
public SwipeDirection SwipeDirection { get; set; }
}
+ public class OpenSwipeEventArgs : EventArgs
+ {
+ public OpenSwipeEventArgs(OpenSwipeItem openSwipeItem)
+ {
+ OpenSwipeItem = openSwipeItem;
+ }
+
+ public OpenSwipeItem OpenSwipeItem { get; set; }
+ }
+
public class SwipeStartedEventArgs : BaseSwipeEventArgs
{
public SwipeStartedEventArgs(SwipeDirection swipeDirection) : base(swipeDirection)
namespace Xamarin.Forms
{
+ public enum OpenSwipeItem
+ {
+ LeftItems,
+ TopItems,
+ RightItems,
+ BottomItems
+ }
+
public class SwipeItems : Element, IList<ISwipeItem>, INotifyCollectionChanged
{
readonly ObservableCollection<ISwipeItem> _swipeItems;
propertyChanged: OnSwipeItemsChanged);
public static readonly BindableProperty RightItemsProperty =
- BindableProperty.Create(nameof(RightItems), typeof(SwipeItems), typeof(SwipeView), null, BindingMode.OneWay, null, defaultValueCreator: SwipeItemsDefaultValueCreator);
+ BindableProperty.Create(nameof(RightItems), typeof(SwipeItems), typeof(SwipeView), null, BindingMode.OneWay, null, defaultValueCreator: SwipeItemsDefaultValueCreator,
+ propertyChanged: OnSwipeItemsChanged);
public static readonly BindableProperty TopItemsProperty =
- BindableProperty.Create(nameof(TopItems), typeof(SwipeItems), typeof(SwipeView), null, BindingMode.OneWay, null, defaultValueCreator: SwipeItemsDefaultValueCreator);
+ BindableProperty.Create(nameof(TopItems), typeof(SwipeItems), typeof(SwipeView), null, BindingMode.OneWay, null, defaultValueCreator: SwipeItemsDefaultValueCreator,
+ propertyChanged: OnSwipeItemsChanged);
public static readonly BindableProperty BottomItemsProperty =
- BindableProperty.Create(nameof(BottomItems), typeof(SwipeItems), typeof(SwipeView), null, BindingMode.OneWay, null, defaultValueCreator: SwipeItemsDefaultValueCreator);
+ BindableProperty.Create(nameof(BottomItems), typeof(SwipeItems), typeof(SwipeView), null, BindingMode.OneWay, null, defaultValueCreator: SwipeItemsDefaultValueCreator,
+ propertyChanged: OnSwipeItemsChanged);
public SwipeItems LeftItems
{
public event EventHandler<SwipeStartedEventArgs> SwipeStarted;
public event EventHandler<SwipeChangingEventArgs> SwipeChanging;
public event EventHandler<SwipeEndedEventArgs> SwipeEnded;
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event EventHandler<OpenSwipeEventArgs> OpenRequested;
+
public event EventHandler CloseRequested;
+ public void Open(OpenSwipeItem openSwipeItem)
+ {
+ OpenRequested?.Invoke(this, new OpenSwipeEventArgs(openSwipeItem));
+ }
+
public void Close()
{
CloseRequested?.Invoke(this, EventArgs.Empty);
swipeItems.Parent = this;
foreach (var swipeItem in swipeItems)
- ((VisualElement)swipeItem).Parent = swipeItems;
+ ((Element)swipeItem).Parent = swipeItems;
}
}
}
\ No newline at end of file
{
public static class TabIndexExtensions
{
- public static SortedDictionary<int, List<ITabStopElement>> GetSortedTabIndexesOnParentPage(this VisualElement element, out int countChildrensWithTabStopWithoutThis)
+ public static SortedDictionary<int, List<ITabStopElement>> GetSortedTabIndexesOnParentPage(this VisualElement element)
{
- return new SortedDictionary<int, List<ITabStopElement>>(TabIndexExtensions.GetTabIndexesOnParentPage(element, out countChildrensWithTabStopWithoutThis));
+ return new SortedDictionary<int, List<ITabStopElement>>(GetTabIndexesOnParentPage(element, out _));
}
- public static IDictionary<int, List<ITabStopElement>> GetTabIndexesOnParentPage(this ITabStopElement element, out int countChildrensWithTabStopWithoutThis, bool checkContainsElement = true)
+ public static IDictionary<int, List<ITabStopElement>> GetTabIndexesOnParentPage(this ITabStopElement element, out int countChildrenWithTabStopWithoutThis)
{
- countChildrensWithTabStopWithoutThis = 0;
+ var empty = new Dictionary<int, List<ITabStopElement>>();
+ countChildrenWithTabStopWithoutThis = 0;
Element parentPage = (element as Element)?.Parent;
while (parentPage != null && !(parentPage is Page))
descendantsOnPage = shell.GetItems();
if (descendantsOnPage == null)
- return new Dictionary<int, List<ITabStopElement>>();
+ return empty;
- var childrensWithTabStop = new List<ITabStopElement>();
+ var childrenWithTabStop = new List<ITabStopElement>();
foreach (var descendant in descendantsOnPage)
{
- if (descendant is ITabStopElement visualElement && visualElement.IsTabStop)
- childrensWithTabStop.Add(visualElement);
+ if (descendant is ITabStopElement visualElement && IsTabStop(descendant))
+ childrenWithTabStop.Add(visualElement);
}
- if (checkContainsElement && !childrensWithTabStop.Contains(element))
- return new Dictionary<int, List<ITabStopElement>>();
-
- countChildrensWithTabStopWithoutThis = childrensWithTabStop.Count - 1;
- return childrensWithTabStop.GroupToDictionary(c => c.TabIndex);
+ countChildrenWithTabStopWithoutThis = childrenWithTabStop.Count - 1;
+ return childrenWithTabStop.GroupToDictionary(c => c.TabIndex);
}
public static ITabStopElement FindNextElement(this ITabStopElement element, bool forwardDirection, IDictionary<int, List<ITabStopElement>> tabIndexes, ref int tabIndex)
}
}
}
+
+ static bool IsTabStop(BindableObject e)
+ {
+ if (e is VisualElement fe)
+ return
+ AutomationProperties.GetIsInAccessibleTree(fe) != false //Focusable
+ && fe.IsTabStop
+ && fe.IsEnabled
+ && fe.IsVisible;
+
+ return false;
+ }
}
}
\ No newline at end of file
BindableObject target;
#if DO_NOT_CHECK_FOR_BINDING_REUSE
if (!_weakTarget.TryGetTarget(out target))
- throw new InvalidOperationException();
+ return;
#else
if (!_weakTarget.TryGetTarget(out target) || target == null) {
Unapply();
static string GetCacheKey(Uri uri)
{
- return Device.PlatformServices.GetMD5Hash(uri.AbsoluteUri);
+ return Device.PlatformServices.GetHash(uri.AbsoluteUri);
}
async Task<bool> GetHasLocallyCachedCopyAsync(string key, bool checkValidity = true)
static string CleanseFontName(string fontName)
{
+ //First check Alias
+ var (hasFontAlias, fontPostScriptName) = FontRegistrar.HasFont(fontName);
+ if (hasFontAlias)
+ return fontPostScriptName;
var fontFile = FontFile.FromString(fontName);
if (!string.IsNullOrWhiteSpace(fontFile.Extension))
using ELayout = ElmSharp.Layout;
using DeviceOrientation = Xamarin.Forms.Internals.DeviceOrientation;
using Xamarin.Forms.PlatformConfiguration.TizenSpecific;
+using ElmSharp.Wearable;
namespace Xamarin.Forms
{
public static ELayout BaseLayout => NativeParent as ELayout;
+ public static CircleSurface CircleSurface
+ {
+ get; internal set;
+ }
+
public static bool IsInitialized
{
get;
EWindow eWindow = null;
ELayout eLayout = null;
+ CircleSurface eCircleSurface = null;
var typeWin = typeof(EWindow);
var methodInfo = typeWin.GetMethod("CreateWindow", BindingFlags.NonPublic | BindingFlags.Static);
if (methodInfo != null)
{
eWindow = (EWindow)methodInfo.Invoke(null, new object[] { "FormsWindow" });
eLayout = (ELayout)eWindow.GetType().GetProperty("BaseLayout")?.GetValue(eWindow);
+ eCircleSurface = (CircleSurface)eWindow.GetType().GetProperty("BaseCircleSurface")?.GetValue(eWindow);
}
PreloadedWindow preloadedWindow = null;
if (eWindow != null && eLayout != null)
{
- preloadedWindow = new PreloadedWindow(eWindow, eLayout);
+ preloadedWindow = new PreloadedWindow(eWindow, eLayout, eCircleSurface);
}
else
{
using ELayout = ElmSharp.Layout;
using DeviceOrientation = Xamarin.Forms.Internals.DeviceOrientation;
using Xamarin.Forms.Platform.Tizen.Native;
+using ElmSharp.Wearable;
+using Specific = Xamarin.Forms.PlatformConfiguration.TizenSpecific.Application;
namespace Xamarin.Forms.Platform.Tizen
{
Application _application;
bool _isInitialStart;
Window _window;
+ bool _useBezelInteration;
protected FormsApplication()
{
get; protected set;
}
+ public CircleSurface BaseCircleSurface
+ {
+ get; protected set;
+ }
+
+ public bool UseBezelInteration => _useBezelInteration;
+
protected override void OnPreCreate()
{
base.OnPreCreate();
PreloadedWindow window = PreloadedWindow.GetInstance() ?? new PreloadedWindow();
BaseLayout = window.BaseLayout;
MainWindow = window.Window;
+ BaseCircleSurface = window.BaseCircleSurface;
+ Forms.CircleSurface = BaseCircleSurface;
}
protected override void OnTerminate()
application.SendStart();
application.PropertyChanged += new PropertyChangedEventHandler(this.AppOnPropertyChanged);
SetPage(_application.MainPage);
+ _useBezelInteration = Device.Idiom == TargetIdiom.Watch && Specific.GetUseBezelInteraction(_application);
}
void AppOnPropertyChanged(object sender, PropertyChangedEventArgs args)
{
SetPage(_application.MainPage);
}
+ else if (Device.Idiom == TargetIdiom.Watch)
+ {
+ if (Specific.UseBezelInteractionProperty.PropertyName == args.PropertyName)
+ {
+ _useBezelInteration = Specific.GetUseBezelInteraction(_application);
+ }
+ }
}
void SetPage(Page page)
layout.Show();
BaseLayout = layout;
+
+ if (Device.Idiom == TargetIdiom.Watch)
+ {
+ BaseCircleSurface = new CircleSurface(conformant);
+ Forms.CircleSurface = BaseCircleSurface;
+ }
conformant.SetContent(BaseLayout);
}
internal TemplatedItemsList<ItemsView<Cell>, Cell> ListOfSubItems;
}
+ class ScrollerExtension : Scroller
+ {
+ public ScrollerExtension(GenList scrollableLayout) : base(scrollableLayout)
+ {
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return parent.RealHandle;
+ }
+ }
+
/// <summary>
/// The item context list for each added element.
/// </summary>
/// </summary>
GenItemClass _headerFooterItemClass = null;
+ ScrollerExtension _scrollerExtension;
+
/// <summary>
/// Gets or sets a value indicating whether this instance has grouping enabled.
/// </summary>
public bool IsGroupingEnabled { get; set; }
/// <summary>
+ /// Gets the current region in the content object that is visible through the Scroller.
+ /// </summary>
+ public Rect CurrentRegion => _scrollerExtension.CurrentRegion;
+
+ /// <summary>
+ /// Occurs when the ListView has scrolled.
+ /// </summary>
+ public event EventHandler Scrolled;
+
+ /// <summary>
/// Constructor of ListView native control.
/// </summary>
/// <param name="parent">ElmSharp object which is parent of particular list view</param>
public ListView(EvasObject parent)
: base(parent)
{
+ _scrollerExtension = new ScrollerExtension(this);
+ new SmartEvent(this, RealHandle, "scroll").On += (s,e) =>
+ {
+ Scrolled?.Invoke(this, null);
+ };
}
protected ListView() : base()
using ElmSharp;
+using ElmSharp.Wearable;
using ELayout = ElmSharp.Layout;
namespace Xamarin.Forms.Platform.Tizen
Initialize();
}
- public PreloadedWindow(Window win, ELayout layout)
+ public PreloadedWindow(Window win, ELayout layout, CircleSurface circleSurface)
{
s_precreated = this;
Window = win;
BaseLayout = layout;
+ BaseCircleSurface = circleSurface;
}
public Window Window
protected set;
}
+ public CircleSurface BaseCircleSurface
+ {
+ get; protected set;
+ }
+
protected void Initialize()
{
Window = new Window("FormsWindow");
layout.Show();
BaseLayout = layout;
+
+ if (Device.Idiom == TargetIdiom.Watch)
+ {
+ BaseCircleSurface = new CircleSurface(conformant);
+ }
conformant.SetContent(BaseLayout);
}
{
SetNativeControl(new Native.ListView(Forms.NativeParent));
+ Control.Scrolled += OnScrolled;
Control.ItemSelected += OnListViewItemSelected;
Control.ItemUnselected += OnListViewItemUnselected;
}
if (Control != null)
{
+ Control.Scrolled -= OnScrolled;
Control.ItemSelected -= OnListViewItemSelected;
Control.ItemUnselected -= OnListViewItemUnselected;
}
}
}
+ void OnScrolled(object sender, EventArgs e)
+ {
+ var region = Control.CurrentRegion.ToDP();
+ Element.SendScrolled(new ScrolledEventArgs(region.X, region.Y));
+ }
+
/// <summary>
/// This is method handles "scroll to" requests from xamarin events.
/// It allows for scrolling to specified item on list view.
{
internal class TizenPlatformServices : IPlatformServices
{
- static Lazy<MD5> checksum = new Lazy<MD5>(CreateChecksum);
-
static SynchronizationContext s_context;
public TizenPlatformServices()
return new TizenIsolatedStorageFile();
}
- static readonly char[] HexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- public string GetMD5Hash(string input)
- {
- byte[] bin = checksum.Value.ComputeHash(System.Text.Encoding.UTF8.GetBytes(input));
- char[] hex = new char[32];
- for (var i = 0; i < 16; ++i)
- {
- hex[2 * i] = HexDigits[bin[i] >> 4];
- hex[2 * i + 1] = HexDigits[bin[i] & 0xf];
- }
- return new string(hex);
- }
+ public string GetHash(string input) => Crc64.GetHash(input);
+
+ string IPlatformServices.GetMD5Hash(string input) => GetHash(input);
public void QuitApplication()
{
{
return Platform.GetNativeSize(view, widthConstraint, heightConstraint);
}
-
- static MD5 CreateChecksum()
- {
- return MD5.Create();
- }
}
}
\ No newline at end of file
protected Property ParseProperty(IServiceProvider serviceProvider, ref string remaining)
{
- char next;
object value = null;
string str_value;
string name;
if (remaining[0] == '{')
return ParsePropertyExpression(null, serviceProvider, ref remaining);
- str_value = GetNextPiece(serviceProvider, ref remaining, out next);
+ str_value = GetNextPiece(serviceProvider, ref remaining, out var next);
if (next == '=') {
remaining = remaining.TrimStart();
if (remaining[0] == '{')
return new Property { last = next == '}', name = name, strValue = str_value, value = value };
}
- private Property ParsePropertyExpression(string prop, IServiceProvider serviceProvider, ref string remaining)
+ Property ParsePropertyExpression(string prop, IServiceProvider serviceProvider, ref string remaining)
{
bool last;
var value = ParseExpression(ref remaining, serviceProvider);
return new Property { last = last, name = prop, strValue = value as string, value = value };
}
- private string GetNextPiece(IServiceProvider serviceProvider, ref string remaining, out char next)
+ string GetNextPiece(IServiceProvider serviceProvider, ref string remaining, out char next)
{
bool inString = false;
int end = 0;
{
inString = false;
end ++;
+ while (remaining[end] == ' ')
+ end++;
break;
}
}