mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
Fixed a layout bug that preventing the redrawing on Pos and Dim changes. Now the TextAlignment is working well. I move them to the view for a generic uses to others views.
This commit is contained in:
@@ -17,6 +17,27 @@ using System.Linq;
|
||||
using NStack;
|
||||
|
||||
namespace Terminal.Gui {
|
||||
/// <summary>
|
||||
/// Text alignment enumeration, controls how text is displayed.
|
||||
/// </summary>
|
||||
public enum TextAlignment {
|
||||
/// <summary>
|
||||
/// Aligns the text to the left of the frame.
|
||||
/// </summary>
|
||||
Left,
|
||||
/// <summary>
|
||||
/// Aligns the text to the right side of the frame.
|
||||
/// </summary>
|
||||
Right,
|
||||
/// <summary>
|
||||
/// Centers the text in the frame.
|
||||
/// </summary>
|
||||
Centered,
|
||||
/// <summary>
|
||||
/// Shows the text as justified text in the frame.
|
||||
/// </summary>
|
||||
Justified
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the LayoutStyle for a view, if Absolute, during LayoutSubviews, the
|
||||
@@ -299,6 +320,7 @@ namespace Terminal.Gui {
|
||||
set {
|
||||
x = value;
|
||||
SetNeedsLayout ();
|
||||
SetNeedsDisplay (frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +336,7 @@ namespace Terminal.Gui {
|
||||
set {
|
||||
y = value;
|
||||
SetNeedsLayout ();
|
||||
SetNeedsDisplay (frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,6 +354,7 @@ namespace Terminal.Gui {
|
||||
set {
|
||||
width = value;
|
||||
SetNeedsLayout ();
|
||||
SetNeedsDisplay (frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,6 +368,7 @@ namespace Terminal.Gui {
|
||||
set {
|
||||
height = value;
|
||||
SetNeedsLayout ();
|
||||
SetNeedsDisplay (frame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1457,7 +1482,7 @@ namespace Terminal.Gui {
|
||||
/// <param name="hotKey">The hot-key to look for.</param>
|
||||
/// <param name="hotPos">The returning hot-key position.</param>
|
||||
/// <param name="showHotKey">The character immediately to the right relative to the hot-key position</param>
|
||||
/// <returns></returns>
|
||||
/// <returns>It aims to facilitate the preparation for <see cref="TextAlignment"/> procedures.</returns>
|
||||
public virtual ustring GetTextFromHotKey(ustring text, Rune hotKey, out int hotPos, out Rune showHotKey)
|
||||
{
|
||||
Rune hot_key = (Rune)0;
|
||||
@@ -1471,7 +1496,7 @@ namespace Terminal.Gui {
|
||||
if (c == hotKey) {
|
||||
hot_pos = i;
|
||||
} else if (hot_pos > -1) {
|
||||
hot_key = (char)c;
|
||||
hot_key = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1482,10 +1507,12 @@ namespace Terminal.Gui {
|
||||
// Use first upper-case char if there are no hot-key in the text.
|
||||
i = 0;
|
||||
foreach (Rune c in shown_text) {
|
||||
if (Rune.IsUpper (c)) {
|
||||
hot_key = (char)c;
|
||||
hot_pos = i;
|
||||
break;
|
||||
if ((char)c != 0xFFFD) {
|
||||
if (Rune.IsUpper (c)) {
|
||||
hot_key = c;
|
||||
hot_pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -1514,6 +1541,87 @@ namespace Terminal.Gui {
|
||||
return shown_text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A generic virtual method at the level of View to manipulate any hot-keys with <see cref="TextAlignment"/> process.
|
||||
/// </summary>
|
||||
/// <param name="shown_text">The text to manipulate to align.</param>
|
||||
/// <param name="hot_pos">The passed in hot-key position.</param>
|
||||
/// <param name="c_hot_pos">The returning hot-key position.</param>
|
||||
/// <param name="textAlignment">The <see cref="TextAlignment"/> to align to.</param>
|
||||
/// <returns>It performs the <see cref="TextAlignment"/> process to the caller.</returns>
|
||||
public virtual ustring GetTextAlignment (ustring shown_text, int hot_pos, out int c_hot_pos, TextAlignment textAlignment)
|
||||
{
|
||||
int start;
|
||||
var caption = shown_text;
|
||||
c_hot_pos = hot_pos;
|
||||
|
||||
if (Frame.Width > shown_text.Length + 1) {
|
||||
switch (textAlignment) {
|
||||
case TextAlignment.Left:
|
||||
caption += new string (' ', Frame.Width - caption.RuneCount);
|
||||
break;
|
||||
case TextAlignment.Right:
|
||||
start = Frame.Width - caption.RuneCount;
|
||||
caption = $"{new string (' ', Frame.Width - caption.RuneCount)}{caption}";
|
||||
if (c_hot_pos > -1) {
|
||||
c_hot_pos += start;
|
||||
}
|
||||
break;
|
||||
case TextAlignment.Centered:
|
||||
start = Frame.Width / 2 - caption.RuneCount / 2;
|
||||
caption = $"{new string (' ', start)}{caption}{new string (' ', Frame.Width - caption.RuneCount - start)}";
|
||||
if (c_hot_pos > -1) {
|
||||
c_hot_pos += start;
|
||||
}
|
||||
break;
|
||||
case TextAlignment.Justified:
|
||||
var words = caption.Split (" ");
|
||||
var wLen = GetWordsLength (words, c_hot_pos, out int runeCount, out int w_hot_pos);
|
||||
var space = (Frame.Width - runeCount) / (caption.Length - wLen);
|
||||
caption = "";
|
||||
for (int i = 0; i < words.Length; i++) {
|
||||
if (i == words.Length - 1) {
|
||||
caption += new string (' ', Frame.Width - caption.RuneCount - 1);
|
||||
caption += words [i];
|
||||
} else {
|
||||
caption += words [i];
|
||||
}
|
||||
if (i < words.Length - 1) {
|
||||
caption += new string (' ', space);
|
||||
}
|
||||
}
|
||||
if (c_hot_pos > -1) {
|
||||
if (wLen - runeCount == 0) {
|
||||
c_hot_pos += (wLen - runeCount == 0 ? w_hot_pos * (space) - space - w_hot_pos + 1 : space + wLen - runeCount);
|
||||
} else {
|
||||
c_hot_pos += space + wLen - runeCount;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return caption;
|
||||
}
|
||||
|
||||
int GetWordsLength (ustring [] words, int hotPos, out int runeCount, out int wordHotPos)
|
||||
{
|
||||
int length = 0;
|
||||
int rCount = 0;
|
||||
int wHotPos = -1;
|
||||
for (int i = 0; i < words.Length; i++) {
|
||||
if (wHotPos == -1 && rCount + words [i].RuneCount >= hotPos)
|
||||
wHotPos = i;
|
||||
length += words [i].Length;
|
||||
rCount += words [i].RuneCount;
|
||||
}
|
||||
if (wHotPos == -1 && hotPos > -1)
|
||||
wHotPos = words.Length;
|
||||
runeCount = rCount;
|
||||
wordHotPos = wHotPos;
|
||||
return length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pretty prints the View
|
||||
/// </summary>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using NStack;
|
||||
|
||||
namespace Terminal.Gui {
|
||||
@@ -137,9 +138,7 @@ namespace Terminal.Gui {
|
||||
}
|
||||
|
||||
set {
|
||||
if (text?.Length != value?.Length) {
|
||||
SetWidthHeight (value, is_default);
|
||||
}
|
||||
SetWidthHeight (value, is_default);
|
||||
text = value;
|
||||
Update ();
|
||||
}
|
||||
@@ -152,7 +151,7 @@ namespace Terminal.Gui {
|
||||
get => textAlignment;
|
||||
set {
|
||||
textAlignment = value;
|
||||
SetNeedsDisplay ();
|
||||
Update ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,51 +180,8 @@ namespace Terminal.Gui {
|
||||
Driver.SetAttribute (HasFocus ? ColorScheme.Focus : ColorScheme.Normal);
|
||||
Move (0, 0);
|
||||
|
||||
var caption = shown_text;
|
||||
c_hot_pos = hot_pos;
|
||||
int start;
|
||||
|
||||
if (Frame.Width > shown_text.Length + 1) {
|
||||
switch (TextAlignment) {
|
||||
case TextAlignment.Left:
|
||||
caption += new string (' ', Frame.Width - caption.RuneCount);
|
||||
break;
|
||||
case TextAlignment.Right:
|
||||
start = Frame.Width - caption.RuneCount;
|
||||
caption = $"{new string (' ', Frame.Width - caption.RuneCount)}{caption}";
|
||||
if (c_hot_pos > -1) {
|
||||
c_hot_pos += start;
|
||||
}
|
||||
break;
|
||||
case TextAlignment.Centered:
|
||||
start = Frame.Width / 2 - caption.RuneCount / 2;
|
||||
caption = $"{new string (' ', start)}{caption}{new string (' ', Frame.Width - caption.RuneCount - start)}";
|
||||
if (c_hot_pos > -1) {
|
||||
c_hot_pos += start;
|
||||
}
|
||||
break;
|
||||
case TextAlignment.Justified:
|
||||
var words = caption.Split (" ");
|
||||
var wLen = GetWordsLength (words, out int runeCount);
|
||||
var space = (Frame.Width - runeCount) / (caption.Length - wLen);
|
||||
caption = "";
|
||||
for (int i = 0; i < words.Length; i++) {
|
||||
if (i == words.Length - 1) {
|
||||
caption += new string (' ', Frame.Width - caption.RuneCount - 1);
|
||||
caption += words [i];
|
||||
} else {
|
||||
caption += words [i];
|
||||
}
|
||||
if (i < words.Length - 1) {
|
||||
caption += new string (' ', space);
|
||||
}
|
||||
}
|
||||
if (c_hot_pos > -1) {
|
||||
c_hot_pos += space - 1 + (wLen - runeCount == 0 ? 0 : wLen - runeCount + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
var caption = GetTextAlignment (shown_text, hot_pos, out int s_hot_pos, TextAlignment);
|
||||
c_hot_pos = s_hot_pos;
|
||||
|
||||
Driver.AddStr (caption);
|
||||
|
||||
@@ -236,18 +192,6 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
int GetWordsLength (ustring [] words, out int runeCount)
|
||||
{
|
||||
int length = 0;
|
||||
int rCount = 0;
|
||||
for (int i = 0; i < words.Length; i++) {
|
||||
length += words [i].Length;
|
||||
rCount += words [i].RuneCount;
|
||||
}
|
||||
runeCount = rCount;
|
||||
return length;
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void PositionCursor ()
|
||||
{
|
||||
|
||||
@@ -11,28 +11,6 @@ using System.Linq;
|
||||
using NStack;
|
||||
|
||||
namespace Terminal.Gui {
|
||||
/// <summary>
|
||||
/// Text alignment enumeration, controls how text is displayed.
|
||||
/// </summary>
|
||||
public enum TextAlignment {
|
||||
/// <summary>
|
||||
/// Aligns the text to the left of the frame.
|
||||
/// </summary>
|
||||
Left,
|
||||
/// <summary>
|
||||
/// Aligns the text to the right side of the frame.
|
||||
/// </summary>
|
||||
Right,
|
||||
/// <summary>
|
||||
/// Centers the text in the frame.
|
||||
/// </summary>
|
||||
Centered,
|
||||
/// <summary>
|
||||
/// Shows the text as justified text in the frame.
|
||||
/// </summary>
|
||||
Justified
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Label <see cref="View"/> displays a string at a given position and supports multiple lines separted by newline characters.
|
||||
/// </summary>
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace UICatalog {
|
||||
textChanger.Clicked = () => textChanger.Text += "!";
|
||||
|
||||
Win.Add (button = new Button ("Lets see if this will move as \"Text Changer\" grows") {
|
||||
X = Pos.Right(textChanger) + 2,
|
||||
X = Pos.Right (textChanger) + 2,
|
||||
Y = Pos.Y (textChanger),
|
||||
});
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace UICatalog {
|
||||
var computedFrame = new FrameView ("Computed Layout") {
|
||||
X = 0,
|
||||
Y = Pos.Bottom (removeButton) + 1,
|
||||
Width = Dim.Percent(50),
|
||||
Width = Dim.Percent (50),
|
||||
Height = 5
|
||||
};
|
||||
Win.Add (computedFrame);
|
||||
@@ -113,7 +113,7 @@ namespace UICatalog {
|
||||
// Demonstrates how changing the View.Frame property can move Views
|
||||
var moveBtn = new Button ("Move This \u263b Button _via Pos") {
|
||||
X = 0,
|
||||
Y = Pos.Center() - 1,
|
||||
Y = Pos.Center () - 1,
|
||||
Width = 30,
|
||||
ColorScheme = Colors.Error,
|
||||
};
|
||||
@@ -124,7 +124,7 @@ namespace UICatalog {
|
||||
computedFrame.Add (moveBtn);
|
||||
|
||||
// Demonstrates how changing the View.Frame property can SIZE Views (#583)
|
||||
var sizeBtn = new Button ("Size This \u263a Button _via Pos") {
|
||||
var sizeBtn = new Button ("Size This Button _via Pos") {
|
||||
X = 0,
|
||||
Y = Pos.Center () + 1,
|
||||
Width = 30,
|
||||
@@ -132,14 +132,14 @@ namespace UICatalog {
|
||||
};
|
||||
sizeBtn.Clicked = () => {
|
||||
sizeBtn.Width = sizeBtn.Frame.Width + 5;
|
||||
computedFrame.LayoutSubviews (); // BUGBUG: This call should not be needed. View.X is not causing relayout correctly
|
||||
//computedFrame.LayoutSubviews (); // FIXED: This call should not be needed. View.X is not causing relayout correctly
|
||||
};
|
||||
computedFrame.Add (sizeBtn);
|
||||
|
||||
var absoluteFrame = new FrameView ("Absolute Layout") {
|
||||
X = Pos.Right(computedFrame),
|
||||
X = Pos.Right (computedFrame),
|
||||
Y = Pos.Bottom (removeButton) + 1,
|
||||
Width = Dim.Fill(),
|
||||
Width = Dim.Fill (),
|
||||
Height = 5
|
||||
};
|
||||
Win.Add (absoluteFrame);
|
||||
@@ -172,34 +172,6 @@ namespace UICatalog {
|
||||
X = 4,
|
||||
Y = Pos.Bottom (label) + 1,
|
||||
SelectedItem = 2,
|
||||
SelectedItemChanged = (args) => {
|
||||
switch (args.SelectedItem) {
|
||||
case 0:
|
||||
moveBtn.TextAlignment = TextAlignment.Left;
|
||||
sizeBtn.TextAlignment = TextAlignment.Left;
|
||||
moveBtnA.TextAlignment = TextAlignment.Left;
|
||||
sizeBtnA.TextAlignment = TextAlignment.Left;
|
||||
break;
|
||||
case 1:
|
||||
moveBtn.TextAlignment = TextAlignment.Right;
|
||||
sizeBtn.TextAlignment = TextAlignment.Right;
|
||||
moveBtnA.TextAlignment = TextAlignment.Right;
|
||||
sizeBtnA.TextAlignment = TextAlignment.Right;
|
||||
break;
|
||||
case 2:
|
||||
moveBtn.TextAlignment = TextAlignment.Centered;
|
||||
sizeBtn.TextAlignment = TextAlignment.Centered;
|
||||
moveBtnA.TextAlignment = TextAlignment.Centered;
|
||||
sizeBtnA.TextAlignment = TextAlignment.Centered;
|
||||
break;
|
||||
case 3:
|
||||
moveBtn.TextAlignment = TextAlignment.Justified;
|
||||
sizeBtn.TextAlignment = TextAlignment.Justified;
|
||||
moveBtnA.TextAlignment = TextAlignment.Justified;
|
||||
sizeBtnA.TextAlignment = TextAlignment.Justified;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
Win.Add (radioGroup);
|
||||
|
||||
@@ -208,7 +180,9 @@ namespace UICatalog {
|
||||
{
|
||||
// Remove the '_'
|
||||
var i = txt.IndexOf ('_');
|
||||
var start = txt [0, i];
|
||||
ustring start = "";
|
||||
if (i > -1)
|
||||
start = txt [0, i];
|
||||
txt = start + txt [i + 1, txt.Length];
|
||||
|
||||
// Move over one or go to start
|
||||
@@ -224,9 +198,11 @@ namespace UICatalog {
|
||||
return txt;
|
||||
}
|
||||
|
||||
var moveHotKeyBtn = new Button ("Click to Change th_is Button's Hotkey") {
|
||||
var mhkb = "Click to Change th_is Button's Hotkey";
|
||||
var moveHotKeyBtn = new Button (mhkb) {
|
||||
X = 2,
|
||||
Y = Pos.Bottom (radioGroup) + 1,
|
||||
Width = mhkb.Length + 10,
|
||||
ColorScheme = Colors.TopLevel,
|
||||
};
|
||||
moveHotKeyBtn.Clicked = () => {
|
||||
@@ -234,15 +210,54 @@ namespace UICatalog {
|
||||
};
|
||||
Win.Add (moveHotKeyBtn);
|
||||
|
||||
var moveUnicodeHotKeyBtn = new Button (" ~ s gui.cs master ↑10 = Сохранить") {
|
||||
var muhkb = " ~ s gui.cs master ↑10 = Сохранить";
|
||||
var moveUnicodeHotKeyBtn = new Button (muhkb) {
|
||||
X = Pos.Right (moveHotKeyBtn) + 6,
|
||||
Y = Pos.Bottom (radioGroup) + 1,
|
||||
Width = muhkb.Length + 30,
|
||||
ColorScheme = Colors.TopLevel,
|
||||
};
|
||||
moveUnicodeHotKeyBtn.Clicked = () => {
|
||||
moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
|
||||
};
|
||||
Win.Add (moveUnicodeHotKeyBtn);
|
||||
|
||||
radioGroup.SelectedItemChanged += (args) => {
|
||||
switch (args.SelectedItem) {
|
||||
case 0:
|
||||
moveBtn.TextAlignment = TextAlignment.Left;
|
||||
sizeBtn.TextAlignment = TextAlignment.Left;
|
||||
moveBtnA.TextAlignment = TextAlignment.Left;
|
||||
sizeBtnA.TextAlignment = TextAlignment.Left;
|
||||
moveHotKeyBtn.TextAlignment = TextAlignment.Left;
|
||||
moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Left;
|
||||
break;
|
||||
case 1:
|
||||
moveBtn.TextAlignment = TextAlignment.Right;
|
||||
sizeBtn.TextAlignment = TextAlignment.Right;
|
||||
moveBtnA.TextAlignment = TextAlignment.Right;
|
||||
sizeBtnA.TextAlignment = TextAlignment.Right;
|
||||
moveHotKeyBtn.TextAlignment = TextAlignment.Right;
|
||||
moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Right;
|
||||
break;
|
||||
case 2:
|
||||
moveBtn.TextAlignment = TextAlignment.Centered;
|
||||
sizeBtn.TextAlignment = TextAlignment.Centered;
|
||||
moveBtnA.TextAlignment = TextAlignment.Centered;
|
||||
sizeBtnA.TextAlignment = TextAlignment.Centered;
|
||||
moveHotKeyBtn.TextAlignment = TextAlignment.Centered;
|
||||
moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Centered;
|
||||
break;
|
||||
case 3:
|
||||
moveBtn.TextAlignment = TextAlignment.Justified;
|
||||
sizeBtn.TextAlignment = TextAlignment.Justified;
|
||||
moveBtnA.TextAlignment = TextAlignment.Justified;
|
||||
sizeBtnA.TextAlignment = TextAlignment.Justified;
|
||||
moveHotKeyBtn.TextAlignment = TextAlignment.Justified;
|
||||
moveUnicodeHotKeyBtn.TextAlignment = TextAlignment.Justified;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user