diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets index 74c39cc99..4e96fafcd 100644 --- a/.paket/Paket.Restore.targets +++ b/.paket/Paket.Restore.targets @@ -21,16 +21,16 @@ $(PaketToolsPath)paket $(PaketRootPath)paket.exe - $(PaketToolsPath)paket.exe - $(PaketToolsPath)paket.exe - $(PaketToolsPath)paket + $(PaketToolsPath)paket.exe + $(PaketToolsPath)paket.exe + $(PaketToolsPath)paket + paket <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) dotnet "$(PaketExePath)" - "$(PaketExePath)" $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" - "$(PaketExePath)" + "$(PaketExePath)" $(PaketRootPath)paket.bootstrapper.exe $(PaketToolsPath)paket.bootstrapper.exe diff --git a/ROADMAP.md b/ROADMAP.md index e8e9c5c51..870590406 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -13,8 +13,6 @@ ## Ideas -* Consider allowing explicit static Xaml through a type provider, e.g `xaml<"""...""">`, evaluating to a `ViewElement` - * Performance: * Do better list comparison/diffing * Perf-test on large lists and do resulting perf work @@ -22,7 +20,7 @@ * Consider memoize function closure creation * Consider moving 'view' and 'model' computations off the UI thread -* Make some small F# langauge improvements to improve code: +* Make some small F# language improvements to improve code: * Remove `yield` in more cases * Automatically save function values that do not capture any arguments * Allow a default unnamed argument for `children` so the argument name doesn't have to be given explicitly @@ -35,9 +33,3 @@ ## Discarded Ideas * Possibly switch to a type provider (see [this comment](https://github.com/fsprojects/Fabulous/issues/50#issuecomment-390396365)) - - -## Bugs: - * Fix issue for slider where minimum = 1.0, maximum=10.0 (i.e. when value=0 and minimum gets set before maximum?) - - diff --git a/samples/AllControls/AllControls/AllControls.fs b/samples/AllControls/AllControls/AllControls.fs index 45b1aa5db..f2d369ad5 100644 --- a/samples/AllControls/AllControls/AllControls.fs +++ b/samples/AllControls/AllControls/AllControls.fs @@ -23,6 +23,8 @@ type Model = CountForSlider : int CountForActivityIndicator : int StepForSlider : int + MinimumForSlider : int + MaximumForSlider : int StartDate : System.DateTime EndDate : System.DateTime EditorText : string @@ -53,6 +55,8 @@ type Msg = | Reset | IncrementForSlider | DecrementForSlider + | ChangeMinimumMaximumForSlider1 + | ChangeMinimumMaximumForSlider2 | IncrementForActivityIndicator | DecrementForActivityIndicator | SliderValueChanged of int @@ -138,8 +142,10 @@ module App = { RootPageKind = Choice false Count = 0 CountForSlider = 0 - CountForActivityIndicator = 0 StepForSlider = 3 + MinimumForSlider = 0 + MaximumForSlider = 10 + CountForActivityIndicator = 0 PickedColorIndex = 0 EditorText = "hic hac hoc" Placeholder = "cogito ergo sum" @@ -167,6 +173,8 @@ module App = | Decrement -> { model with Count = model.Count - 1} | IncrementForSlider -> { model with CountForSlider = model.CountForSlider + model.StepForSlider } | DecrementForSlider -> { model with CountForSlider = model.CountForSlider - model.StepForSlider } + | ChangeMinimumMaximumForSlider1 -> { model with MinimumForSlider = 0; MaximumForSlider = 10 } + | ChangeMinimumMaximumForSlider2 -> { model with MinimumForSlider = 15; MaximumForSlider = 20 } | IncrementForActivityIndicator -> { model with CountForActivityIndicator = model.CountForActivityIndicator + 1 } | DecrementForActivityIndicator -> { model with CountForActivityIndicator = model.CountForActivityIndicator - 1 } | Reset -> init () @@ -422,7 +430,7 @@ module App = currentPage=model.Tabbed1CurrentPageIndex, children= [ - dependsOn (model.CountForSlider, model.StepForSlider) (fun model (count, step) -> + dependsOn (model.MinimumForSlider, model.MaximumForSlider, model.CountForSlider, model.StepForSlider) (fun model (minimum, maximum, count, step) -> View.ScrollingContentPage("Slider", [ View.Label(text="Label:") View.Label(text= sprintf "%d" count, horizontalOptions=LayoutOptions.CenterAndExpand) @@ -432,10 +440,13 @@ module App = View.Label(text="Button:") View.Button(text="Decrement", command=(fun () -> dispatch DecrementForSlider), horizontalOptions=LayoutOptions.CenterAndExpand) - - View.Label(text="Slider:") - View.Slider(minimum=0.0, - maximum=10.0, + + View.Label(text="Button:") + View.Button(text="Set Minimum = 0 / Maximum = 10", command=(fun () -> dispatch ChangeMinimumMaximumForSlider1), horizontalOptions=LayoutOptions.CenterAndExpand) + View.Button(text="Set Minimum = 15 / Maximum = 20", command=(fun () -> dispatch ChangeMinimumMaximumForSlider2), horizontalOptions=LayoutOptions.CenterAndExpand) + + View.Label(text=sprintf "Slider: (Minimum %d, Maximum %d, Value %d)" minimum maximum step) + View.Slider(minimumMaximum=(float minimum, float maximum), value=double step, valueChanged=(fun args -> dispatch (SliderValueChanged (int (args.NewValue + 0.5)))), horizontalOptions=LayoutOptions.Fill) diff --git a/samples/CounterApp/CounterApp/CounterApp.fs b/samples/CounterApp/CounterApp/CounterApp.fs index 0368d7bb0..e9102e014 100644 --- a/samples/CounterApp/CounterApp/CounterApp.fs +++ b/samples/CounterApp/CounterApp/CounterApp.fs @@ -159,7 +159,7 @@ module App = yield View.StackLayout(padding=20.0, orientation=StackOrientation.Horizontal, horizontalOptions=LayoutOptions.Center, children = [ View.Label(text="Timer") View.Switch(isToggled=model.TimerOn, toggled=(fun on -> dispatch (TimerToggled on.Value))) ]) - yield View.Slider(minimum=0.0, maximum=10.0, value= double model.Step, valueChanged=(fun args -> dispatch (SetStep (int (args.NewValue + 0.5))))) + yield View.Slider(minimumMaximum=(0.0, 10.0), value= double model.Step, valueChanged=(fun args -> dispatch (SetStep (int (args.NewValue + 0.5))))) yield View.Label(text=sprintf "Step size: %d" model.Step, horizontalOptions=LayoutOptions.Center) //if model <> initModel () then yield View.Button(text="Reset", horizontalOptions=LayoutOptions.Center, command=(fun () -> dispatch Reset), canExecute = (model <> initModel () )) diff --git a/src/Fabulous.Core/ViewConverters.fs b/src/Fabulous.Core/ViewConverters.fs index ae9f385a7..6393bf652 100644 --- a/src/Fabulous.Core/ViewConverters.fs +++ b/src/Fabulous.Core/ViewConverters.fs @@ -559,6 +559,42 @@ module Converters = | ValueSome _, ValueNone -> control.CurrentPage <- null | _, ValueSome curr -> control.CurrentPage <- control.Children.[curr] + let updateSliderMinimumMaximum prevValueOpt valueOpt (target: obj) = + let control = target :?> Xamarin.Forms.Slider + let defaultValue = (0.0, 1.0) + let updateFunc (prevMinimum, prevMaximum) (newMinimum, newMaximum) = + if newMinimum > prevMaximum then + control.Maximum <- newMaximum + control.Minimum <- newMinimum + else + control.Minimum <- newMinimum + control.Maximum <- newMaximum + + match prevValueOpt, valueOpt with + | ValueNone, ValueNone -> () + | ValueSome prev, ValueSome curr when prev = curr -> () + | ValueSome prev, ValueSome curr -> updateFunc prev curr + | ValueSome prev, ValueNone -> updateFunc prev defaultValue + | ValueNone, ValueSome curr -> updateFunc defaultValue curr + + let updateStepperMinimumMaximum prevValueOpt valueOpt (target: obj) = + let control = target :?> Xamarin.Forms.Stepper + let defaultValue = (0.0, 1.0) + let updateFunc (prevMinimum, prevMaximum) (newMinimum, newMaximum) = + if newMinimum > prevMaximum then + control.Maximum <- newMaximum + control.Minimum <- newMinimum + else + control.Minimum <- newMinimum + control.Maximum <- newMaximum + + match prevValueOpt, valueOpt with + | ValueNone, ValueNone -> () + | ValueSome prev, ValueSome curr when prev = curr -> () + | ValueSome prev, ValueSome curr -> updateFunc prev curr + | ValueSome prev, ValueNone -> updateFunc prev defaultValue + | ValueNone, ValueSome curr -> updateFunc defaultValue curr + let equalLayoutOptions (x:Xamarin.Forms.LayoutOptions) (y:Xamarin.Forms.LayoutOptions) = x.Alignment = y.Alignment && x.Expands = y.Expands diff --git a/src/Fabulous.Core/Xamarin.Forms.Core.fs b/src/Fabulous.Core/Xamarin.Forms.Core.fs index 7a427095f..86739c6a4 100644 --- a/src/Fabulous.Core/Xamarin.Forms.Core.fs +++ b/src/Fabulous.Core/Xamarin.Forms.Core.fs @@ -143,14 +143,16 @@ type View() = [] static member val _ButtonImageSourceAttribKey : AttributeKey<_> = AttributeKey<_>("ButtonImageSource") [] - static member val _MinimumAttribKey : AttributeKey<_> = AttributeKey<_>("Minimum") - [] - static member val _MaximumAttribKey : AttributeKey<_> = AttributeKey<_>("Maximum") + static member val _MinimumMaximumAttribKey : AttributeKey<_> = AttributeKey<_>("MinimumMaximum") [] static member val _ValueAttribKey : AttributeKey<_> = AttributeKey<_>("Value") [] static member val _ValueChangedAttribKey : AttributeKey<_> = AttributeKey<_>("ValueChanged") [] + static member val _MaximumAttribKey : AttributeKey<_> = AttributeKey<_>("Maximum") + [] + static member val _MinimumAttribKey : AttributeKey<_> = AttributeKey<_>("Minimum") + [] static member val _IncrementAttribKey : AttributeKey<_> = AttributeKey<_>("Increment") [] static member val _IsToggledAttribKey : AttributeKey<_> = AttributeKey<_>("IsToggled") @@ -2976,8 +2978,7 @@ type View() = /// Builds the attributes for a Slider in the view [] static member inline BuildSlider(attribCount: int, - ?minimum: double, - ?maximum: double, + ?minimumMaximum: float * float, ?value: double, ?valueChanged: Xamarin.Forms.ValueChangedEventArgs -> unit, ?horizontalOptions: Xamarin.Forms.LayoutOptions, @@ -3012,14 +3013,12 @@ type View() = ?created: obj -> unit, ?ref: ViewRef) = - let attribCount = match minimum with Some _ -> attribCount + 1 | None -> attribCount - let attribCount = match maximum with Some _ -> attribCount + 1 | None -> attribCount + let attribCount = match minimumMaximum with Some _ -> attribCount + 1 | None -> attribCount let attribCount = match value with Some _ -> attribCount + 1 | None -> attribCount let attribCount = match valueChanged with Some _ -> attribCount + 1 | None -> attribCount let attribBuilder = View.BuildView(attribCount, ?horizontalOptions=horizontalOptions, ?verticalOptions=verticalOptions, ?margin=margin, ?gestureRecognizers=gestureRecognizers, ?anchorX=anchorX, ?anchorY=anchorY, ?backgroundColor=backgroundColor, ?heightRequest=heightRequest, ?inputTransparent=inputTransparent, ?isEnabled=isEnabled, ?isVisible=isVisible, ?minimumHeightRequest=minimumHeightRequest, ?minimumWidthRequest=minimumWidthRequest, ?opacity=opacity, ?rotation=rotation, ?rotationX=rotationX, ?rotationY=rotationY, ?scale=scale, ?style=style, ?styleClass=styleClass, ?translationX=translationX, ?translationY=translationY, ?widthRequest=widthRequest, ?resources=resources, ?styles=styles, ?styleSheets=styleSheets, ?classId=classId, ?styleId=styleId, ?automationId=automationId, ?created=created, ?ref=ref) - match minimum with None -> () | Some v -> attribBuilder.Add(View._MinimumAttribKey, (v)) - match maximum with None -> () | Some v -> attribBuilder.Add(View._MaximumAttribKey, (v)) + match minimumMaximum with None -> () | Some v -> attribBuilder.Add(View._MinimumMaximumAttribKey, (v)) match value with None -> () | Some v -> attribBuilder.Add(View._ValueAttribKey, (v)) match valueChanged with None -> () | Some v -> attribBuilder.Add(View._ValueChangedAttribKey, (fun f -> System.EventHandler(fun _sender args -> f args))(v)) attribBuilder @@ -3039,19 +3038,15 @@ type View() = // update the inherited View element let baseElement = (if View.ProtoView.IsNone then View.ProtoView <- Some (View.View())); View.ProtoView.Value baseElement.UpdateInherited (prevOpt, curr, target) - let mutable prevMinimumOpt = ValueNone - let mutable currMinimumOpt = ValueNone - let mutable prevMaximumOpt = ValueNone - let mutable currMaximumOpt = ValueNone + let mutable prevMinimumMaximumOpt = ValueNone + let mutable currMinimumMaximumOpt = ValueNone let mutable prevValueOpt = ValueNone let mutable currValueOpt = ValueNone let mutable prevValueChangedOpt = ValueNone let mutable currValueChangedOpt = ValueNone for kvp in curr.AttributesKeyed do - if kvp.Key = View._MinimumAttribKey.KeyValue then - currMinimumOpt <- ValueSome (kvp.Value :?> double) - if kvp.Key = View._MaximumAttribKey.KeyValue then - currMaximumOpt <- ValueSome (kvp.Value :?> double) + if kvp.Key = View._MinimumMaximumAttribKey.KeyValue then + currMinimumMaximumOpt <- ValueSome (kvp.Value :?> float * float) if kvp.Key = View._ValueAttribKey.KeyValue then currValueOpt <- ValueSome (kvp.Value :?> double) if kvp.Key = View._ValueChangedAttribKey.KeyValue then @@ -3060,24 +3055,13 @@ type View() = | ValueNone -> () | ValueSome prev -> for kvp in prev.AttributesKeyed do - if kvp.Key = View._MinimumAttribKey.KeyValue then - prevMinimumOpt <- ValueSome (kvp.Value :?> double) - if kvp.Key = View._MaximumAttribKey.KeyValue then - prevMaximumOpt <- ValueSome (kvp.Value :?> double) + if kvp.Key = View._MinimumMaximumAttribKey.KeyValue then + prevMinimumMaximumOpt <- ValueSome (kvp.Value :?> float * float) if kvp.Key = View._ValueAttribKey.KeyValue then prevValueOpt <- ValueSome (kvp.Value :?> double) if kvp.Key = View._ValueChangedAttribKey.KeyValue then prevValueChangedOpt <- ValueSome (kvp.Value :?> System.EventHandler) - match prevMinimumOpt, currMinimumOpt with - | ValueSome prevValue, ValueSome currValue when prevValue = currValue -> () - | _, ValueSome currValue -> target.Minimum <- currValue - | ValueSome _, ValueNone -> target.Minimum <- 0.0 - | ValueNone, ValueNone -> () - match prevMaximumOpt, currMaximumOpt with - | ValueSome prevValue, ValueSome currValue when prevValue = currValue -> () - | _, ValueSome currValue -> target.Maximum <- currValue - | ValueSome _, ValueNone -> target.Maximum <- 1.0 - | ValueNone, ValueNone -> () + updateSliderMinimumMaximum prevMinimumMaximumOpt currMinimumMaximumOpt target match prevValueOpt, currValueOpt with | ValueSome prevValue, ValueSome currValue when prevValue = currValue -> () | _, ValueSome currValue -> target.Value <- currValue @@ -3091,8 +3075,7 @@ type View() = | ValueNone, ValueNone -> () /// Describes a Slider in the view - static member inline Slider(?minimum: double, - ?maximum: double, + static member inline Slider(?minimumMaximum: float * float, ?value: double, ?valueChanged: Xamarin.Forms.ValueChangedEventArgs -> unit, ?horizontalOptions: Xamarin.Forms.LayoutOptions, @@ -3128,8 +3111,7 @@ type View() = ?ref: ViewRef) = let attribBuilder = View.BuildSlider(0, - ?minimum=minimum, - ?maximum=maximum, + ?minimumMaximum=minimumMaximum, ?value=value, ?valueChanged=valueChanged, ?horizontalOptions=horizontalOptions, @@ -3172,8 +3154,8 @@ type View() = /// Builds the attributes for a Stepper in the view [] static member inline BuildStepper(attribCount: int, - ?minimum: double, ?maximum: double, + ?minimum: double, ?value: double, ?increment: double, ?valueChanged: Xamarin.Forms.ValueChangedEventArgs -> unit, @@ -3209,15 +3191,15 @@ type View() = ?created: obj -> unit, ?ref: ViewRef) = - let attribCount = match minimum with Some _ -> attribCount + 1 | None -> attribCount let attribCount = match maximum with Some _ -> attribCount + 1 | None -> attribCount + let attribCount = match minimum with Some _ -> attribCount + 1 | None -> attribCount let attribCount = match value with Some _ -> attribCount + 1 | None -> attribCount let attribCount = match increment with Some _ -> attribCount + 1 | None -> attribCount let attribCount = match valueChanged with Some _ -> attribCount + 1 | None -> attribCount let attribBuilder = View.BuildView(attribCount, ?horizontalOptions=horizontalOptions, ?verticalOptions=verticalOptions, ?margin=margin, ?gestureRecognizers=gestureRecognizers, ?anchorX=anchorX, ?anchorY=anchorY, ?backgroundColor=backgroundColor, ?heightRequest=heightRequest, ?inputTransparent=inputTransparent, ?isEnabled=isEnabled, ?isVisible=isVisible, ?minimumHeightRequest=minimumHeightRequest, ?minimumWidthRequest=minimumWidthRequest, ?opacity=opacity, ?rotation=rotation, ?rotationX=rotationX, ?rotationY=rotationY, ?scale=scale, ?style=style, ?styleClass=styleClass, ?translationX=translationX, ?translationY=translationY, ?widthRequest=widthRequest, ?resources=resources, ?styles=styles, ?styleSheets=styleSheets, ?classId=classId, ?styleId=styleId, ?automationId=automationId, ?created=created, ?ref=ref) - match minimum with None -> () | Some v -> attribBuilder.Add(View._MinimumAttribKey, (v)) match maximum with None -> () | Some v -> attribBuilder.Add(View._MaximumAttribKey, (v)) + match minimum with None -> () | Some v -> attribBuilder.Add(View._MinimumAttribKey, (v)) match value with None -> () | Some v -> attribBuilder.Add(View._ValueAttribKey, (v)) match increment with None -> () | Some v -> attribBuilder.Add(View._IncrementAttribKey, (v)) match valueChanged with None -> () | Some v -> attribBuilder.Add(View._ValueChangedAttribKey, (fun f -> System.EventHandler(fun _sender args -> f args))(v)) @@ -3238,10 +3220,10 @@ type View() = // update the inherited View element let baseElement = (if View.ProtoView.IsNone then View.ProtoView <- Some (View.View())); View.ProtoView.Value baseElement.UpdateInherited (prevOpt, curr, target) - let mutable prevMinimumOpt = ValueNone - let mutable currMinimumOpt = ValueNone let mutable prevMaximumOpt = ValueNone let mutable currMaximumOpt = ValueNone + let mutable prevMinimumOpt = ValueNone + let mutable currMinimumOpt = ValueNone let mutable prevValueOpt = ValueNone let mutable currValueOpt = ValueNone let mutable prevIncrementOpt = ValueNone @@ -3249,10 +3231,10 @@ type View() = let mutable prevValueChangedOpt = ValueNone let mutable currValueChangedOpt = ValueNone for kvp in curr.AttributesKeyed do - if kvp.Key = View._MinimumAttribKey.KeyValue then - currMinimumOpt <- ValueSome (kvp.Value :?> double) if kvp.Key = View._MaximumAttribKey.KeyValue then currMaximumOpt <- ValueSome (kvp.Value :?> double) + if kvp.Key = View._MinimumAttribKey.KeyValue then + currMinimumOpt <- ValueSome (kvp.Value :?> double) if kvp.Key = View._ValueAttribKey.KeyValue then currValueOpt <- ValueSome (kvp.Value :?> double) if kvp.Key = View._IncrementAttribKey.KeyValue then @@ -3263,26 +3245,26 @@ type View() = | ValueNone -> () | ValueSome prev -> for kvp in prev.AttributesKeyed do - if kvp.Key = View._MinimumAttribKey.KeyValue then - prevMinimumOpt <- ValueSome (kvp.Value :?> double) if kvp.Key = View._MaximumAttribKey.KeyValue then prevMaximumOpt <- ValueSome (kvp.Value :?> double) + if kvp.Key = View._MinimumAttribKey.KeyValue then + prevMinimumOpt <- ValueSome (kvp.Value :?> double) if kvp.Key = View._ValueAttribKey.KeyValue then prevValueOpt <- ValueSome (kvp.Value :?> double) if kvp.Key = View._IncrementAttribKey.KeyValue then prevIncrementOpt <- ValueSome (kvp.Value :?> double) if kvp.Key = View._ValueChangedAttribKey.KeyValue then prevValueChangedOpt <- ValueSome (kvp.Value :?> System.EventHandler) - match prevMinimumOpt, currMinimumOpt with - | ValueSome prevValue, ValueSome currValue when prevValue = currValue -> () - | _, ValueSome currValue -> target.Minimum <- currValue - | ValueSome _, ValueNone -> target.Minimum <- 0.0 - | ValueNone, ValueNone -> () match prevMaximumOpt, currMaximumOpt with | ValueSome prevValue, ValueSome currValue when prevValue = currValue -> () | _, ValueSome currValue -> target.Maximum <- currValue | ValueSome _, ValueNone -> target.Maximum <- 1.0 | ValueNone, ValueNone -> () + match prevMinimumOpt, currMinimumOpt with + | ValueSome prevValue, ValueSome currValue when prevValue = currValue -> () + | _, ValueSome currValue -> target.Minimum <- currValue + | ValueSome _, ValueNone -> target.Minimum <- 0.0 + | ValueNone, ValueNone -> () match prevValueOpt, currValueOpt with | ValueSome prevValue, ValueSome currValue when prevValue = currValue -> () | _, ValueSome currValue -> target.Value <- currValue @@ -3301,8 +3283,8 @@ type View() = | ValueNone, ValueNone -> () /// Describes a Stepper in the view - static member inline Stepper(?minimum: double, - ?maximum: double, + static member inline Stepper(?maximum: double, + ?minimum: double, ?value: double, ?increment: double, ?valueChanged: Xamarin.Forms.ValueChangedEventArgs -> unit, @@ -3339,8 +3321,8 @@ type View() = ?ref: ViewRef) = let attribBuilder = View.BuildStepper(0, - ?minimum=minimum, ?maximum=maximum, + ?minimum=minimum, ?value=value, ?increment=increment, ?valueChanged=valueChanged, @@ -11059,11 +11041,8 @@ module ViewElementExtensions = /// Adjusts the ButtonImageSource property in the visual element member x.ButtonImageSource(value: string) = x.WithAttribute(View._ButtonImageSourceAttribKey, (value)) - /// Adjusts the Minimum property in the visual element - member x.Minimum(value: double) = x.WithAttribute(View._MinimumAttribKey, (value)) - - /// Adjusts the Maximum property in the visual element - member x.Maximum(value: double) = x.WithAttribute(View._MaximumAttribKey, (value)) + /// Adjusts the MinimumMaximum property in the visual element + member x.MinimumMaximum(value: float * float) = x.WithAttribute(View._MinimumMaximumAttribKey, (value)) /// Adjusts the Value property in the visual element member x.Value(value: double) = x.WithAttribute(View._ValueAttribKey, (value)) @@ -11071,6 +11050,12 @@ module ViewElementExtensions = /// Adjusts the ValueChanged property in the visual element member x.ValueChanged(value: Xamarin.Forms.ValueChangedEventArgs -> unit) = x.WithAttribute(View._ValueChangedAttribKey, (fun f -> System.EventHandler(fun _sender args -> f args))(value)) + /// Adjusts the Maximum property in the visual element + member x.Maximum(value: double) = x.WithAttribute(View._MaximumAttribKey, (value)) + + /// Adjusts the Minimum property in the visual element + member x.Minimum(value: double) = x.WithAttribute(View._MinimumAttribKey, (value)) + /// Adjusts the Increment property in the visual element member x.Increment(value: double) = x.WithAttribute(View._IncrementAttribKey, (value)) @@ -11690,11 +11675,8 @@ module ViewElementExtensions = /// Adjusts the ButtonImageSource property in the visual element let buttonImageSource (value: string) (x: ViewElement) = x.ButtonImageSource(value) - /// Adjusts the Minimum property in the visual element - let minimum (value: double) (x: ViewElement) = x.Minimum(value) - - /// Adjusts the Maximum property in the visual element - let maximum (value: double) (x: ViewElement) = x.Maximum(value) + /// Adjusts the MinimumMaximum property in the visual element + let minimumMaximum (value: float * float) (x: ViewElement) = x.MinimumMaximum(value) /// Adjusts the Value property in the visual element let value (value: double) (x: ViewElement) = x.Value(value) @@ -11702,6 +11684,12 @@ module ViewElementExtensions = /// Adjusts the ValueChanged property in the visual element let valueChanged (value: Xamarin.Forms.ValueChangedEventArgs -> unit) (x: ViewElement) = x.ValueChanged(value) + /// Adjusts the Maximum property in the visual element + let maximum (value: double) (x: ViewElement) = x.Maximum(value) + + /// Adjusts the Minimum property in the visual element + let minimum (value: double) (x: ViewElement) = x.Minimum(value) + /// Adjusts the Increment property in the visual element let increment (value: double) (x: ViewElement) = x.Increment(value) diff --git a/templates/content/blank/NewApp/NewApp.fs b/templates/content/blank/NewApp/NewApp.fs index 4a403c891..fc43990de 100644 --- a/templates/content/blank/NewApp/NewApp.fs +++ b/templates/content/blank/NewApp/NewApp.fs @@ -51,7 +51,7 @@ module App = View.Button(text = "Decrement", command = (fun () -> dispatch Decrement), horizontalOptions = LayoutOptions.Center) View.Label(text = "Timer", horizontalOptions = LayoutOptions.Center) View.Switch(isToggled = model.TimerOn, toggled = (fun on -> dispatch (TimerToggled on.Value)), horizontalOptions = LayoutOptions.Center) - View.Slider(minimum = 0.0, maximum = 10.0, value = double model.Step, valueChanged = (fun args -> dispatch (SetStep (int (args.NewValue + 0.5)))), horizontalOptions = LayoutOptions.FillAndExpand) + View.Slider(minimumMaximum = (0.0, 10.0), value = double model.Step, valueChanged = (fun args -> dispatch (SetStep (int (args.NewValue + 0.5)))), horizontalOptions = LayoutOptions.FillAndExpand) View.Label(text = sprintf "Step size: %d" model.Step, horizontalOptions = LayoutOptions.Center) View.Button(text = "Reset", horizontalOptions = LayoutOptions.Center, command = (fun () -> dispatch Reset), canExecute = (model <> initModel)) ])) diff --git a/tools/Generator/Xamarin.Forms.Core.json b/tools/Generator/Xamarin.Forms.Core.json index e2a4935d4..460e5da38 100644 --- a/tools/Generator/Xamarin.Forms.Core.json +++ b/tools/Generator/Xamarin.Forms.Core.json @@ -444,14 +444,12 @@ { "name": "Xamarin.Forms.Slider", "members": [ - // ugh, beware the order these are set. setting minimum before maximum throws an exception.... { - "name": "Minimum", - "defaultValue": "0.0" - }, - { - "name": "Maximum", - "defaultValue": "1.0" + "name": "MinimumMaximum", + "inputType": "float * float", + "modelType": "float * float", + "defaultValue": "(0.0, 1.0)", + "updateCode": "updateSliderMinimumMaximum" }, { "name": "Value", @@ -468,14 +466,12 @@ { "name": "Xamarin.Forms.Stepper", "members": [ - // ugh, beware the order these are set. setting minimum before maximum throws an exception.... { - "name": "Minimum", - "defaultValue": "0.0" - }, - { - "name": "Maximum", - "defaultValue": "1.0" + "name": "MinimumMaximum", + "inputType": "float * float", + "modelType": "float * float", + "defaultValue": "(0.0, 1.0)", + "updateCode": "updateStepperMinimumMaximum" }, { "name": "Value",