Files
Quentin Bray 6ffa63b923 Apply R# clean-up for reliability (#877)
* Apply R# clean-up for reliability

- Migrate to NUnit4 Assert.That
- Update dependencise versions
- Fix LangVersion to 9.0 (until net core migration)
- Reformat code
- Apply 'var' style (easier for refactoring)
- Remove redundant parentheses
- Add braces on every condition blocks (1 line)
- Uses new null checking patterns
- Uses AutoProperties when possible
- Uses string scalar type instead of class
- Clean usings
- Add .orig files in git ignore
- Rename some properties to respect defined conventions and US format definition
	- ID -> Id
	- BPM -> Bpm
	- Finish -> End

* Update R# settings according to the clean-up made
2026-06-22 19:52:06 +02:00

507 lines
14 KiB
C#

#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Xml.Serialization;
namespace VocaluxeLib.Menu
{
[XmlType("Text")]
public struct SThemeText
{
[XmlAttribute(AttributeName = "Name")]
public string Name;
public float X;
public float Y;
public float Z;
[XmlElement("H")]
public float FontHeight;
[XmlElement("MaxW")]
public float MaxWidth;
public SThemeColor Color;
public SThemeColor SelColor; //for Buttons
public EAlignment Align;
public EHAlignment ResizeAlign;
[XmlElement("Style")]
public EStyle FontStyle;
[XmlElement("Font")]
public string FontFamily;
public string Text;
public SReflection? Reflection;
public bool? AllMonitors;
}
public sealed class CText : CMenuElementBase, IMenuElement, IThemeable, IFontObserver
{
private SThemeText _Theme;
private readonly int _PartyModeId = -1;
private int _TranslationId = -1;
public string GetThemeName()
{
return _Theme.Name;
}
public bool ThemeLoaded { get; private set; }
private bool _ButtonText;
private bool _PositionNeedsUpdate = true;
public override float X
{
set
{
if (Math.Abs(X - value) > 0.01)
{
base.X = value;
_PositionNeedsUpdate = true;
}
}
}
public override float Y
{
set
{
if (Math.Abs(Y - value) > 0.01)
{
base.Y = value;
_PositionNeedsUpdate = true;
}
}
}
public override float W
{
set
{
if (Math.Abs(W - value) > 0.01)
{
base.W = value;
_PositionNeedsUpdate = true;
}
}
}
private EAlignment _Align = EAlignment.Left;
public EAlignment Align
{
get { return _Align; }
set
{
if (_Align != value)
{
_Align = value;
_PositionNeedsUpdate = true;
}
}
}
private EHAlignment _ResizeAlign = EHAlignment.Center;
public EHAlignment ResizeAlign
{
get { return _ResizeAlign; }
set
{
if (_ResizeAlign != value)
{
_ResizeAlign = value;
_PositionNeedsUpdate = true;
}
}
}
private CFont _Font = new CFont();
public CFont Font
{
get { return _Font; }
set
{
if (!_Font.Equals(value))
{
_Font.RemoveObserver(this);
_Font = value;
_Font.AddObserver(this);
_PositionNeedsUpdate = true;
}
}
}
/// <summary>
/// Gets set in _UpdateTextPosition!
/// </summary>
private SRectF _Rect;
public override SRectF Rect
{
get
{
_UpdateTextPosition();
return _Rect;
}
}
public bool Selectable
{
get { return false; }
}
public SColorF Color; //normal Color
public SColorF SelColor; //selected Color for Buttons
private float _ReflectionSpace;
private float _ReflectionHeight;
public bool AllMonitors = true;
public string Text
{
get { return _Theme.Text; }
set
{
var translation = CBase.Language.Translate(value, _TranslationId);
if (_Theme.Text != value || translation != TranslatedText)
{
_Theme.Text = value;
TranslatedText = translation;
if (_EditMode)
{
TranslatedText += "|";
}
_PositionNeedsUpdate = true;
}
}
}
public string TranslatedText { get; private set; } = string.Empty;
public int TranslationId
{
get { return _TranslationId; }
set
{
if (_TranslationId != value)
{
TranslatedText = CBase.Language.Translate(TranslatedText, value);
_TranslationId = value;
_PositionNeedsUpdate = true;
}
}
}
private bool _EditMode;
public bool EditMode
{
get { return _EditMode; }
set
{
if (_EditMode != value)
{
TranslatedText = value ? TranslatedText + "|" : TranslatedText.Substring(0, TranslatedText.Length - 1);
_EditMode = value;
_PositionNeedsUpdate = true;
}
}
}
public float Alpha = 1f;
private CFont _CalculatedFont;
public CFont CalculatedFont
{
get
{
if (_PositionNeedsUpdate)
{
_UpdateTextPosition();
}
return _CalculatedFont;
}
}
public CText(int partyModeId)
{
_PartyModeId = partyModeId;
_TranslationId = _PartyModeId;
_Font.AddObserver(this);
}
public CText(CText text)
{
_PartyModeId = text._PartyModeId;
_TranslationId = text._TranslationId;
MaxRect = text.MaxRect;
_Rect = text._Rect;
_PositionNeedsUpdate = false;
_Align = text._Align;
_ResizeAlign = text._ResizeAlign;
Font = new CFont(text.Font); //Use setter to set observer
Color = text.Color;
SelColor = text.SelColor;
_ReflectionSpace = text._ReflectionSpace;
_ReflectionHeight = text._ReflectionHeight;
AllMonitors = text.AllMonitors;
Text = text.Text;
Visible = text.Visible;
Alpha = text.Alpha;
_EditMode = text._EditMode;
}
public CText(float x, float y, float z, float h, float mw, EAlignment align, EStyle style, string fontFamily, SColorF col, string text, int partyModeId = -1,
float rheight = 0,
float rspace = 0) : this(partyModeId)
{
_Theme = new SThemeText { FontFamily = fontFamily, FontStyle = style, FontHeight = h, Text = text, Color = { A = col.A, B = col.B, G = col.G, R = col.R } };
ThemeLoaded = false;
_ButtonText = false;
MaxRect = new SRectF(x, y, mw, h, z);
Align = align;
ResizeAlign = EHAlignment.Center;
_Font.Name = fontFamily;
_Font.Style = style;
_Font.Height = h;
Color = col;
SelColor = col;
Text = text;
Selected = false;
_ReflectionSpace = rspace;
_ReflectionHeight = rheight;
}
public CText(SThemeText theme, int partyModeId, bool buttonText = false)
{
_PartyModeId = partyModeId;
_TranslationId = partyModeId;
_Theme = theme;
_ButtonText = buttonText;
ThemeLoaded = true;
}
public void Draw()
{
_Draw(false);
}
private void _Draw(bool force)
{
if (!force && !Visible && CBase.Settings.GetProgramState() != EProgramState.EditTheme)
{
return;
}
// Update Text
Text = Text;
var currentColor = Selected ? SelColor : Color;
var color = new SColorF(currentColor.R, currentColor.G, currentColor.B, currentColor.A * Alpha);
CBase.Fonts.DrawText(TranslatedText, CalculatedFont, Rect.X, Rect.Y, Z, color, AllMonitors);
if (_ReflectionHeight > 0)
{
CBase.Fonts.DrawTextReflection(TranslatedText, CalculatedFont, Rect.X, Rect.Y, Z, color, _ReflectionSpace, _ReflectionHeight);
}
if (Selected && CBase.Settings.GetProgramState() == EProgramState.EditTheme)
{
CBase.Drawing.DrawRect(new SColorF(0.5f, 1f, 0.5f, 0.5f), new SRectF(Rect.X, Rect.Y, Rect.W, Rect.H, Z));
}
}
public void Draw(float begin, float end)
{
var currentColor = Selected ? SelColor : Color;
var color = new SColorF(currentColor.R, currentColor.G, currentColor.B, currentColor.A * Alpha);
CBase.Fonts.DrawText(Text, CalculatedFont, Rect.X, Rect.Y, Z, color, begin, end);
if (_ReflectionHeight > 0)
{
// TODO
}
if (Selected && CBase.Settings.GetProgramState() == EProgramState.EditTheme)
{
CBase.Drawing.DrawRect(new SColorF(0.5f, 1f, 0.5f, 0.5f), new SRectF(X, Y, Rect.W, Rect.H, Z));
}
}
public void DrawRelative(float rx, float ry, float reflectionHeight = 0f, float reflectionSpace = 0f, float rectHeight = 0f)
{
var oldReflectionSpace = _ReflectionSpace;
var oldReflectionHeight = _ReflectionHeight;
if (reflectionHeight > 0)
{
_ReflectionSpace = (rectHeight - Rect.Y - Rect.H) * 2 + reflectionSpace;
_ReflectionHeight = reflectionHeight - (rectHeight - Rect.Y) + Rect.H;
}
else
{
_ReflectionHeight = 0;
}
X += rx;
Y += ry;
_Draw(true);
_ReflectionSpace = oldReflectionSpace;
_ReflectionHeight = oldReflectionHeight;
X -= rx;
Y -= ry;
}
public void UnloadSkin() { }
public void LoadSkin()
{
if (!ThemeLoaded)
{
return;
}
_Theme.Color.Get(_PartyModeId, out Color);
_Theme.SelColor.Get(_PartyModeId, out SelColor);
X = _Theme.X;
Y = _Theme.Y;
if (!_ButtonText)
{
Z = _Theme.Z;
}
W = _Theme.MaxWidth;
H = _Theme.FontHeight;
_Align = _Theme.Align;
_ResizeAlign = _Theme.ResizeAlign;
Font = new CFont(_Theme.FontFamily, _Theme.FontStyle, _Theme.FontHeight);
if (_Theme.Reflection.HasValue)
{
_ReflectionSpace = _Theme.Reflection.Value.Space;
_ReflectionHeight = _Theme.Reflection.Value.Height;
}
Text = _Theme.Text;
Selected = false;
}
public void ReloadSkin()
{
UnloadSkin();
LoadSkin();
}
public object GetTheme()
{
return _Theme;
}
#region ThemeEdit
public void MoveElement(int stepX, int stepY)
{
X += stepX;
Y += stepY;
_Theme.X = X;
_Theme.Y = Y;
}
public void ResizeElement(int stepW, int stepH)
{
_Theme.FontHeight += stepH;
if (_Theme.FontHeight <= 0)
{
_Theme.FontHeight = 1;
}
_Font.Height = _Theme.FontHeight;
}
#endregion ThemeEdit
private void _UpdateTextPosition()
{
if (!_PositionNeedsUpdate)
{
return;
}
_CalculatedFont = new CFont(Font);
_Rect = MaxRect;
_PositionNeedsUpdate = false;
if (TranslatedText == "")
{
return;
}
var h = _CalculatedFont.Height;
var y = Y;
var bounds = CBase.Fonts.GetTextBounds(this);
if (W > 0f && bounds.Width > W && bounds.Width > 0f)
{
var factor = W / bounds.Width;
var step = h * (1 - factor);
h *= factor;
switch (ResizeAlign)
{
case EHAlignment.Top:
y += step * 0.25f;
break;
case EHAlignment.Center:
y += step * 0.50f;
break;
case EHAlignment.Bottom:
y += step * 0.75f;
break;
}
_CalculatedFont.Height = h;
bounds = CBase.Fonts.GetTextBounds(this);
}
var x = X;
switch (Align)
{
case EAlignment.Center:
x = X - bounds.Width / 2;
break;
case EAlignment.Right:
x = X - bounds.Width;
break;
}
_Rect = new SRectF(x, y, bounds.Width, bounds.Height, Z);
}
public void FontChanged()
{
_PositionNeedsUpdate = true;
}
}
}