Skip to content

Commit

Permalink
Merge pull request #264 from leocb/orapps44-textfield-assistive-text
Browse files Browse the repository at this point in the history
Add assistive text to MaterialMaskedTextBox & MaterialMultiLineTextBox2
  • Loading branch information
orapps44 authored Oct 27, 2021
2 parents a7a7d32 + 9989da5 commit f77be7c
Show file tree
Hide file tree
Showing 4 changed files with 291 additions and 27 deletions.
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

0 comments on commit f77be7c

Please sign in to comment.