Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add assistive text to MaterialMaskedTextBox & MaterialMultiLineTextBox2 #264

Merged
merged 5 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 130 additions & 13 deletions MaterialSkin/Controls/MaterialMaskedTextBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,54 @@ public bool UseTallSize
get { return _UseTallSize; }
set
{
//if (_UseTallSize != value)
//{
_UseTallSize = value;
HEIGHT = _UseTallSize ? 48 : 36;
Size = new Size(Size.Width, HEIGHT);
UpdateHeight();
UpdateRects();
Invalidate();
//}
}
}

private bool _showAssistiveText;
[Category("Material Skin"), DefaultValue(false), Description("Assistive elements provide additional detail about text entered into text fields. Could be Helper text or Error message.")]
public bool ShowAssistiveText
{
get { return _showAssistiveText; }
set
{
_showAssistiveText = value;
if (_showAssistiveText)
_helperTextHeight = HELPER_TEXT_HEIGHT;
else
_helperTextHeight = 0;
UpdateHeight();
//UpdateRects();
Invalidate();
}
}

private string _helperText;

[Category("Material Skin"), DefaultValue(""), Localizable(true), Description("Helper text conveys additional guidance about the input field, such as how it will be used.")]
public string HelperText
{
get { return _helperText; }
set
{
_helperText = value;
Invalidate();
}
}

private string _errorMessage;

[Category("Material Skin"), DefaultValue(""), Localizable(true), Description("When text input isn't accepted, an error message can display instructions on how to fix it. Error messages are displayed below the input line, replacing helper text until fixed.")]
public string ErrorMessage
{
get { return _errorMessage; }
set
{
_errorMessage = value;
Invalidate();
}
}

Expand Down Expand Up @@ -1273,6 +1313,7 @@ public event TypeValidationEventHandler TypeValidationCompleted
private const int LEFT_PADDING = 16;
private const int RIGHT_PADDING = 12;
private const int ACTIVATION_INDICATOR_HEIGHT = 2;
private const int HELPER_TEXT_HEIGHT = 16;
private const int FONT_HEIGHT = 20;

private int HEIGHT = 48;
Expand All @@ -1284,13 +1325,15 @@ public event TypeValidationEventHandler TypeValidationCompleted
private int _right_padding;
private int _prefix_padding;
private int _suffix_padding;
private int _helperTextHeight;
private Rectangle _leadingIconBounds;
private Rectangle _trailingIconBounds;

private Dictionary<string, TextureBrush> iconsBrushes;
private Dictionary<string, TextureBrush> iconsErrorBrushes;

protected readonly BaseMaskedTextBox baseTextBox;

public MaterialMaskedTextBox()
{
// Material Properties
Expand Down Expand Up @@ -1337,6 +1380,9 @@ public MaterialMaskedTextBox()

UseTallSize = true;
PrefixSuffix = PrefixSuffixTypes.None;
ShowAssistiveText = true;
HelperText = string.Empty;
ErrorMessage = string.Empty;

if (!Controls.Contains(baseTextBox) && !DesignMode)
{
Expand Down Expand Up @@ -1404,7 +1450,10 @@ protected override void OnPaint(PaintEventArgs pevent)
//Leading Icon
if (LeadingIcon != null)
{
g.FillRectangle(iconsBrushes["_leadingIcon"], _leadingIconBounds);
if (_errorState)
g.FillRectangle(iconsErrorBrushes["_leadingIcon"], _leadingIconBounds);
else
g.FillRectangle(iconsBrushes["_leadingIcon"], _leadingIconBounds);
}

//Trailing Icon
Expand All @@ -1418,6 +1467,7 @@ protected override void OnPaint(PaintEventArgs pevent)

// HintText
bool userTextPresent = !String.IsNullOrEmpty(Text);
Rectangle helperTextRect = new Rectangle(LEFT_PADDING - _prefix_padding, LINE_Y + ACTIVATION_INDICATOR_HEIGHT, Width - (LEFT_PADDING - _prefix_padding) - _right_padding, HELPER_TEXT_HEIGHT);
Rectangle hintRect = new Rectangle(_left_padding - _prefix_padding, HINT_TEXT_SMALL_Y, Width - (_left_padding - _prefix_padding) - _right_padding, HINT_TEXT_SMALL_SIZE);
int hintTextSize = 12;

Expand All @@ -1431,7 +1481,7 @@ protected override void OnPaint(PaintEventArgs pevent)
// bottom line
if (isFocused)
{
g.FillRectangle(isFocused ? UseAccent ? SkinManager.ColorScheme.AccentBrush : SkinManager.ColorScheme.PrimaryBrush : SkinManager.DividersBrush, 0, LINE_Y, Width, isFocused ? 2 : 1);
g.FillRectangle(_errorState ? SkinManager.BackgroundHoverRedBrush : isFocused ? UseAccent ? SkinManager.ColorScheme.AccentBrush : SkinManager.ColorScheme.PrimaryBrush : SkinManager.DividersBrush, 0, LINE_Y, Width, isFocused ? 2 : 1);
}
}
else
Expand All @@ -1453,7 +1503,6 @@ protected override void OnPaint(PaintEventArgs pevent)
Rectangle prefixRect = new Rectangle(
_left_padding - _prefix_padding,
hasHint && UseTallSize ? (hintRect.Y + hintRect.Height) - 2 : ClientRectangle.Y,
// NativeText.MeasureLogString(_prefixsuffixText, SkinManager.getLogFontByType(MaterialSkinManager.fontType.Subtitle1)).Width,
_prefix_padding,
hasHint && UseTallSize ? LINE_Y - (hintRect.Y + hintRect.Height) : LINE_Y);

Expand All @@ -1476,7 +1525,6 @@ protected override void OnPaint(PaintEventArgs pevent)
Rectangle suffixRect = new Rectangle(
Width - _right_padding ,
hasHint && UseTallSize ? (hintRect.Y + hintRect.Height) - 2 : ClientRectangle.Y,
//NativeText.MeasureLogString(_prefixsuffixText, SkinManager.getLogFontByType(MaterialSkinManager.fontType.Subtitle1)).Width + PREFIX_SUFFIX_PADDING,
_suffix_padding,
hasHint && UseTallSize ? LINE_Y - (hintRect.Y + hintRect.Height) : LINE_Y);

Expand Down Expand Up @@ -1511,6 +1559,43 @@ protected override void OnPaint(PaintEventArgs pevent)
}
}

// Draw helper text
if (_showAssistiveText && isFocused && !_errorState)
{
using (NativeTextRenderer NativeText = new NativeTextRenderer(g))
{
NativeText.DrawTransparentText(
HelperText,
SkinManager.getTextBoxFontBySize(hintTextSize),
Enabled ? !_errorState || (!userTextPresent && !isFocused) ? isFocused ? UseAccent ?
SkinManager.ColorScheme.AccentColor : // Focus Accent
SkinManager.ColorScheme.PrimaryColor : // Focus Primary
SkinManager.TextMediumEmphasisColor : // not focused
SkinManager.BackgroundHoverRedColor : // error state
SkinManager.TextDisabledOrHintColor, // Disabled
helperTextRect.Location,
helperTextRect.Size,
NativeTextRenderer.TextAlignFlags.Left | NativeTextRenderer.TextAlignFlags.Middle);
}
}

// Draw error message
if (_showAssistiveText && _errorState && ErrorMessage!=null)
{
using (NativeTextRenderer NativeText = new NativeTextRenderer(g))
{
NativeText.DrawTransparentText(
ErrorMessage,
SkinManager.getTextBoxFontBySize(hintTextSize),
Enabled ?
SkinManager.BackgroundHoverRedColor : // error state
SkinManager.TextDisabledOrHintColor, // Disabled
helperTextRect.Location,
helperTextRect.Size,
NativeTextRenderer.TextAlignFlags.Left | NativeTextRenderer.TextAlignFlags.Middle);
}
}

}

protected override void OnMouseMove(MouseEventArgs e)
Expand Down Expand Up @@ -1588,7 +1673,7 @@ protected override void OnResize(EventArgs e)
preProcessIcons();

Size = new Size(Width, HEIGHT);
LINE_Y = HEIGHT - ACTIVATION_INDICATOR_HEIGHT;
LINE_Y = HEIGHT - ACTIVATION_INDICATOR_HEIGHT - _helperTextHeight;

}

Expand Down Expand Up @@ -1707,18 +1792,38 @@ private void preProcessIcons()
destRect, GraphicsUnit.Pixel, grayImageAttributes);
}

//Create a pre - processed copy of the image(RED)
Bitmap bred = new Bitmap(destRect.Width, destRect.Height);
using (Graphics gred = Graphics.FromImage(bred))
{
gred.DrawImage(_leadingIconIconResized,
new Point[] {
new Point(0, 0),
new Point(destRect.Width, 0),
new Point(0, destRect.Height),
},
destRect, GraphicsUnit.Pixel, redImageAttributes);
}

// added processed image to brush for drawing
TextureBrush textureBrushGray = new TextureBrush(bgray);
TextureBrush textureBrushRed = new TextureBrush(bred);

textureBrushGray.WrapMode = System.Drawing.Drawing2D.WrapMode.Clamp;
textureBrushRed.WrapMode = System.Drawing.Drawing2D.WrapMode.Clamp;

var iconRect = _leadingIconBounds;

textureBrushGray.TranslateTransform(iconRect.X + iconRect.Width / 2 - _leadingIconIconResized.Width / 2,
iconRect.Y + iconRect.Height / 2 - _leadingIconIconResized.Height / 2);
textureBrushRed.TranslateTransform(iconRect.X + iconRect.Width / 2 - _leadingIconIconResized.Width / 2,
iconRect.Y + iconRect.Height / 2 - _leadingIconIconResized.Height / 2);

// add to dictionary
iconsBrushes.Add("_leadingIcon", textureBrushGray);

iconsErrorBrushes.Add("_leadingIcon", textureBrushRed);

}

if (_trailingIcon != null)
Expand Down Expand Up @@ -1781,6 +1886,13 @@ private void preProcessIcons()

#endregion

private void UpdateHeight()
{
HEIGHT = _UseTallSize ? 48 : 36;
HEIGHT += _helperTextHeight;
Size = new Size(Size.Width, HEIGHT);
}

private void UpdateRects()
{
if (LeadingIcon != null)
Expand Down Expand Up @@ -1822,18 +1934,23 @@ private void UpdateRects()
}
else
{
baseTextBox.Location = new Point(_left_padding, HEIGHT / 2 - FONT_HEIGHT / 2);
baseTextBox.Location = new Point(_left_padding, (LINE_Y + ACTIVATION_INDICATOR_HEIGHT) / 2 - FONT_HEIGHT / 2);
baseTextBox.Width = Width - (_left_padding + _right_padding);
baseTextBox.Height = FONT_HEIGHT;
}

_leadingIconBounds = new Rectangle(8, (HEIGHT / 2) - (ICON_SIZE / 2), ICON_SIZE, ICON_SIZE);
_trailingIconBounds = new Rectangle(Width - (ICON_SIZE + 8), (HEIGHT / 2) - (ICON_SIZE / 2), ICON_SIZE, ICON_SIZE);
_leadingIconBounds = new Rectangle(8, ((LINE_Y + ACTIVATION_INDICATOR_HEIGHT) / 2) - (ICON_SIZE / 2), ICON_SIZE, ICON_SIZE);
_trailingIconBounds = new Rectangle(Width - (ICON_SIZE + 8), ((LINE_Y + ACTIVATION_INDICATOR_HEIGHT) / 2) - (ICON_SIZE / 2), ICON_SIZE, ICON_SIZE);
}

public void SetErrorState(bool ErrorState)
{
_errorState = ErrorState;
if (_errorState)
baseTextBox.ForeColor = SkinManager.BackgroundHoverRedColor;
else
baseTextBox.ForeColor = SkinManager.TextHighEmphasisColor;
baseTextBox.Invalidate();
Invalidate();
}

Expand Down
Loading