mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Merge branch 'master' of tig:migueldeicaza/gui.cs
This commit is contained in:
@@ -19,15 +19,14 @@ namespace Terminal.Gui {
|
||||
/// </remarks>
|
||||
public class DateField : TextField {
|
||||
bool isShort;
|
||||
|
||||
int longFieldLen = 10;
|
||||
int shortFieldLen = 8;
|
||||
int FieldLen { get { return isShort ? shortFieldLen : longFieldLen; } }
|
||||
string sepChar;
|
||||
string longFormat;
|
||||
string shortFormat;
|
||||
string Format { get { return isShort ? shortFormat : longFormat; } }
|
||||
|
||||
int FieldLen { get { return isShort ? shortFieldLen : longFieldLen; } }
|
||||
string Format { get { return isShort ? shortFormat : longFormat; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="DateField"/> at an absolute position and fixed size.
|
||||
@@ -37,20 +36,32 @@ namespace Terminal.Gui {
|
||||
/// <param name="date">Initial date contents.</param>
|
||||
/// <param name="isShort">If true, shows only two digits for the year.</param>
|
||||
public DateField (int x, int y, DateTime date, bool isShort = false) : base(x, y, isShort ? 10 : 12, "")
|
||||
{
|
||||
this.isShort = isShort;
|
||||
Initialize (date);
|
||||
}
|
||||
|
||||
public DateField (DateTime date) : base ("")
|
||||
{
|
||||
this.isShort = true;
|
||||
Width = FieldLen + 2;
|
||||
Initialize (date);
|
||||
}
|
||||
|
||||
void Initialize (DateTime date)
|
||||
{
|
||||
CultureInfo cultureInfo = CultureInfo.CurrentCulture;
|
||||
sepChar = cultureInfo.DateTimeFormat.DateSeparator;
|
||||
longFormat = GetLongFormat (cultureInfo.DateTimeFormat.ShortDatePattern);
|
||||
shortFormat = GetShortFormat(longFormat);
|
||||
this.isShort = isShort;
|
||||
shortFormat = GetShortFormat (longFormat);
|
||||
CursorPosition = 1;
|
||||
Date = date;
|
||||
Changed += DateField_Changed;
|
||||
}
|
||||
|
||||
void DateField_Changed(object sender, ustring e)
|
||||
void DateField_Changed (object sender, ustring e)
|
||||
{
|
||||
if (!DateTime.TryParseExact(Text.ToString(), Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result))
|
||||
if (!DateTime.TryParseExact (Text.ToString (), Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result))
|
||||
Text = e;
|
||||
}
|
||||
|
||||
@@ -70,7 +81,7 @@ namespace Terminal.Gui {
|
||||
|
||||
string GetShortFormat (string lf)
|
||||
{
|
||||
return lf.Replace("yyyy", "yy");
|
||||
return lf.Replace ("yyyy", "yy");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,85 +91,111 @@ namespace Terminal.Gui {
|
||||
/// </remarks>
|
||||
public DateTime Date {
|
||||
get {
|
||||
if (!DateTime.TryParseExact(Text.ToString(), Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result)) return new DateTime();
|
||||
if (!DateTime.TryParseExact (Text.ToString (), Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result)) return new DateTime ();
|
||||
return result;
|
||||
}
|
||||
set {
|
||||
this.Text = value.ToString(Format);
|
||||
this.Text = value.ToString (Format);
|
||||
}
|
||||
}
|
||||
|
||||
bool SetText(Rune key)
|
||||
{
|
||||
var text = TextModel.ToRunes(Text);
|
||||
var newText = text.GetRange(0, CursorPosition);
|
||||
newText.Add(key);
|
||||
if (CursorPosition < FieldLen)
|
||||
newText = newText.Concat(text.GetRange(CursorPosition + 1, text.Count - (CursorPosition + 1))).ToList();
|
||||
return SetText(ustring.Make(newText));
|
||||
/// <summary>
|
||||
/// Get or set the data format for the widget.
|
||||
/// </summary>
|
||||
public bool IsShortFormat {
|
||||
get => isShort;
|
||||
set {
|
||||
isShort = value;
|
||||
if (isShort)
|
||||
Width = 10;
|
||||
else
|
||||
Width = 12;
|
||||
var ro = ReadOnly;
|
||||
if (ro)
|
||||
ReadOnly = false;
|
||||
SetText (Text);
|
||||
ReadOnly = ro;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
|
||||
bool SetText(ustring text)
|
||||
bool SetText (Rune key)
|
||||
{
|
||||
ustring[] vals = text.Split(ustring.Make(sepChar));
|
||||
ustring[] frm = ustring.Make(Format).Split(ustring.Make(sepChar));
|
||||
var text = TextModel.ToRunes (Text);
|
||||
var newText = text.GetRange (0, CursorPosition);
|
||||
newText.Add (key);
|
||||
if (CursorPosition < FieldLen)
|
||||
newText = newText.Concat (text.GetRange (CursorPosition + 1, text.Count - (CursorPosition + 1))).ToList ();
|
||||
return SetText (ustring.Make (newText));
|
||||
}
|
||||
|
||||
bool SetText (ustring text)
|
||||
{
|
||||
ustring [] vals = text.Split (ustring.Make (sepChar));
|
||||
ustring [] frm = ustring.Make (Format).Split (ustring.Make (sepChar));
|
||||
bool isValidDate = true;
|
||||
int idx = GetFormatIndex(frm, "y");
|
||||
int year = Int32.Parse(vals[idx].ToString());
|
||||
int idx = GetFormatIndex (frm, "y");
|
||||
int year = Int32.Parse (vals [idx].ToString ());
|
||||
int month;
|
||||
int day;
|
||||
idx = GetFormatIndex(frm, "M");
|
||||
if (Int32.Parse(vals[idx].ToString()) < 1) {
|
||||
idx = GetFormatIndex (frm, "M");
|
||||
if (Int32.Parse (vals [idx].ToString ()) < 1) {
|
||||
isValidDate = false;
|
||||
month = 1;
|
||||
vals[idx] = "1";
|
||||
} else if (Int32.Parse(vals[idx].ToString()) > 12) {
|
||||
vals [idx] = "1";
|
||||
} else if (Int32.Parse (vals [idx].ToString ()) > 12) {
|
||||
isValidDate = false;
|
||||
month = 12;
|
||||
vals[idx] = "12";
|
||||
vals [idx] = "12";
|
||||
} else
|
||||
month = Int32.Parse(vals[idx].ToString());
|
||||
idx = GetFormatIndex(frm, "d");
|
||||
if (Int32.Parse(vals[idx].ToString()) < 1) {
|
||||
month = Int32.Parse (vals [idx].ToString ());
|
||||
idx = GetFormatIndex (frm, "d");
|
||||
if (Int32.Parse (vals [idx].ToString ()) < 1) {
|
||||
isValidDate = false;
|
||||
day = 1;
|
||||
vals[idx] = "1";
|
||||
} else if (Int32.Parse(vals[idx].ToString()) > 31) {
|
||||
vals [idx] = "1";
|
||||
} else if (Int32.Parse (vals [idx].ToString ()) > 31) {
|
||||
isValidDate = false;
|
||||
day = DateTime.DaysInMonth(year, month);
|
||||
vals[idx] = day.ToString();
|
||||
day = DateTime.DaysInMonth (year, month);
|
||||
vals [idx] = day.ToString ();
|
||||
} else
|
||||
day = Int32.Parse(vals[idx].ToString());
|
||||
string date = GetData(month, day, year, frm);
|
||||
day = Int32.Parse (vals [idx].ToString ());
|
||||
string date = GetDate (month, day, year, frm);
|
||||
Text = date;
|
||||
|
||||
if (!DateTime.TryParseExact(date, Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result) ||
|
||||
if (!DateTime.TryParseExact (date, Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result) ||
|
||||
!isValidDate)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
string GetData(int month, int day, int year, ustring[] fm)
|
||||
string GetDate (int month, int day, int year, ustring [] fm)
|
||||
{
|
||||
string data = " ";
|
||||
string date = " ";
|
||||
for (int i = 0; i < fm.Length; i++) {
|
||||
if (fm[i].Contains("M"))
|
||||
data += $"{month,2:00}";
|
||||
else if (fm[i].Contains("d"))
|
||||
data += $"{day,2:00}";
|
||||
else
|
||||
data += isShort ? $"{year,2:00}" : $"{year,4:0000}";
|
||||
if (fm [i].Contains ("M")) {
|
||||
date += $"{month,2:00}";
|
||||
} else if (fm [i].Contains ("d")) {
|
||||
date += $"{day,2:00}";
|
||||
} else {
|
||||
if (!isShort && year.ToString ().Length == 2) {
|
||||
var y = DateTime.Now.Year.ToString ();
|
||||
date += y.Substring (0, 2) + year.ToString ();
|
||||
} else {
|
||||
date += $"{year,2:00}";
|
||||
}
|
||||
}
|
||||
if (i < 2)
|
||||
data += $"{sepChar}";
|
||||
date += $"{sepChar}";
|
||||
}
|
||||
return data;
|
||||
return date;
|
||||
}
|
||||
|
||||
int GetFormatIndex(ustring[] fm, string t)
|
||||
int GetFormatIndex (ustring [] fm, string t)
|
||||
{
|
||||
int idx = -1;
|
||||
for (int i = 0; i < fm.Length; i++) {
|
||||
if (fm[i].Contains(t)) {
|
||||
if (fm [i].Contains (t)) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
@@ -166,25 +203,25 @@ namespace Terminal.Gui {
|
||||
return idx;
|
||||
}
|
||||
|
||||
void IncCursorPosition()
|
||||
void IncCursorPosition ()
|
||||
{
|
||||
if (CursorPosition == FieldLen)
|
||||
return;
|
||||
if (Text[++CursorPosition] == sepChar.ToCharArray()[0])
|
||||
if (Text [++CursorPosition] == sepChar.ToCharArray () [0])
|
||||
CursorPosition++;
|
||||
}
|
||||
|
||||
void DecCursorPosition()
|
||||
void DecCursorPosition ()
|
||||
{
|
||||
if (CursorPosition == 1)
|
||||
return;
|
||||
if (Text[--CursorPosition] == sepChar.ToCharArray()[0])
|
||||
if (Text [--CursorPosition] == sepChar.ToCharArray () [0])
|
||||
CursorPosition--;
|
||||
}
|
||||
|
||||
void AdjCursorPosition()
|
||||
void AdjCursorPosition ()
|
||||
{
|
||||
if (Text[CursorPosition] == sepChar.ToCharArray()[0])
|
||||
if (Text [CursorPosition] == sepChar.ToCharArray () [0])
|
||||
CursorPosition++;
|
||||
}
|
||||
|
||||
@@ -194,13 +231,13 @@ namespace Terminal.Gui {
|
||||
switch (kb.Key) {
|
||||
case Key.DeleteChar:
|
||||
case Key.ControlD:
|
||||
SetText('0');
|
||||
SetText ('0');
|
||||
break;
|
||||
|
||||
case Key.Delete:
|
||||
case Key.Backspace:
|
||||
SetText('0');
|
||||
DecCursorPosition();
|
||||
SetText ('0');
|
||||
DecCursorPosition ();
|
||||
break;
|
||||
|
||||
// Home, C-A
|
||||
@@ -211,7 +248,7 @@ namespace Terminal.Gui {
|
||||
|
||||
case Key.CursorLeft:
|
||||
case Key.ControlB:
|
||||
DecCursorPosition();
|
||||
DecCursorPosition ();
|
||||
break;
|
||||
|
||||
case Key.End:
|
||||
@@ -221,15 +258,15 @@ namespace Terminal.Gui {
|
||||
|
||||
case Key.CursorRight:
|
||||
case Key.ControlF:
|
||||
IncCursorPosition();
|
||||
IncCursorPosition ();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore non-numeric characters.
|
||||
if (kb.Key < (Key)((int)'0') || kb.Key > (Key)((int)'9'))
|
||||
return false;
|
||||
if (SetText(TextModel.ToRunes(ustring.Make((uint)kb.Key)).First()))
|
||||
IncCursorPosition();
|
||||
if (SetText (TextModel.ToRunes (ustring.Make ((uint)kb.Key)).First ()))
|
||||
IncCursorPosition ();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
@@ -238,10 +275,10 @@ namespace Terminal.Gui {
|
||||
///<inheritdoc cref="MouseEvent(Gui.MouseEvent)"/>
|
||||
public override bool MouseEvent(MouseEvent ev)
|
||||
{
|
||||
if (!ev.Flags.HasFlag(MouseFlags.Button1Clicked))
|
||||
if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked))
|
||||
return false;
|
||||
if (!HasFocus)
|
||||
SuperView.SetFocus(this);
|
||||
SuperView.SetFocus (this);
|
||||
|
||||
var point = ev.X;
|
||||
if (point > FieldLen)
|
||||
@@ -249,7 +286,7 @@ namespace Terminal.Gui {
|
||||
if (point < 1)
|
||||
point = 1;
|
||||
CursorPosition = point;
|
||||
AdjCursorPosition();
|
||||
AdjCursorPosition ();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,13 +183,13 @@ namespace Terminal.Gui {
|
||||
break;
|
||||
case TextAlignment.Justified:
|
||||
Recalc ();
|
||||
x = Frame.Left;
|
||||
x = Bounds.Left;
|
||||
break;
|
||||
case TextAlignment.Right:
|
||||
x = Frame.Right - str.Length;
|
||||
x = Bounds.Right - str.Length;
|
||||
break;
|
||||
case TextAlignment.Centered:
|
||||
x = Frame.Left + (Frame.Width - str.Length) / 2;
|
||||
x = Bounds.Left + (Bounds.Width - str.Length) / 2;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException ();
|
||||
|
||||
@@ -21,10 +21,11 @@ namespace Terminal.Gui {
|
||||
|
||||
int longFieldLen = 8;
|
||||
int shortFieldLen = 5;
|
||||
int FieldLen { get { return isShort ? shortFieldLen : longFieldLen; } }
|
||||
string sepChar;
|
||||
string longFormat;
|
||||
string shortFormat;
|
||||
|
||||
int FieldLen { get { return isShort ? shortFieldLen : longFieldLen; } }
|
||||
string Format { get { return isShort ? shortFormat : longFormat; } }
|
||||
|
||||
|
||||
@@ -36,12 +37,24 @@ namespace Terminal.Gui {
|
||||
/// <param name="time">Initial time contents.</param>
|
||||
/// <param name="isShort">If true, the seconds are hidden.</param>
|
||||
public TimeField (int x, int y, DateTime time, bool isShort = false) : base (x, y, isShort ? 7 : 10, "")
|
||||
{
|
||||
this.isShort = isShort;
|
||||
Initialize (time);
|
||||
}
|
||||
|
||||
public TimeField (DateTime time) : base ("")
|
||||
{
|
||||
this.isShort = true;
|
||||
Width = FieldLen + 2;
|
||||
Initialize (time);
|
||||
}
|
||||
|
||||
void Initialize (DateTime time)
|
||||
{
|
||||
CultureInfo cultureInfo = CultureInfo.CurrentCulture;
|
||||
sepChar = cultureInfo.DateTimeFormat.TimeSeparator;
|
||||
longFormat = $" HH{sepChar}mm{sepChar}ss";
|
||||
shortFormat = $" HH{sepChar}mm";
|
||||
this.isShort = isShort;
|
||||
CursorPosition = 1;
|
||||
Time = time;
|
||||
Changed += TimeField_Changed;
|
||||
@@ -68,6 +81,26 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or set the data format for the widget.
|
||||
/// </summary>
|
||||
public bool IsShortFormat {
|
||||
get => isShort;
|
||||
set {
|
||||
isShort = value;
|
||||
if (isShort)
|
||||
Width = 7;
|
||||
else
|
||||
Width = 10;
|
||||
var ro = ReadOnly;
|
||||
if (ro)
|
||||
ReadOnly = false;
|
||||
SetText (Text);
|
||||
ReadOnly = ro;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
|
||||
bool SetText (Rune key)
|
||||
{
|
||||
var text = TextModel.ToRunes (Text);
|
||||
@@ -84,7 +117,7 @@ namespace Terminal.Gui {
|
||||
bool isValidTime = true;
|
||||
int hour = Int32.Parse (vals [0].ToString ());
|
||||
int minute = Int32.Parse (vals [1].ToString ());
|
||||
int second = isShort ? 0 : Int32.Parse (vals [2].ToString ());
|
||||
int second = isShort ? 0 : vals.Length > 2 ? Int32.Parse (vals [2].ToString ()) : 0;
|
||||
if (hour < 0) {
|
||||
isValidTime = false;
|
||||
hour = 0;
|
||||
|
||||
@@ -83,11 +83,11 @@ namespace UICatalog {
|
||||
};
|
||||
Win.Add (keyPressedLabel);
|
||||
// BUGBUG: Label is not positioning right with Pos, so using TextField instead
|
||||
var labelKeypress = new TextField ("") {
|
||||
X = Pos.Right (keyPressedLabel) + 1,
|
||||
var labelKeypress = new Label ("") {
|
||||
X = Pos.Left (edit),
|
||||
Y = Pos.Top (keyPressedLabel),
|
||||
Width = 20,
|
||||
//TextAlignment = Terminal.Gui.TextAlignment.Left,
|
||||
TextAlignment = Terminal.Gui.TextAlignment.Centered,
|
||||
ColorScheme = Colors.Error,
|
||||
};
|
||||
Win.Add (labelKeypress);
|
||||
|
||||
Reference in New Issue
Block a user