diff --git a/.editorconfig b/.editorconfig
index c8b73b2d84..ed21eef370 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -27,14 +27,24 @@ csharp_style_var_elsewhere = true:none
# ReSharper properties
resharper_align_linq_query = true
+resharper_align_multiline_binary_patterns = true
resharper_align_multiline_calls_chain = true
resharper_align_multiline_extends_list = true
resharper_align_multiline_parameter = true
resharper_blank_lines_around_region = 1
resharper_braces_redundant = true
+resharper_csharp_alignment_tab_fill_style = optimal_fill
+resharper_csharp_max_line_length = 200
resharper_csharp_stick_comment = false
+resharper_csharp_wrap_parameters_style = chop_if_long
resharper_force_attribute_style = separate
resharper_indent_type_constraints = true
+#resharper_int_align_binary_expressions = true
+resharper_int_align_comments = true
+resharper_int_align_invocations = true
+resharper_int_align_nested_ternary = true
+resharper_int_align_switch_expressions = true
+resharper_int_align_switch_sections = true
resharper_local_function_body = expression_body
resharper_remove_blank_lines_near_braces_in_declarations = true
resharper_use_roslyn_logic_for_evident_types = true
@@ -82,7 +92,19 @@ csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_prefer_not_pattern = true:suggestion
csharp_style_prefer_extended_property_pattern = true:suggestion
-csharp_style_var_for_built_in_types = false:silent
+csharp_style_var_for_built_in_types = true:none
+resharper_wrap_before_linq_expression = true
+resharper_wrap_chained_binary_expressions = chop_if_long
+resharper_wrap_chained_binary_patterns = chop_if_long
+resharper_xmldoc_indent_size = 2
+resharper_xmldoc_indent_style = space
+resharper_xmldoc_indent_text = DoNotTouch
+resharper_xmldoc_linebreaks_inside_tags_for_elements_longer_than = 120
+resharper_xmldoc_max_blank_lines_between_tags = 1
+resharper_xmldoc_max_line_length = 100
+resharper_xmldoc_space_before_self_closing = false
+resharper_xmldoc_tab_width = 2
+resharper_xmldoc_use_indent_from_vs = true
[*.{cs,vb}]
dotnet_style_operator_placement_when_wrapping = beginning_of_line
diff --git a/Terminal.Gui/View/ViewDrawing.cs b/Terminal.Gui/View/ViewDrawing.cs
index f622d80e37..94d8cad846 100644
--- a/Terminal.Gui/View/ViewDrawing.cs
+++ b/Terminal.Gui/View/ViewDrawing.cs
@@ -291,12 +291,12 @@ public void DrawHotString (string text, bool focused, ColorScheme scheme)
/// the row to move to, in view-relative coordinates.
public void Move (int col, int row)
{
- if (Driver.Rows == 0) {
+ if (Driver == null || Driver?.Rows == 0) {
return;
}
BoundsToScreen (col, row, out int rCol, out int rRow, false);
- Driver.Move (rCol, rRow);
+ Driver?.Move (rCol, rRow);
}
///
diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs
index 0280f5b307..21fb8a2695 100644
--- a/Terminal.Gui/Views/Slider.cs
+++ b/Terminal.Gui/Views/Slider.cs
@@ -1,10 +1,7 @@
-using Microsoft.VisualBasic.FileIO;
-using System;
+using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Text;
-using Unix.Terminal;
namespace Terminal.Gui;
@@ -13,48 +10,26 @@ namespace Terminal.Gui;
///
public class SliderOptionEventArgs : EventArgs {
///
- /// Gets whether the option is set or not.
+ /// Initializes a new instance of
///
- public bool IsSet { get; }
-
+ /// indicates whether the option is set
+ public SliderOptionEventArgs (bool isSet) => IsSet = isSet;
///
- /// Initializes a new instance of
+ /// Gets whether the option is set or not.
///
- /// indicates whether the option is set
- public SliderOptionEventArgs (bool isSet)
- {
- IsSet = isSet;
- }
+ public bool IsSet { get; }
}
///
/// Represents an option in a .
///
-/// Datatype of the option.
+/// Data type of the option.
public class SliderOption {
- ///
- /// Legend of the option.
- ///
- public string Legend { get; set; }
-
- ///
- /// Abbreviation of the Legend. When the too small to fit .
- ///
- public Rune LegendAbbr { get; set; }
-
- ///
- /// Custom data of the option.
- ///
- public T Data { get; set; }
-
///
/// Creates a new empty instance of the class.
///
- public SliderOption ()
- {
-
- }
+ public SliderOption () { }
///
/// Creates a new instance of the class with values for
@@ -67,29 +42,36 @@ public SliderOption (string legend, Rune legendAbbr, T data)
Data = data;
}
+ ///
+ /// Legend of the option.
+ ///
+ public string Legend { get; set; }
+
+ ///
+ /// Abbreviation of the Legend. When the too small to fit
+ /// .
+ ///
+ public Rune LegendAbbr { get; set; }
+
+ ///
+ /// Custom data of the option.
+ ///
+ public T Data { get; set; }
+
///
/// To Raise the event from the Slider.
///
- internal void OnSet ()
- {
- Set?.Invoke (this, new SliderOptionEventArgs (true));
- }
+ internal void OnSet () => Set?.Invoke (this, new SliderOptionEventArgs (true));
///
/// To Raise the event from the Slider.
///
- internal void OnUnSet ()
- {
- UnSet?.Invoke (this, new SliderOptionEventArgs (false));
- }
+ internal void OnUnSet () => UnSet?.Invoke (this, new SliderOptionEventArgs (false));
///
/// To Raise the event from the Slider.
///
- internal void OnChanged (bool isSet)
- {
- Changed?.Invoke (this, new SliderOptionEventArgs (isSet));
- }
+ internal void OnChanged (bool isSet) => Changed?.Invoke (this, new SliderOptionEventArgs (isSet));
///
/// Event Raised when this option is set.
@@ -109,8 +91,7 @@ internal void OnChanged (bool isSet)
///
/// Creates a human-readable string that represents this .
///
- public override string ToString () => "{Legend=" + Legend + ", LegendAbbr=" + LegendAbbr.ToString () + ", Data=" + Data?.ToString () + "}";
-
+ public override string ToString () => "{Legend=" + Legend + ", LegendAbbr=" + LegendAbbr + ", Data=" + Data + "}";
}
///
@@ -118,31 +99,35 @@ internal void OnChanged (bool isSet)
///
public enum SliderType {
///
- ///
+ ///
/// ├─┼─┼─┼─┼─█─┼─┼─┼─┼─┼─┼─┤
///
///
Single,
+
///
- ///
+ ///
/// ├─┼─█─┼─┼─█─┼─┼─┼─┼─█─┼─┤
///
///
Multiple,
+
///
- ///
+ ///
/// ├▒▒▒▒▒▒▒▒▒█─┼─┼─┼─┼─┼─┼─┤
///
///
LeftRange,
+
///
- ///
+ ///
/// ├─┼─┼─┼─┼─█▒▒▒▒▒▒▒▒▒▒▒▒▒┤
///
///
RightRange,
+
///
- ///
+ ///
/// ├─┼─┼─┼─┼─█▒▒▒▒▒▒▒█─┼─┼─┤
///
///
@@ -157,10 +142,12 @@ public class SliderAttributes {
/// Attribute for when the respective Option is NOT Set.
///
public Attribute? NormalAttribute { get; set; }
+
///
/// Attribute for when the respective Option is Set.
///
public Attribute? SetAttribute { get; set; }
+
///
/// Attribute for the Legends Container.
///
@@ -171,80 +158,95 @@ public class SliderAttributes {
/// Style
///
public class SliderStyle {
+ ///
+ /// Constructs a new instance.
+ ///
+ public SliderStyle () => LegendAttributes = new SliderAttributes ();
+
///
/// Legend attributes
///
public SliderAttributes LegendAttributes { get; set; }
+
///
/// The glyph and the attribute used for empty spaces on the slider.
///
public Cell EmptyChar { get; set; }
+
///
/// The glyph and the attribute used for each option (tick) on the slider.
///
public Cell OptionChar { get; set; }
+
///
/// The glyph and the attribute used for options (ticks) that are set on the slider.
///
public Cell SetChar { get; set; }
+
///
/// The glyph and the attribute to indicate mouse dragging.
///
public Cell DragChar { get; set; }
+
///
/// The glyph and the attribute used for spaces between options (ticks) on the slider.
///
public Cell SpaceChar { get; set; }
+
///
/// The glyph and the attribute used for filling in ranges on the slider.
///
public Cell RangeChar { get; set; }
+
///
/// The glyph and the attribute used for the start of ranges on the slider.
///
public Cell StartRangeChar { get; set; }
+
///
/// The glyph and the attribute used for the end of ranges on the slider.
///
public Cell EndRangeChar { get; set; }
-
- ///
- /// Constructs a new instance.
- ///
- public SliderStyle ()
- {
- LegendAttributes = new SliderAttributes { };
- }
}
///
/// All configuration are grouped in this class.
///
-internal class SliderConfiguration {
- internal bool _rangeAllowSingle;
+class SliderConfiguration {
internal bool _allowEmpty;
- internal int _mouseClickXOptionThreshold;
-
internal bool _autoSize;
-
- internal int _startSpacing;
internal int _endSpacing;
internal int _innerSpacing;
+ internal Orientation _legendsOrientation = Orientation.Horizontal;
+ internal bool _rangeAllowSingle;
- internal bool _showSpacing;
+ internal bool _showEndSpacing;
internal bool _showLegends;
internal bool _showLegendsAbbr;
+ internal Orientation _sliderOrientation = Orientation.Horizontal;
+
+ internal int _startSpacing;
internal SliderType _type = SliderType.Single;
- internal Orientation _sliderOrientation = Orientation.Horizontal;
- internal Orientation _legendsOrientation = Orientation.Horizontal;
}
///
/// for events.
///
public class SliderEventArgs : EventArgs {
+ ///
+ /// Initializes a new instance of
+ ///
+ /// The current options.
+ /// Index of the option that is focused. -1 if no option has the focus.
+ public SliderEventArgs (Dictionary> options, int focused = -1)
+ {
+ Options = options;
+ Focused = focused;
+ Cancel = false;
+ }
+
///
/// Gets/sets whether the option is set or not.
///
@@ -259,24 +261,22 @@ public class SliderEventArgs : EventArgs {
/// If set to true, the focus operation will be canceled, if applicable.
///
public bool Cancel { get; set; }
+}
+///
+/// for events.
+///
+public class OrientationEventArgs : EventArgs {
///
- /// Initializes a new instance of
+ /// Constructs a new instance.
///
- /// The current options.
- /// Index of the option that is focused. -1 if no option has the focus.
- public SliderEventArgs (Dictionary> options, int focused = -1)
+ /// the new orientation
+ public OrientationEventArgs (Orientation orientation)
{
- Options = options;
- Focused = focused;
+ Orientation = orientation;
Cancel = false;
}
-}
-///
-/// for events.
-///
-public class OrientationEventArgs : EventArgs {
///
/// The new orientation.
///
@@ -286,26 +286,16 @@ public class OrientationEventArgs : EventArgs {
/// If set to true, the orientation change operation will be canceled, if applicable.
///
public bool Cancel { get; set; }
-
- ///
- /// Constructs a new instance.
- ///
- /// the new orientation
- public OrientationEventArgs (Orientation orientation)
- {
- Orientation = orientation;
- Cancel = false;
- }
}
+
///
/// Slider control.
///
public class Slider : Slider {
-
///
/// Initializes a new instance of the class.
///
- public Slider () : base () { }
+ public Slider () { }
///
/// Initializes a new instance of the class.
@@ -316,25 +306,57 @@ public Slider (List options, Orientation orientation = Orientation.Horiz
}
///
-/// Provides a slider control letting the user navigate from a set of typed options in a linear manner using the keyboard or mouse.
+/// Provides a slider control letting the user navigate from a set of typed options in a linear manner
+/// using the keyboard or mouse.
///
///
public class Slider : View {
- SliderConfiguration _config = new SliderConfiguration ();
- SliderStyle _style = new SliderStyle ();
+ readonly SliderConfiguration _config = new ();
+
+ // List of the current set options.
+ readonly List _setOptions = new ();
// Options
List> _options;
- // List of the current set options.
- List _setOptions = new List ();
///
- /// The focused option (has the cursor).
+ /// The focused option (has the cursor).
///
public int FocusedOption { get; set; }
- #region Events
+ #region Initialize
+ void SetInitialProperties (List> options, Orientation orientation = Orientation.Horizontal)
+ {
+ CanFocus = true;
+
+ _options = options ?? new List> ();
+
+ _config._sliderOrientation = orientation;
+
+ _config._showLegends = true;
+
+ SetDefaultStyle ();
+ SetCommands ();
+
+ // When we lose focus of the View(Slider), if we are range selecting we stop it.
+ Leave += (s, e) => {
+ //if (_settingRange == true) {
+ // _settingRange = false;
+ //}
+ Driver.SetCursorVisibility (CursorVisibility.Invisible);
+ };
+
+
+ Enter += (s, e) => { };
+
+ LayoutComplete += (s, e) => {
+ CalcSpacingConfig ();
+ SetBoundsBestFit ();
+ };
+ }
+ #endregion
+ #region Events
///
/// Event raised when the slider option/s changed.
/// The dictionary contains: key = option index, value = T
@@ -342,7 +364,8 @@ public class Slider : View {
public event EventHandler> OptionsChanged;
///
- /// Overridable method called when the slider options have changed. Raises the event.
+ /// Overridable method called when the slider options have changed. Raises the
+ /// event.
///
public virtual void OnOptionsChanged ()
{
@@ -376,17 +399,13 @@ public virtual bool OnOptionFocused (int newFocusedOption, SliderEventArgs ar
}
return args.Cancel;
}
-
#endregion
#region Constructors
-
///
/// Initializes a new instance of the class.
///
- public Slider () : this (new List ())
- {
- }
+ public Slider () : this (new List ()) { }
///
/// Initializes a new instance of the class.
@@ -403,50 +422,14 @@ public Slider (List options, Orientation orientation = Orientation.Horizontal
return new SliderOption {
Data = e,
Legend = legend,
- LegendAbbr = (Rune)(legend?.Length > 0 ? legend [0] : ' '),
+ LegendAbbr = (Rune)(legend?.Length > 0 ? legend [0] : ' ')
};
}).ToList (), orientation);
}
}
-
- #endregion
-
- #region Initialize
- void SetInitialProperties (List> options, Orientation orientation = Orientation.Horizontal)
- {
- CanFocus = true;
-
- this._options = options ?? new List> ();
-
- _config._sliderOrientation = orientation;
-
- _config._showLegends = true;
-
- SetDefaultStyle ();
- SetCommands ();
-
- // When we lose focus of the View(Slider), if we are range selecting we stop it.
- Leave += (object s, FocusEventArgs e) => {
- //if (_settingRange == true) {
- // _settingRange = false;
- //}
- Driver.SetCursorVisibility (CursorVisibility.Invisible);
- };
-
-
- Enter += (object s, FocusEventArgs e) => {
- };
-
- LayoutComplete += (s, e) => {
- CalcSpacingConfig ();
- AdjustBestHeight ();
- AdjustBestWidth ();
- };
- }
#endregion
#region Properties
-
///
/// Allow no selection.
///
@@ -461,29 +444,38 @@ public bool AllowEmpty {
}
///
- /// If the slider will be sized to fit the available space (the Bounds of the the SuperView).
+ /// If the slider will be sized to fit the available space (the Bounds of the
+ /// the SuperView).
///
///
- /// For testing, if there is no SuperView, the slider will be sized based on what is
+ /// For testing, if there is no SuperView, the slider will be sized based on what
+ /// is
/// set to.
///
public override bool AutoSize {
get => _config._autoSize;
- set => _config._autoSize = value;
+ set {
+ _config._autoSize = value;
+ if (IsInitialized) {
+ CalcSpacingConfig ();
+ SetBoundsBestFit ();
+
+ }
+ }
}
///
/// Gets or sets the number of rows/columns between
///
public int InnerSpacing {
-
get => _config._innerSpacing;
set {
_config._innerSpacing = value;
- CalcSpacingConfig ();
- Adjust ();
- SetNeedsDisplay ();
- SuperView?.SetNeedsLayout ();
+ if (IsInitialized) {
+ CalcSpacingConfig ();
+ SetBoundsBestFit ();
+
+ }
}
}
@@ -497,7 +489,6 @@ public SliderType Type {
// Todo: Custom logic to preserve options.
_setOptions.Clear ();
-
SetNeedsDisplay ();
}
}
@@ -511,7 +502,8 @@ public Orientation Orientation {
}
///
- /// Fired when the slider orientation has changed. Can be cancelled by setting to true.
+ /// Fired when the slider orientation has changed. Can be cancelled by setting
+ /// to true.
///
public event EventHandler OrientationChanged;
@@ -529,9 +521,8 @@ public virtual bool OnOrientationChanged (Orientation newOrientation)
SetKeyBindings ();
if (IsInitialized) {
CalcSpacingConfig ();
- Adjust ();
- SetNeedsDisplay ();
- SuperView?.SetNeedsLayout ();
+ SetBoundsBestFit ();
+
}
}
return args.Cancel;
@@ -544,10 +535,11 @@ public Orientation LegendsOrientation {
get => _config._legendsOrientation;
set {
_config._legendsOrientation = value;
- CalcSpacingConfig ();
- Adjust ();
- SetNeedsDisplay ();
- SuperView?.SetNeedsLayout ();
+ if (IsInitialized) {
+ CalcSpacingConfig ();
+ SetBoundsBestFit ();
+
+ }
}
}
@@ -555,38 +547,31 @@ public Orientation LegendsOrientation {
/// Slider styles.
///
public SliderStyle Style {
- get {
- // Note(jmperricone): Maybe SliderStyle should be a struct so we return a copy ???
- // Or SetStyle() and ( GetStyle() || Style getter copy )
- return _style;
- }
- set {
- // Note(jmperricone): If the user change a style, he/she must call SetNeedsDisplay(). OK ???
- _style = value;
- }
- }
+ // Note(jmperricone): Maybe SliderStyle should be a struct so we return a copy ???
+ // Or SetStyle() and ( GetStyle() || Style getter copy )
+ get;
+ set;
+ } = new ();
///
/// Set the slider options.
///
public List> Options {
- get {
+ get =>
// Note(jmperricone): Maybe SliderOption should be a struct so we return a copy ???
// Events will be preserved ? Need a test.
// Or SetOptions() and ( GetOptions() || Options getter copy )
- return _options;
- }
+ _options;
set {
- _options = value;
+ // _options should never be null
+ _options = value ?? throw new ArgumentNullException (nameof (value));
- if (_options == null || _options.Count == 0) {
+ if (!IsInitialized || _options.Count == 0) {
return;
}
CalcSpacingConfig ();
- Adjust ();
- SetNeedsDisplay ();
- SuperView?.SetNeedsLayout ();
+ SetBoundsBestFit ();
}
}
@@ -595,18 +580,16 @@ public List> Options {
///
public bool RangeAllowSingle {
get => _config._rangeAllowSingle;
- set {
- _config._rangeAllowSingle = value;
- }
+ set => _config._rangeAllowSingle = value;
}
///
/// Show/Hide spacing before and after the first and last option.
///
- public bool ShowSpacing {
- get => _config._showSpacing;
+ public bool ShowEndSpacing {
+ get => _config._showEndSpacing;
set {
- _config._showSpacing = value;
+ _config._showEndSpacing = value;
SetNeedsDisplay ();
}
}
@@ -618,7 +601,8 @@ public bool ShowLegends {
get => _config._showLegends;
set {
_config._showLegends = value;
- Adjust ();
+ SetBoundsBestFit ();
+
}
}
@@ -644,7 +628,7 @@ public bool SetOption (int optionIndex)
public bool UnSetOption (int optionIndex)
{
// TODO: Handle range type.
- if ((!AllowEmpty && _setOptions.Count > 2) && _setOptions.Contains (optionIndex)) {
+ if (!AllowEmpty && _setOptions.Count > 2 && _setOptions.Contains (optionIndex)) {
FocusedOption = optionIndex;
SetFocusedOption ();
return true;
@@ -655,12 +639,9 @@ public bool UnSetOption (int optionIndex)
///
/// Get the indexes of the set options.
///
- public List GetSetOptions ()
- {
+ public List GetSetOptions () =>
// Copy
- return _setOptions.OrderBy (e => e).ToList ();
- }
-
+ _setOptions.OrderBy (e => e).ToList ();
#endregion
#region Helpers
@@ -681,12 +662,12 @@ void SetDefaultStyle ()
{
switch (_config._sliderOrientation) {
case Orientation.Horizontal:
- _style.SpaceChar = new Cell () { Rune = CM.Glyphs.HLine }; // '─'
- _style.OptionChar = new Cell () { Rune = CM.Glyphs.BlackCircle }; // '┼●🗹□⏹'
+ Style.SpaceChar = new Cell { Rune = Glyphs.HLine }; // '─'
+ Style.OptionChar = new Cell { Rune = Glyphs.BlackCircle }; // '┼●🗹□⏹'
break;
case Orientation.Vertical:
- _style.SpaceChar = new Cell () { Rune = CM.Glyphs.VLine };
- _style.OptionChar = new Cell () { Rune = CM.Glyphs.BlackCircle };
+ Style.SpaceChar = new Cell { Rune = Glyphs.VLine };
+ Style.OptionChar = new Cell { Rune = Glyphs.BlackCircle };
break;
}
@@ -710,12 +691,12 @@ void SetDefaultStyle ()
*/
_config._legendsOrientation = _config._sliderOrientation;
- _style.EmptyChar = new Cell () { Rune = new Rune (' ') };
- _style.SetChar = new Cell () { Rune = CM.Glyphs.ContinuousMeterSegment }; // ■
- _style.RangeChar = new Cell () { Rune = CM.Glyphs.Stipple }; // ░ ▒ ▓ // Medium shade not blinking on curses.
- _style.StartRangeChar = new Cell () { Rune = CM.Glyphs.ContinuousMeterSegment };
- _style.EndRangeChar = new Cell () { Rune = CM.Glyphs.ContinuousMeterSegment };
- _style.DragChar = new Cell () { Rune = CM.Glyphs.Diamond };
+ Style.EmptyChar = new Cell { Rune = new Rune (' ') };
+ Style.SetChar = new Cell { Rune = Glyphs.ContinuousMeterSegment }; // ■
+ Style.RangeChar = new Cell { Rune = Glyphs.Stipple }; // ░ ▒ ▓ // Medium shade not blinking on curses.
+ Style.StartRangeChar = new Cell { Rune = Glyphs.ContinuousMeterSegment };
+ Style.EndRangeChar = new Cell { Rune = Glyphs.ContinuousMeterSegment };
+ Style.DragChar = new Cell { Rune = Glyphs.Diamond };
// TODO: Support left & right (top/bottom)
// First = '├',
@@ -723,29 +704,39 @@ void SetDefaultStyle ()
}
///
- /// Calculates the spacing configuration (start, inner, end) as well as turning on/off legend abbreviation
- /// if needed. Behaves differently based on and .
+ /// Calculates the spacing configuration (start, inner, end) as well as turning on/off legend
+ /// abbreviation if needed. Behaves differently based on and
+ /// .
///
internal void CalcSpacingConfig ()
{
- int size = 0;
+ var size = 0;
- if (_options.Count == 0) {
+ if (_options.Count == 0 || !IsInitialized) {
return;
}
- if (_config._autoSize || !IsInitialized) {
- if (IsInitialized && SuperView != null) {
+ _config._innerSpacing = 0;
+ _config._startSpacing = 0;
+ _config._endSpacing = 0;
+
+ if (AutoSize) {
+ // Max size is SuperView's Bounds. Min Size is size that will fit.
+ if (SuperView != null) {
// Calculate the size of the slider based on the size of the SuperView's Bounds.
- // TODO:
+ if (_config._sliderOrientation == Orientation.Horizontal) {
+ size = int.Min (SuperView.Bounds.Width, CalcBestLength ());
+ } else {
+ size = int.Min (SuperView.Bounds.Height, CalcBestLength ());
+ }
} else {
// Use the config values
- size = CalcLength ();
+ size = CalcMinLength ();
return;
}
} else {
- // Fit Slider to the actual width and height.
+ // Fit Slider to the Bounds
if (_config._sliderOrientation == Orientation.Horizontal) {
size = Bounds.Width;
} else {
@@ -753,21 +744,24 @@ internal void CalcSpacingConfig ()
}
}
- int max_legend;
+ int max_legend; // Because the legends are centered, the longest one determines inner spacing
if (_config._sliderOrientation == _config._legendsOrientation) {
- max_legend = _options.Max (e => e.Legend.ToString ().Length);
+ max_legend = int.Max (_options.Max (s => s.Legend?.Length ?? 1), 1);
} else {
max_legend = 1;
}
- var min = (size - max_legend) / (_options.Count - 1);
+ var min_size_that_fits_legends = _options.Count == 1 ? max_legend : max_legend / (_options.Count - 1);
string first;
string last;
- if (max_legend >= min) {
+ if (max_legend >= size) {
if (_config._sliderOrientation == _config._legendsOrientation) {
_config._showLegendsAbbr = true;
+ foreach (var o in _options.Where (op => op.LegendAbbr == default)) {
+ o.LegendAbbr = (Rune)(o.Legend?.Length > 0 ? o.Legend [0] : ' ');
+ }
}
first = "x";
last = "x";
@@ -782,85 +776,104 @@ internal void CalcSpacingConfig ()
// Left = He
// Right = lo
var first_left = (first.Length - 1) / 2; // Chars count of the first option to the left.
- var last_right = (last.Length) / 2; // Chars count of the last option to the right.
+ var last_right = last.Length / 2; // Chars count of the last option to the right.
if (_config._sliderOrientation != _config._legendsOrientation) {
first_left = 0;
last_right = 0;
}
+ // -1 because it's better to have an extra space at right than to clip
var width = size - first_left - last_right - 1;
_config._startSpacing = first_left;
- _config._innerSpacing = Math.Max (0, (int)Math.Floor ((double)width / (_options.Count - 1)) - 1);
+ if (_options.Count == 1) {
+ _config._innerSpacing = max_legend;
+ } else {
+ _config._innerSpacing = Math.Max (0, (int)Math.Floor ((double)width / (_options.Count - 1)) - 1);
+ }
_config._endSpacing = last_right;
}
///
- /// Adjust the height of the Slider to the best value.
- ///
- public void AdjustBestHeight ()
+ /// Adjust the dimensions of the Slider to the best value if is true.
+ ///
+ public void SetBoundsBestFit ()
{
+ if (!IsInitialized || AutoSize == false) {
+ return;
+ }
// Hack??? Otherwise we can't go back to Dim.Absolute.
LayoutStyle = LayoutStyle.Absolute;
-
+ Width = 0;
+ Height = 0;
if (_config._sliderOrientation == Orientation.Horizontal) {
- Bounds = new Rect (Bounds.Location, new Size (Bounds.Width, CalcThickness ()));
+ Bounds = new Rect (Bounds.Location,
+ new Size (int.Min (SuperView.Bounds.Width - GetFramesThickness ().Horizontal, CalcBestLength ()),
+ int.Min (SuperView.Bounds.Height - GetFramesThickness ().Vertical, CalcThickness ())));
} else {
- Bounds = new Rect (Bounds.Location, new Size (Bounds.Width, CalcLength ()));
+ Bounds = new Rect (Bounds.Location,
+ new Size (int.Min (SuperView.Bounds.Width - GetFramesThickness ().Horizontal, CalcThickness ()),
+ int.Min (SuperView.Bounds.Height - GetFramesThickness ().Vertical, CalcBestLength ())));
}
-
LayoutStyle = LayoutStyle.Computed;
}
///
- /// Adjust the height of the Slider to the best value. (Only works if height is DimAbsolute).
- ///
- public void AdjustBestWidth ()
- {
- LayoutStyle = LayoutStyle.Absolute;
-
- if (_config._sliderOrientation == Orientation.Horizontal) {
- Bounds = new Rect (Bounds.Location, new Size (CalcLength (), Bounds.Height));
- } else {
- Bounds = new Rect (Bounds.Location, new Size (CalcThickness (), Bounds.Height));
- }
-
- LayoutStyle = LayoutStyle.Computed;
- }
-
- void Adjust ()
+ /// Calculates the min dimension required for all options and inner spacing with abbreviated legends
+ ///
+ ///
+ int CalcMinLength ()
{
- if (Width is Dim.DimAbsolute) {
- AdjustBestWidth ();
+ if (_options.Count == 0) {
+ return 0;
}
- if (Height is Dim.DimAbsolute) {
- AdjustBestHeight ();
- }
+ var length = 0;
+ length += _config._startSpacing + _config._endSpacing;
+ length += _options.Count;
+ length += (_options.Count - 1) * _config._innerSpacing;
+ return length;
}
- internal int CalcLength ()
+ ///
+ /// Calculates the ideal dimension required for all options, inner spacing, and legends
+ /// (non-abbreviated).
+ ///
+ ///
+ int CalcBestLength ()
{
if (_options.Count == 0) {
return 0;
}
var length = 0;
- length += _config._startSpacing + _config._endSpacing;
- length += _options.Count;
- length += (_options.Count - 1) * _config._innerSpacing;
- return length;
+
+ if (_config._showLegends) {
+ var max_legend = 1;
+ if (_config._legendsOrientation == _config._sliderOrientation && _options.Count > 0) {
+ max_legend = int.Max (_options.Max (s => s.Legend?.Length + 1 ?? 1), 1);
+ length += max_legend * _options.Count;
+ //length += (max_legend / 2);
+ } else {
+ length += 1;
+ }
+ }
+ return int.Max (length, CalcMinLength ());
}
+ ///
+ /// Calculates the min dimension required for the slider and legends
+ ///
+ ///
int CalcThickness ()
{
var thickness = 1; // Always show the slider.
if (_config._showLegends) {
if (_config._legendsOrientation != _config._sliderOrientation && _options.Count > 0) {
- thickness += _options.Max (s => s.Legend.Length);
+ thickness += _options.Max (s => s.Legend?.Length ?? 0);
} else {
thickness += 1;
}
@@ -907,7 +920,7 @@ internal bool TryGetOptionByPosition (int x, int y, int threshold, out int optio
return false;
}
- for (int xx = (x - threshold); xx < (x + threshold + 1); xx++) {
+ for (var xx = x - threshold; xx < x + threshold + 1; xx++) {
var cx = xx;
cx -= _config._startSpacing;
@@ -927,7 +940,7 @@ internal bool TryGetOptionByPosition (int x, int y, int threshold, out int optio
return false;
}
- for (int yy = (y - threshold); yy < (y + threshold + 1); yy++) {
+ for (var yy = y - threshold; yy < y + threshold + 1; yy++) {
var cy = yy;
cy -= _config._startSpacing;
@@ -945,11 +958,9 @@ internal bool TryGetOptionByPosition (int x, int y, int threshold, out int optio
return false;
}
-
#endregion
#region Cursor and Drawing
-
///
public override void PositionCursor ()
{
@@ -960,7 +971,7 @@ public override void PositionCursor ()
} else {
Driver?.SetCursorVisibility (CursorVisibility.Invisible);
}
- if (TryGetPositionByOption (FocusedOption, out (int x, int y) position)) {
+ if (TryGetPositionByOption (FocusedOption, out var position)) {
if (IsInitialized && Bounds.Contains (position.x, position.y)) {
Move (position.x, position.y);
}
@@ -972,17 +983,15 @@ public override void OnDrawContent (Rect contentArea)
{
// TODO: make this more surgical to reduce repaint
- var normalScheme = ColorScheme?.Normal ?? Application.Current.ColorScheme.Normal;
-
- if (this._options == null && this._options.Count > 0) {
+ if (_options == null && _options.Count > 0) {
return;
}
// Debug
#if (DEBUG)
- Driver.SetAttribute (new Attribute (Color.White, Color.Red));
- for (var y = 0; y < Bounds.Height; y++) {
- for (var x = 0; x < Bounds.Width; x++) {
+ Driver?.SetAttribute (new Attribute (Color.White, Color.Red));
+ for (var y = 0; y < contentArea.Height; y++) {
+ for (var x = 0; x < contentArea.Width; x++) {
// MoveAndAdd (x, y, '·');
}
}
@@ -997,7 +1006,7 @@ public override void OnDrawContent (Rect contentArea)
}
if (_dragPosition.HasValue && _moveRenderPosition.HasValue) {
- AddRune (_moveRenderPosition.Value.X, _moveRenderPosition.Value.Y, _style.DragChar.Rune);
+ AddRune (_moveRenderPosition.Value.X, _moveRenderPosition.Value.Y, Style.DragChar.Rune);
}
}
@@ -1008,26 +1017,24 @@ string AlignText (string text, int width, TextAlignment textAlignment)
}
if (text.Length > width) {
- text = text [0..width];
+ text = text [..width];
}
var w = width - text.Length;
- var s1 = new string (' ', w / 2);
- var s2 = new string (' ', w % 2);
+ string s1 = new (' ', w / 2);
+ string s2 = new (' ', w % 2);
// Note: The formatter doesn't handle all of this ???
switch (textAlignment) {
case TextAlignment.Justified:
-
return TextFormatter.Justify (text, width);
case TextAlignment.Left:
return text + s1 + s1 + s2;
case TextAlignment.Centered:
if (text.Length % 2 != 0) {
return s1 + text + s1 + s2;
- } else {
- return s1 + s2 + text + s1;
}
+ return s1 + s2 + text + s1;
case TextAlignment.Right:
return s1 + s1 + s2 + text;
default:
@@ -1041,9 +1048,13 @@ void DrawSlider ()
Clear ();
// Attributes
- var normalScheme = ColorScheme?.Normal ?? Application.Current.ColorScheme.Normal;
- //var normalScheme = style.LegendStyle.NormalAttribute ?? ColorScheme.Disabled;
- var setScheme = _style.SetChar.Attribute ?? ColorScheme.HotNormal;// ColorScheme?.Focus ?? Application.Current.ColorScheme.Focus;
+
+ var normalAttr = new Attribute (Color.White, Color.Black);
+ var setAtrr = new Attribute (Color.Black, Color.White);
+ if (IsInitialized) {
+ normalAttr = ColorScheme?.Normal ?? Application.Current.ColorScheme.Normal;
+ setAtrr = Style.SetChar.Attribute ?? ColorScheme.HotNormal;
+ }
var isVertical = _config._sliderOrientation == Orientation.Vertical;
var isLegendsVertical = _config._legendsOrientation == Orientation.Vertical;
@@ -1055,21 +1066,28 @@ void DrawSlider ()
var isSet = _setOptions.Count > 0;
// Left Spacing
- if (_config._showSpacing && _config._startSpacing > 0) {
+ if (_config._showEndSpacing && _config._startSpacing > 0) {
- Driver.SetAttribute (isSet && _config._type == SliderType.LeftRange ? _style.RangeChar.Attribute ?? normalScheme : _style.SpaceChar.Attribute ?? normalScheme);
- var rune = isSet && _config._type == SliderType.LeftRange ? _style.RangeChar.Rune : _style.SpaceChar.Rune;
+ Driver?.SetAttribute (isSet && _config._type == SliderType.LeftRange ? Style.RangeChar.Attribute ?? normalAttr : Style.SpaceChar.Attribute ?? normalAttr);
+ var rune = isSet && _config._type == SliderType.LeftRange ? Style.RangeChar.Rune : Style.SpaceChar.Rune;
- for (var i = 0; i < this._config._startSpacing; i++) {
+ for (var i = 0; i < _config._startSpacing; i++) {
MoveAndAdd (x, y, rune);
- if (isVertical) y++; else x++;
+ if (isVertical) {
+ y++;
+ } else {
+ x++;
+ }
}
} else {
- Driver.SetAttribute (_style.EmptyChar.Attribute ?? normalScheme);
- // for (int i = 0; i < this.config.StartSpacing + ((this.config.StartSpacing + this.config.EndSpacing) % 2 == 0 ? 1 : 2); i++) {
- for (var i = 0; i < this._config._startSpacing; i++) {
- MoveAndAdd (x, y, _style.EmptyChar.Rune);
- if (isVertical) y++; else x++;
+ Driver?.SetAttribute (Style.EmptyChar.Attribute ?? normalAttr);
+ for (var i = 0; i < _config._startSpacing; i++) {
+ MoveAndAdd (x, y, Style.EmptyChar.Rune);
+ if (isVertical) {
+ y++;
+ } else {
+ x++;
+ }
}
}
@@ -1091,19 +1109,17 @@ void DrawSlider ()
drawRange = false;
break;
case SliderType.Range when _setOptions.Count == 2:
- if ((i >= _setOptions [0] && i <= _setOptions [1]) || (i >= _setOptions [1] && i <= _setOptions [0])) {
- drawRange = (i >= _setOptions [0] && i < _setOptions [1]) || (i >= _setOptions [1] && i < _setOptions [0]);
+ if (i >= _setOptions [0] && i <= _setOptions [1] || i >= _setOptions [1] && i <= _setOptions [0]) {
+ drawRange = i >= _setOptions [0] && i < _setOptions [1] || i >= _setOptions [1] && i < _setOptions [0];
}
break;
- default:
- // Is Not a Range.
- break;
}
}
// Draw Option
- Driver.SetAttribute (isSet && _setOptions.Contains (i) ? _style.SetChar.Attribute ?? setScheme : drawRange ? _style.RangeChar.Attribute ?? setScheme : _style.OptionChar.Attribute ?? normalScheme);
+ Driver?.SetAttribute (isSet && _setOptions.Contains (i) ? Style.SetChar.Attribute ?? setAtrr : drawRange
+ ? Style.RangeChar.Attribute ?? setAtrr : Style.OptionChar.Attribute ?? normalAttr);
// Note(jmperricone): Maybe only for curses, windows inverts actual colors, while curses inverts bg with fg.
//if (Application.Driver is CursesDriver) {
@@ -1111,25 +1127,34 @@ void DrawSlider ()
// Driver.SetAttribute (ColorScheme.Focus);
// }
//}
- Rune rune = drawRange ? _style.RangeChar.Rune : _style.OptionChar.Rune;
+ var rune = drawRange ? Style.RangeChar.Rune : Style.OptionChar.Rune;
if (isSet) {
if (_setOptions [0] == i) {
- rune = _style.StartRangeChar.Rune;
+ rune = Style.StartRangeChar.Rune;
} else if (_setOptions.Count > 1 && _setOptions [1] == i) {
- rune = _style.EndRangeChar.Rune;
+ rune = Style.EndRangeChar.Rune;
} else if (_setOptions.Contains (i)) {
- rune = _style.SetChar.Rune;
+ rune = Style.SetChar.Rune;
}
}
MoveAndAdd (x, y, rune);
- if (isVertical) y++; else x++;
+ if (isVertical) {
+ y++;
+ } else {
+ x++;
+ }
// Draw Spacing
- if (_config._showSpacing || i < _options.Count - 1) { // Skip if is the Last Spacing.
- Driver.SetAttribute (drawRange && isSet ? _style.RangeChar.Attribute ?? setScheme : _style.SpaceChar.Attribute ?? normalScheme);
+ if (_config._showEndSpacing || i < _options.Count - 1) {
+ // Skip if is the Last Spacing.
+ Driver?.SetAttribute (drawRange && isSet ? Style.RangeChar.Attribute ?? setAtrr : Style.SpaceChar.Attribute ?? normalAttr);
for (var s = 0; s < _config._innerSpacing; s++) {
- MoveAndAdd (x, y, drawRange && isSet ? _style.RangeChar.Rune : _style.SpaceChar.Rune);
- if (isVertical) y++; else x++;
+ MoveAndAdd (x, y, drawRange && isSet ? Style.RangeChar.Rune : Style.SpaceChar.Rune);
+ if (isVertical) {
+ y++;
+ } else {
+ x++;
+ }
}
}
}
@@ -1137,18 +1162,26 @@ void DrawSlider ()
var remaining = isVertical ? Bounds.Height - y : Bounds.Width - x;
// Right Spacing
- if (_config._showSpacing) {
- Driver.SetAttribute (isSet && _config._type == SliderType.RightRange ? _style.RangeChar.Attribute ?? normalScheme : _style.SpaceChar.Attribute ?? normalScheme);
- var rune = isSet && _config._type == SliderType.RightRange ? _style.RangeChar.Rune : _style.SpaceChar.Rune;
+ if (_config._showEndSpacing) {
+ Driver?.SetAttribute (isSet && _config._type == SliderType.RightRange ? Style.RangeChar.Attribute ?? normalAttr : Style.SpaceChar.Attribute ?? normalAttr);
+ var rune = isSet && _config._type == SliderType.RightRange ? Style.RangeChar.Rune : Style.SpaceChar.Rune;
for (var i = 0; i < remaining; i++) {
MoveAndAdd (x, y, rune);
- if (isVertical) y++; else x++;
+ if (isVertical) {
+ y++;
+ } else {
+ x++;
+ }
}
} else {
- Driver.SetAttribute (_style.EmptyChar.Attribute ?? normalScheme);
+ Driver?.SetAttribute (Style.EmptyChar.Attribute ?? normalAttr);
for (var i = 0; i < remaining; i++) {
- MoveAndAdd (x, y, _style.EmptyChar.Rune);
- if (isVertical) y++; else x++;
+ MoveAndAdd (x, y, Style.EmptyChar.Rune);
+ if (isVertical) {
+ y++;
+ } else {
+ x++;
+ }
}
}
}
@@ -1156,9 +1189,14 @@ void DrawSlider ()
void DrawLegends ()
{
// Attributes
- var normalScheme = _style.LegendAttributes.NormalAttribute ?? ColorScheme?.Normal ?? ColorScheme.Disabled;
- var setScheme = _style.LegendAttributes.SetAttribute ?? ColorScheme?.HotNormal ?? ColorScheme.Normal;
- var spaceScheme = normalScheme;// style.LegendStyle.EmptyAttribute ?? normalScheme;
+ var normalAttr = new Attribute (Color.White, Color.Black);
+ var setAttr = new Attribute (Color.Black, Color.White);
+ var spaceAttr = normalAttr;
+ if (IsInitialized) {
+ normalAttr = Style.LegendAttributes.NormalAttribute ?? ColorScheme?.Normal ?? ColorScheme.Disabled;
+ setAttr = Style.LegendAttributes.SetAttribute ?? ColorScheme?.HotNormal ?? ColorScheme.Normal;
+ spaceAttr = Style.LegendAttributes.EmptyAttribute ?? normalAttr;
+ }
var isTextVertical = _config._legendsOrientation == Orientation.Vertical;
var isSet = _setOptions.Count > 0;
@@ -1177,42 +1215,47 @@ void DrawLegends ()
if (_config._sliderOrientation == Orientation.Horizontal) {
y += 1;
- } else { // Vertical
+ } else {
+ // Vertical
x += 1;
}
- for (int i = 0; i < _options.Count; i++) {
+ for (var i = 0; i < _options.Count; i++) {
- bool isOptionSet = false;
+ var isOptionSet = false;
// Check if the Option is Set.
switch (_config._type) {
case SliderType.Single:
case SliderType.Multiple:
- if (isSet && _setOptions.Contains (i))
+ if (isSet && _setOptions.Contains (i)) {
isOptionSet = true;
+ }
break;
case SliderType.LeftRange:
- if (isSet && i <= _setOptions [0])
+ if (isSet && i <= _setOptions [0]) {
isOptionSet = true;
+ }
break;
case SliderType.RightRange:
- if (isSet && i >= _setOptions [0])
+ if (isSet && i >= _setOptions [0]) {
isOptionSet = true;
+ }
break;
case SliderType.Range when _setOptions.Count == 1:
- if (isSet && i == _setOptions [0])
+ if (isSet && i == _setOptions [0]) {
isOptionSet = true;
+ }
break;
case SliderType.Range:
- if (isSet && ((i >= _setOptions [0] && i <= _setOptions [1]) || (i >= _setOptions [1] && i <= _setOptions [0]))) {
+ if (isSet && (i >= _setOptions [0] && i <= _setOptions [1] || i >= _setOptions [1] && i <= _setOptions [0])) {
isOptionSet = true;
}
break;
}
// Text || Abbreviation
- string text = string.Empty;
+ var text = string.Empty;
if (_config._showLegendsAbbr) {
text = _options [i].LegendAbbr.ToString () ?? new Rune (_options [i].Legend.First ()).ToString ();
} else {
@@ -1266,18 +1309,24 @@ void DrawLegends ()
}
// Option Left Spacing
- if (isTextVertical) y += legend_left_spaces_count;
- else x += legend_left_spaces_count;
+ if (isTextVertical) {
+ y += legend_left_spaces_count;
+ } else {
+ x += legend_left_spaces_count;
+ }
//Move (x, y);
}
// Legend
- Driver.SetAttribute (isOptionSet ? setScheme : normalScheme);
+ Driver?.SetAttribute (isOptionSet ? setAttr : normalAttr);
foreach (var c in text.EnumerateRunes ()) {
MoveAndAdd (x, y, c);
//Driver.AddRune (c);
- if (isTextVertical) y += 1;
- else x += 1;
+ if (isTextVertical) {
+ y += 1;
+ } else {
+ x += 1;
+ }
}
// Calculate End Spacing
@@ -1288,9 +1337,12 @@ void DrawLegends ()
}
// Option Right Spacing of Option
- Driver.SetAttribute (spaceScheme);
- if (isTextVertical) y += legend_right_spaces_count;
- else x += legend_right_spaces_count;
+ Driver?.SetAttribute (spaceAttr);
+ if (isTextVertical) {
+ y += legend_right_spaces_count;
+ } else {
+ x += legend_right_spaces_count;
+ }
if (_config._sliderOrientation == Orientation.Horizontal && _config._legendsOrientation == Orientation.Vertical) {
x += _config._innerSpacing + 1;
@@ -1299,13 +1351,12 @@ void DrawLegends ()
}
}
}
-
#endregion
#region Keys and Mouse
-
// Mouse coordinates of current drag
Point? _dragPosition;
+
// Coordinates of where the "move cursor" is drawn (in OnDrawContent)
Point? _moveRenderPosition;
@@ -1319,9 +1370,9 @@ public override bool MouseEvent (MouseEvent mouseEvent)
// TODO(jmperricone): Make Range Type work with mouse.
if (!(mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked) ||
- mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) ||
- mouseEvent.Flags.HasFlag (MouseFlags.ReportMousePosition) ||
- mouseEvent.Flags.HasFlag (MouseFlags.Button1Released))) {
+ mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) ||
+ mouseEvent.Flags.HasFlag (MouseFlags.ReportMousePosition) ||
+ mouseEvent.Flags.HasFlag (MouseFlags.Button1Released))) {
return false;
}
@@ -1332,13 +1383,13 @@ Point ClampMovePosition (Point position)
if (Orientation == Orientation.Horizontal) {
var left = _config._startSpacing;
var width = _options.Count + (_options.Count - 1) * _config._innerSpacing;
- var right = (left + width - 1);
+ var right = left + width - 1;
var clampedX = Clamp (position.X, left, right);
position = new Point (clampedX, 0);
} else {
var top = _config._startSpacing;
var height = _options.Count + (_options.Count - 1) * _config._innerSpacing;
- var bottom = (top + height - 1);
+ var bottom = top + height - 1;
var clampedY = Clamp (position.Y, top, bottom);
position = new Point (0, clampedY);
}
@@ -1347,7 +1398,7 @@ Point ClampMovePosition (Point position)
SetFocus ();
- if (!_dragPosition.HasValue && (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed))) {
+ if (!_dragPosition.HasValue && mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) {
if (mouseEvent.Flags.HasFlag (MouseFlags.ReportMousePosition)) {
_dragPosition = new Point (mouseEvent.X, mouseEvent.Y);
@@ -1382,7 +1433,7 @@ Point ClampMovePosition (Point position)
return true;
}
- if ((_dragPosition.HasValue && mouseEvent.Flags.HasFlag (MouseFlags.Button1Released)) || mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) {
+ if (_dragPosition.HasValue && mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) || mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) {
// End Drag
Application.UngrabMouse ();
@@ -1411,15 +1462,15 @@ Point ClampMovePosition (Point position)
void SetCommands ()
{
- AddCommand (Command.Right, () => MovePlus ());
- AddCommand (Command.LineDown, () => MovePlus ());
- AddCommand (Command.Left, () => MoveMinus ());
- AddCommand (Command.LineUp, () => MoveMinus ());
- AddCommand (Command.LeftHome, () => MoveStart ());
- AddCommand (Command.RightEnd, () => MoveEnd ());
+ AddCommand (Command.Right, () => MovePlus ());
+ AddCommand (Command.LineDown, () => MovePlus ());
+ AddCommand (Command.Left, () => MoveMinus ());
+ AddCommand (Command.LineUp, () => MoveMinus ());
+ AddCommand (Command.LeftHome, () => MoveStart ());
+ AddCommand (Command.RightEnd, () => MoveEnd ());
AddCommand (Command.RightExtend, () => ExtendPlus ());
- AddCommand (Command.LeftExtend, () => ExtendMinus ());
- AddCommand (Command.Accept, () => Set ());
+ AddCommand (Command.LeftExtend, () => ExtendMinus ());
+ AddCommand (Command.Accept, () => Set ());
SetKeyBindings ();
}
@@ -1449,8 +1500,8 @@ void SetKeyBindings ()
KeyBindings.Add (KeyCode.CursorUp | KeyCode.CtrlMask, Command.LeftExtend);
}
- KeyBindings.Add (KeyCode.Home, Command.LeftHome);
- KeyBindings.Add (KeyCode.End, Command.RightEnd);
+ KeyBindings.Add (KeyCode.Home, Command.LeftHome);
+ KeyBindings.Add (KeyCode.End, Command.RightEnd);
KeyBindings.Add (KeyCode.Enter, Command.Accept);
KeyBindings.Add (KeyCode.Space, Command.Accept);
@@ -1577,7 +1628,7 @@ void SetFocusedOption ()
// extend right
_options [_setOptions [1]].OnUnSet ();
_setOptions [1] = FocusedOption;
- } else if (FocusedOption >= _setOptions [0] && FocusedOption <= _setOptions [1] && (_setOptions [1] - _setOptions [0] > 1)) {
+ } else if (FocusedOption >= _setOptions [0] && FocusedOption <= _setOptions [1] && _setOptions [1] - _setOptions [0] > 1) {
if (FocusedOption < _lastFocusedOption) {
// shrink to the left
_options [_setOptions [1]].OnUnSet ();
@@ -1721,4 +1772,4 @@ internal bool MoveEnd ()
return true;
}
#endregion
-}
+}
\ No newline at end of file
diff --git a/Terminal.sln b/Terminal.sln
index 4d1712f8e4..fcc42be940 100644
--- a/Terminal.sln
+++ b/Terminal.sln
@@ -14,6 +14,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example", "Example\Example.
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E143FB1F-0B88-48CB-9086-72CDCECFCD22}"
ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
.gitignore = .gitignore
.github\workflows\api-docs.yml = .github\workflows\api-docs.yml
.github\CODEOWNERS = .github\CODEOWNERS
diff --git a/UICatalog/Scenarios/Sliders.cs b/UICatalog/Scenarios/Sliders.cs
index 7d4ff03a5c..5da9497115 100644
--- a/UICatalog/Scenarios/Sliders.cs
+++ b/UICatalog/Scenarios/Sliders.cs
@@ -6,15 +6,12 @@
namespace UICatalog.Scenarios;
-[ScenarioMetadata (Name: "Sliders", Description: "Demonstrates the Slider view.")]
+[ScenarioMetadata ("Sliders", "Demonstrates the Slider view.")]
[ScenarioCategory ("Controls")]
public class Sliders : Scenario {
public override void Setup ()
{
MakeSliders (Win, new List { 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000 });
-
- #region configView
-
var configView = new FrameView {
Title = "Configuration",
X = Pos.Percent (50),
@@ -27,88 +24,70 @@ public override void Setup ()
Win.Add (configView);
#region Config Slider
-
- var slider = new Slider () {
+ var slider = new Slider {
Title = "Options",
- X = Pos.Center (),
+ X = 0,
Y = 0,
Type = SliderType.Multiple,
Width = Dim.Fill (),
+ Height = 4,
AllowEmpty = true,
BorderStyle = LineStyle.Single
};
- slider.Style.SetChar.Attribute = new Terminal.Gui.Attribute (Color.BrightGreen, Color.Black);
- slider.Style.LegendAttributes.SetAttribute = new Terminal.Gui.Attribute (Color.Green, Color.Black);
+ slider.Style.SetChar.Attribute = new Attribute (Color.BrightGreen, Color.Black);
+ slider.Style.LegendAttributes.SetAttribute = new Attribute (Color.Green, Color.Black);
slider.Options = new List> {
- new SliderOption{
- Legend="Legends"
- },
- new SliderOption{
- Legend="RangeAllowSingle"
- },
- new SliderOption{
- Legend="Spacing"
- }
- };
+ new () {
+ Legend = "Legends"
+ },
+ new () {
+ Legend = "RangeAllowSingle"
+ },
+ new () {
+ Legend = "EndSpacing"
+ },
+ new () {
+ Legend = "AutoSize"
+ }
+ };
configView.Add (slider);
slider.OptionsChanged += (sender, e) => {
foreach (var s in Win.Subviews.OfType ()) {
- if (e.Options.ContainsKey (0))
- s.ShowLegends = true;
- else
- s.ShowLegends = false;
-
- if (e.Options.ContainsKey (1))
- s.RangeAllowSingle = true;
- else
- s.RangeAllowSingle = false;
-
- if (e.Options.ContainsKey (2))
- s.ShowSpacing = true;
- else
- s.ShowSpacing = false;
+ s.ShowLegends = e.Options.ContainsKey (0);
+ s.RangeAllowSingle = e.Options.ContainsKey (1);
+ s.ShowEndSpacing = e.Options.ContainsKey (2);
+ s.AutoSize = e.Options.ContainsKey (3);
+ if (!s.AutoSize) {
+ if (s.Orientation == Orientation.Horizontal) {
+ s.Width = Dim.Percent (50);
+ var h = s.ShowLegends && s.LegendsOrientation == Orientation.Vertical ? s.Options.Max (o => o.Legend.Length) + 3 : 4;
+ s.Height = h;
+ } else {
+ var w = s.ShowLegends ? s.Options.Max (o => o.Legend.Length) + 3 : 3;
+ s.Width = w;
+ s.Height = Dim.Fill ();
+ }
+ }
}
if (Win.IsInitialized) {
Win.LayoutSubviews ();
}
};
- slider.SetOption (0);
- slider.SetOption (1);
-
- #endregion
-
- #region InnerSpacing Input
- // var innerspacing_slider = new Slider ("Innerspacing", new List { "Auto", "0", "1", "2", "3", "4", "5" }) {
- // X = Pos.Center (),
- // Y = Pos.Bottom (slider) + 1
- // };
-
- // innerspacing_slider.SetOption (0);
-
- // configView.Add (innerspacing_slider);
-
- // innerspacing_slider.OptionsChanged += (options) => {
- // foreach (var s in leftView.Subviews.OfType () ()) {
- // if (options.ContainsKey (0)) { }
- // //s.la = S.SliderLayout.Auto;
- // else {
- // s.InnerSpacing = options.Keys.First () - 1;
- // }
- // }
- // };
- #endregion
+ slider.SetOption (0); // Legends
+ slider.SetOption (1); // RangeAllowSingle
+ //slider.SetOption (3); // AutoSize
#region Slider Orientation Slider
-
var slider_orientation_slider = new Slider (new List { "Horizontal", "Vertical" }) {
Title = "Slider Orientation",
X = 0,
Y = Pos.Bottom (slider) + 1,
Width = Dim.Fill (),
+ Height = 4,
BorderStyle = LineStyle.Single
};
@@ -117,17 +96,12 @@ public override void Setup ()
configView.Add (slider_orientation_slider);
slider_orientation_slider.OptionsChanged += (sender, e) => {
-
View prev = null;
foreach (var s in Win.Subviews.OfType ()) {
-
if (e.Options.ContainsKey (0)) {
s.Orientation = Orientation.Horizontal;
- s.AdjustBestHeight ();
- s.Width = Dim.Percent (50);
-
- s.Style.SpaceChar = new Cell () { Rune = CM.Glyphs.HLine };
+ s.Style.SpaceChar = new Cell { Rune = CM.Glyphs.HLine };
if (prev == null) {
s.LayoutStyle = LayoutStyle.Absolute;
@@ -142,11 +116,7 @@ public override void Setup ()
} else if (e.Options.ContainsKey (1)) {
s.Orientation = Orientation.Vertical;
- s.AdjustBestWidth ();
- s.Height = Dim.Fill ();
-
- s.Style.SpaceChar = new Cell () { Rune = CM.Glyphs.VLine };
-
+ s.Style.SpaceChar = new Cell { Rune = CM.Glyphs.VLine };
if (prev == null) {
s.LayoutStyle = LayoutStyle.Absolute;
@@ -158,19 +128,29 @@ public override void Setup ()
s.Y = 0;
prev = s;
}
+
+ if (s.Orientation == Orientation.Horizontal) {
+ s.Width = Dim.Percent (50);
+ var h = s.ShowLegends && s.LegendsOrientation == Orientation.Vertical ? s.Options.Max (o => o.Legend.Length) + 3 : 4;
+ s.Height = h;
+ } else {
+ var w = s.ShowLegends ? s.Options.Max (o => o.Legend.Length) + 3 : 3;
+ s.Width = w;
+ s.Height = Dim.Fill ();
+ }
+
}
Win.LayoutSubviews ();
};
-
- #endregion
+ #endregion Slider Orientation Slider
#region Legends Orientation Slider
-
var legends_orientation_slider = new Slider (new List { "Horizontal", "Vertical" }) {
Title = "Legends Orientation",
X = Pos.Center (),
Y = Pos.Bottom (slider_orientation_slider) + 1,
Width = Dim.Fill (),
+ Height = 4,
BorderStyle = LineStyle.Single
};
@@ -180,143 +160,170 @@ public override void Setup ()
legends_orientation_slider.OptionsChanged += (sender, e) => {
foreach (var s in Win.Subviews.OfType ()) {
- if (e.Options.ContainsKey (0))
+ if (e.Options.ContainsKey (0)) {
s.LegendsOrientation = Orientation.Horizontal;
- else if (e.Options.ContainsKey (1))
+ } else if (e.Options.ContainsKey (1)) {
s.LegendsOrientation = Orientation.Vertical;
+ }
+ if (s.Orientation == Orientation.Horizontal) {
+ s.Width = Dim.Percent (50);
+ var h = s.ShowLegends && s.LegendsOrientation == Orientation.Vertical ? s.Options.Max (o => o.Legend.Length) + 3 : 4;
+ s.Height = h;
+ } else {
+ var w = s.ShowLegends ? s.Options.Max (o => o.Legend.Length) + 3 : 3;
+ s.Width = w;
+ s.Height = Dim.Fill ();
+ }
}
Win.LayoutSubviews ();
};
-
- #endregion
+ #endregion Legends Orientation Slider
#region Color Slider
+ foreach (var s in Win.Subviews.OfType ()) {
+ s.Style.OptionChar.Attribute = Win.GetNormalColor ();
+ s.Style.SetChar.Attribute = Win.GetNormalColor ();
+ s.Style.LegendAttributes.SetAttribute = Win.GetNormalColor ();
+ s.Style.RangeChar.Attribute = Win.GetNormalColor ();
+ }
- var sliderColor = new Slider<(Color, Color)> () {
- Title = "Color",
- X = Pos.Center (),
+ var sliderFGColor = new Slider<(Color, Color)> {
+ Title = "FG Color",
+ X = 0,
Y = Pos.Bottom (legends_orientation_slider) + 1,
Type = SliderType.Single,
- Width = Dim.Fill (),
BorderStyle = LineStyle.Single,
- AllowEmpty = false
+ AllowEmpty = false,
+ Orientation = Orientation.Vertical,
+ LegendsOrientation = Orientation.Horizontal,
+ AutoSize = true
};
- sliderColor.Style.SetChar.Attribute = new Terminal.Gui.Attribute (Color.BrightGreen, Color.Black);
- sliderColor.Style.LegendAttributes.SetAttribute = new Terminal.Gui.Attribute (Color.Green, Color.Blue);
+ sliderFGColor.Style.SetChar.Attribute = new Attribute (Color.BrightGreen, Color.Black);
+ sliderFGColor.Style.LegendAttributes.SetAttribute = new Attribute (Color.Green, Color.Blue);
- sliderColor.LegendsOrientation = Orientation.Vertical;
var colorOptions = new List> ();
foreach (var colorIndex in Enum.GetValues ()) {
var colorName = colorIndex.ToString ();
colorOptions.Add (new SliderOption<(Color, Color)> {
- Data = (new Color((ColorName)colorIndex), Win.GetNormalColor ().Background),
+ Data = (new Color (colorIndex), new Color (colorIndex)),
Legend = colorName,
- LegendAbbr = (Rune)colorName [0],
+ LegendAbbr = (Rune)colorName [0]
});
}
- sliderColor.Options = colorOptions;
+ sliderFGColor.Options = colorOptions;
- configView.Add (sliderColor);
+ configView.Add (sliderFGColor);
- sliderColor.OptionsChanged += (sender, e) => {
+ sliderFGColor.OptionsChanged += (sender, e) => {
if (e.Options.Count != 0) {
var data = e.Options.First ().Value.Data;
-
foreach (var s in Win.Subviews.OfType ()) {
- s.Style.OptionChar.Attribute = new Attribute (data.Item1, data.Item2);
- s.Style.SetChar.Attribute = new Attribute (data.Item1, data.Item2);
- s.Style.LegendAttributes.SetAttribute = new Attribute (data.Item1, Win.GetNormalColor ().Background);
- s.Style.RangeChar.Attribute = new Attribute (data.Item1, Win.GetNormalColor ().Background);
- s.Style.SpaceChar.Attribute = new Attribute (data.Item1, Win.GetNormalColor ().Background);
- s.Style.LegendAttributes.NormalAttribute = new Attribute (data.Item1, Win.GetNormalColor ().Background);
- // Here we can not call SetNeedDisplay(), because the OptionsChanged was triggered by Key Pressing,
- // that internaly calls SetNeedDisplay.
- }
- } else {
- foreach (var s in Win.Subviews.OfType ()) {
- s.Style.SetChar.Attribute = null;
- s.Style.LegendAttributes.SetAttribute = null;
- s.Style.RangeChar.Attribute = null;
+ s.ColorScheme = new ColorScheme (s.ColorScheme);
+ s.ColorScheme.Normal = new Attribute (data.Item2, s.ColorScheme.Normal.Background);
+
+ s.Style.OptionChar.Attribute = new Attribute (data.Item1, s.ColorScheme.Normal.Background);
+ s.Style.SetChar.Attribute = new Attribute (data.Item1, s.Style.SetChar.Attribute?.Background ?? s.ColorScheme.Normal.Background);
+ s.Style.LegendAttributes.SetAttribute = new Attribute (data.Item1, s.ColorScheme.Normal.Background);
+ s.Style.RangeChar.Attribute = new Attribute (data.Item1, s.ColorScheme.Normal.Background);
+ s.Style.SpaceChar.Attribute = new Attribute (data.Item1, s.ColorScheme.Normal.Background);
+ s.Style.LegendAttributes.NormalAttribute = new Attribute (data.Item1, s.ColorScheme.Normal.Background);
}
}
};
- // Set option after Eventhandler def, so it updates the sliders color.
- // sliderColor.SetOption (2);
+ var sliderBGColor = new Slider<(Color, Color)> {
+ Title = "BG Color",
+ X = Pos.Right (sliderFGColor),
+ Y = Pos.Top (sliderFGColor),
+ Type = SliderType.Single,
+ BorderStyle = LineStyle.Single,
+ AllowEmpty = false,
+ Orientation = Orientation.Vertical,
+ LegendsOrientation = Orientation.Horizontal,
+ AutoSize = true
+ };
+
+ sliderBGColor.Style.SetChar.Attribute = new Attribute (Color.BrightGreen, Color.Black);
+ sliderBGColor.Style.LegendAttributes.SetAttribute = new Attribute (Color.Green, Color.Blue);
- #endregion
+ sliderBGColor.Options = colorOptions;
- #endregion
+ configView.Add (sliderBGColor);
- Win.FocusFirst ();
+ sliderBGColor.OptionsChanged += (sender, e) => {
+ if (e.Options.Count != 0) {
+ var data = e.Options.First ().Value.Data;
+ foreach (var s in Win.Subviews.OfType ()) {
+ s.ColorScheme = new ColorScheme (s.ColorScheme);
+ s.ColorScheme.Normal = new Attribute (s.ColorScheme.Normal.Foreground, data.Item2);
+ }
+ }
+ };
+ #endregion Color Slider
+ #endregion Config Slider
+
+ Win.FocusFirst ();
+ Application.Top.Initialized += (s, e) => Application.Top.LayoutSubviews ();
}
public void MakeSliders (View v, List options)
{
var types = Enum.GetValues (typeof (SliderType)).Cast ().ToList ();
-
Slider prev = null;
foreach (var type in types) {
- var view = new Slider (options, Orientation.Horizontal) {
+ var view = new Slider (options) {
Title = type.ToString (),
X = 0,
- //X = Pos.Right (view) + 1,
Y = prev == null ? 0 : Pos.Bottom (prev),
- //Y = Pos.Center (),
- Width = Dim.Percent (50),
BorderStyle = LineStyle.Single,
Type = type,
- LegendsOrientation = Orientation.Horizontal,
- AllowEmpty = true,
+ AllowEmpty = true
};
v.Add (view);
prev = view;
- };
-
- var singleOptions = new List { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 };
+ }
- var single = new Slider (singleOptions, Orientation.Horizontal) {
- Title = "Actual slider",
+ var singleOptions = new List
+ { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 };
+ var single = new Slider (singleOptions) {
+ Title = "Continuous",
X = 0,
- //X = Pos.Right (view) + 1,
Y = prev == null ? 0 : Pos.Bottom (prev),
- //Y = Pos.Center (),
Type = SliderType.Single,
- //BorderStyle = LineStyle.Single,
- LegendsOrientation = Orientation.Horizontal,
- Width = Dim.Percent (50),
- AllowEmpty = false,
- //ShowSpacing = true
+ BorderStyle = LineStyle.Single,
+ AllowEmpty = false
};
single.LayoutStarted += (s, e) => {
if (single.Orientation == Orientation.Horizontal) {
- single.Style.SpaceChar = new Cell () { Rune = CM.Glyphs.HLine };
- single.Style.OptionChar = new Cell () { Rune = CM.Glyphs.HLine };
+ single.Style.SpaceChar = new Cell { Rune = CM.Glyphs.HLine };
+ single.Style.OptionChar = new Cell { Rune = CM.Glyphs.HLine };
} else {
- single.Style.SpaceChar = new Cell () { Rune = CM.Glyphs.VLine };
- single.Style.OptionChar = new Cell () { Rune = CM.Glyphs.VLine };
+ single.Style.SpaceChar = new Cell { Rune = CM.Glyphs.VLine };
+ single.Style.OptionChar = new Cell { Rune = CM.Glyphs.VLine };
}
};
- single.Style.SetChar = new Cell () { Rune = CM.Glyphs.ContinuousMeterSegment };
- single.Style.DragChar = new Cell () { Rune = CM.Glyphs.ContinuousMeterSegment };
+ single.Style.SetChar = new Cell { Rune = CM.Glyphs.ContinuousMeterSegment };
+ single.Style.DragChar = new Cell { Rune = CM.Glyphs.ContinuousMeterSegment };
v.Add (single);
- var label = new Label () {
- X = 0,
- Y = Pos.Bottom (single),
- Height = 1,
- Width = Dim.Width (single),
- Text = $"{single.GetSetOptions ().FirstOrDefault ()}"
- };
single.OptionsChanged += (s, e) => {
- label.Text = $"{e.Options.FirstOrDefault ().Key}";
+ single.Title = $"Continuous {e.Options.FirstOrDefault ().Key}";
};
- v.Add (label);
+ var oneOption = new List { "The Only Option" };
+ var one = new Slider (oneOption) {
+ Title = "One Option",
+ X = 0,
+ Y = prev == null ? 0 : Pos.Bottom (single),
+ Type = SliderType.Single,
+ BorderStyle = LineStyle.Single,
+ AllowEmpty = false
+ };
+ v.Add (one);
}
-}
+}
\ No newline at end of file
diff --git a/UnitTests/Views/SliderTests.cs b/UnitTests/Views/SliderTests.cs
index c3b4a628e3..67f890a43a 100644
--- a/UnitTests/Views/SliderTests.cs
+++ b/UnitTests/Views/SliderTests.cs
@@ -1,16 +1,11 @@
-using Xunit;
-using Terminal.Gui;
-using System;
+using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
-using System.Threading.Tasks;
+using Xunit;
namespace Terminal.Gui.ViewsTests;
public class SliderOptionTests {
-
-
[Fact]
public void Slider_Option_Default_Constructor ()
{
@@ -24,9 +19,9 @@ public void Slider_Option_Default_Constructor ()
public void Slider_Option_Values_Constructor ()
{
var o = new SliderOption ("1 thousand", new Rune ('y'), 1000);
- Assert.Equal ("1 thousand", o.Legend);
+ Assert.Equal ("1 thousand", o.Legend);
Assert.Equal (new Rune ('y'), o.LegendAbbr);
- Assert.Equal (1000, o.Data);
+ Assert.Equal (1000, o.Data);
}
[Fact]
@@ -87,7 +82,7 @@ public void SliderOption_ToString_WhenPopulated_WithInt ()
var sliderOption = new SliderOption {
Legend = "Lord flibble",
LegendAbbr = new Rune ('l'),
- Data = 1,
+ Data = 1
};
Assert.Equal ("{Legend=Lord flibble, LegendAbbr=l, Data=1}", sliderOption.ToString ());
@@ -100,7 +95,7 @@ public void SliderOption_ToString_WhenPopulated_WithSizeF ()
var sliderOption = new SliderOption {
Legend = "Lord flibble",
LegendAbbr = new Rune ('l'),
- Data = new SizeF(32,11),
+ Data = new SizeF (32, 11)
};
Assert.Equal ("{Legend=Lord flibble, LegendAbbr=l, Data={Width=32, Height=11}}", sliderOption.ToString ());
@@ -150,7 +145,6 @@ public void Constructor_Sets_Cancel_Default_To_False ()
}
}
-
public class SliderTests {
[Fact]
public void Constructor_Default ()
@@ -165,9 +159,9 @@ public void Constructor_Default ()
Assert.Equal (Orientation.Horizontal, slider.Orientation);
Assert.False (slider.AllowEmpty);
Assert.True (slider.ShowLegends);
- Assert.False (slider.ShowSpacing);
+ Assert.False (slider.ShowEndSpacing);
Assert.Equal (SliderType.Single, slider.Type);
- Assert.Equal (0, slider.InnerSpacing);
+ Assert.Equal (0, slider.InnerSpacing);
Assert.False (slider.AutoSize);
Assert.Equal (0, slider.FocusedOption);
}
@@ -192,7 +186,7 @@ public void OnOptionsChanged_Event_Raised ()
{
// Arrange
var slider = new Slider ();
- bool eventRaised = false;
+ var eventRaised = false;
slider.OptionsChanged += (sender, args) => eventRaised = true;
// Act
@@ -207,9 +201,9 @@ public void OnOptionFocused_Event_Raised ()
{
// Arrange
var slider = new Slider (new List { 1, 2, 3 });
- bool eventRaised = false;
+ var eventRaised = false;
slider.OptionFocused += (sender, args) => eventRaised = true;
- int newFocusedOption = 1;
+ var newFocusedOption = 1;
var args = new SliderEventArgs (new Dictionary> (), newFocusedOption);
// Act
@@ -224,10 +218,10 @@ public void OnOptionFocused_Event_Cancelled ()
{
// Arrange
var slider = new Slider (new List { 1, 2, 3 });
- bool eventRaised = false;
- bool cancel = false;
+ var eventRaised = false;
+ var cancel = false;
slider.OptionFocused += (sender, args) => eventRaised = true;
- int newFocusedOption = 1;
+ var newFocusedOption = 1;
// Create args with cancel set to false
cancel = false;
@@ -240,7 +234,7 @@ public void OnOptionFocused_Event_Cancelled ()
slider.OnOptionFocused (newFocusedOption, args);
// Assert
- Assert.True (eventRaised); // Event should be raised
+ Assert.True (eventRaised); // Event should be raised
Assert.Equal (newFocusedOption, slider.FocusedOption); // Focused option should change
// Create args with cancel set to true
@@ -253,7 +247,7 @@ public void OnOptionFocused_Event_Cancelled ()
slider.OnOptionFocused (2, args);
// Assert
- Assert.True (eventRaised); // Event should be raised
+ Assert.True (eventRaised); // Event should be raised
Assert.Equal (newFocusedOption, slider.FocusedOption); // Focused option should not change
}
@@ -271,7 +265,7 @@ public void TryGetPositionByOption_ValidOptionHorizontal_Success (int option, in
// 1--2--3--4
// Act
- bool result = slider.TryGetPositionByOption (option, out var position);
+ var result = slider.TryGetPositionByOption (option, out var position);
// Assert
Assert.True (result);
@@ -292,7 +286,7 @@ public void TryGetPositionByOption_ValidOptionVertical_Success (int option, int
slider.InnerSpacing = 2;
// Act
- bool result = slider.TryGetPositionByOption (option, out var position);
+ var result = slider.TryGetPositionByOption (option, out var position);
// Assert
Assert.True (result);
@@ -305,11 +299,11 @@ public void TryGetPositionByOption_InvalidOption_Failure ()
{
// Arrange
var slider = new Slider (new List { 1, 2, 3 });
- int option = -1;
+ var option = -1;
var expectedPosition = (-1, -1);
// Act
- bool result = slider.TryGetPositionByOption (option, out var position);
+ var result = slider.TryGetPositionByOption (option, out var position);
// Assert
Assert.False (result);
@@ -335,7 +329,7 @@ public void TryGetOptionByPosition_ValidPositionHorizontal_Success (int x, int y
// Arrange
// Act
- bool result = slider.TryGetOptionByPosition (x, y, threshold, out int option);
+ var result = slider.TryGetOptionByPosition (x, y, threshold, out var option);
// Assert
Assert.True (result);
@@ -366,12 +360,9 @@ public void TryGetOptionByPosition_ValidPositionVertical_Success (int x, int y,
// 7 |
// 8 |
// 9 4
- slider.CalcSpacingConfig ();
-
- // Arrange
// Act
- bool result = slider.TryGetOptionByPosition (x, y, threshold, out int option);
+ var result = slider.TryGetOptionByPosition (x, y, threshold, out var option);
// Assert
Assert.True (result);
@@ -384,13 +375,13 @@ public void TryGetOptionByPosition_InvalidPosition_Failure ()
{
// Arrange
var slider = new Slider (new List { 1, 2, 3 });
- int x = 10;
- int y = 10;
- int threshold = 2;
- int expectedOption = -1;
+ var x = 10;
+ var y = 10;
+ var threshold = 2;
+ var expectedOption = -1;
// Act
- bool result = slider.TryGetOptionByPosition (x, y, threshold, out int option);
+ var result = slider.TryGetOptionByPosition (x, y, threshold, out var option);
// Assert
Assert.False (result);
@@ -405,7 +396,7 @@ public void MovePlus_Should_MoveFocusRight_When_OptionIsAvailable ()
slider.AutoSize = true;
// Act
- bool result = slider.MovePlus ();
+ var result = slider.MovePlus ();
// Assert
Assert.True (result);
@@ -421,7 +412,7 @@ public void MovePlus_Should_NotMoveFocusRight_When_AtEnd ()
slider.FocusedOption = 3;
// Act
- bool result = slider.MovePlus ();
+ var result = slider.MovePlus ();
// Assert
Assert.False (result);
@@ -439,7 +430,7 @@ public void Set_Should_SetFocusedOption ()
// Act
slider.FocusedOption = 2;
- bool result = slider.Set ();
+ var result = slider.Set ();
// Assert
Assert.True (result);
@@ -459,14 +450,47 @@ public void Set_Should_Not_UnSetFocusedOption_When_EmptyNotAllowed ()
Assert.NotEmpty (slider.GetSetOptions ());
// Act
- bool result = slider.UnSetOption (slider.FocusedOption);
+ var result = slider.UnSetOption (slider.FocusedOption);
// Assert
Assert.False (result);
Assert.NotEmpty (slider.GetSetOptions ());
}
- // Add more tests for different scenarios and edge cases.
-}
+ [Fact]
+ void Set_Options_Throws_If_Null ()
+ {
+ // Arrange
+ var slider = new Slider ();
+
+ // Act/Assert
+ Assert.Throws (() => slider.Options = null);
+
+ }
+
+ [Fact]
+ void Set_Options_No_Legend_Throws ()
+ {
+ // Arrange
+ var slider = new Slider ();
+
+ // Act/Assert
+ Assert.Throws (() => slider.Options = null);
+
+ }
+
+ // https://github.com/gui-cs/Terminal.Gui/issues/3099
+ [Fact]
+ void One_Option_Does_Not_Throw ()
+ {
+ // Arrange
+ var slider = new Slider ();
+ slider.BeginInit ();
+ slider.EndInit ();
+ // Act/Assert
+ slider.Options = new List> { new () };
+ }
+ // Add more tests for different scenarios and edge cases.
+}
\ No newline at end of file