Merge pull request #4209 from jlewin/2.19.2

Extract validation display to reusable component
This commit is contained in:
johnlewin 2019-01-23 09:56:35 -08:00 committed by GitHub
commit 110c5281f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 125 additions and 88 deletions

View file

@ -2479,28 +2479,20 @@ If you experience adhesion problems, please re-run leveling."
{
UiThread.RunOnIdle(() =>
{
// Project to newline separated Error/Details/Location string
var formattedErrors = errors.Select(err =>
var dialogPage = new DialogPage("Close".Localize())
{
string location = null;
string valueDetails = null;
HAnchor = HAnchor.Stretch,
WindowTitle = windowTitle,
HeaderText = "Action Required".Localize()
};
if (err is SettingsValidationError settingsError)
{
location = settingsError.Location;
valueDetails = settingsError.ValueDetails;
}
dialogPage.ContentRow.AddChild(new ValidationErrorsPanel(errors, AppContext.Theme)
{
FlowDirection = FlowDirection.TopToBottom,
HAnchor = HAnchor.Stretch
});
// Conditionally combine Error/Details/Location when not empty
return err.Error +
((string.IsNullOrWhiteSpace(err.Details)) ? "" : $"\n\n{err.Details}") +
((string.IsNullOrWhiteSpace(valueDetails)) ? "" : $"\n\n{valueDetails}") +
((string.IsNullOrWhiteSpace(location)) ? "" : $"\n\n{location}");
}).ToArray();
StyledMessageBox.ShowMessageBox(
string.Join("\n__________________\n\n", formattedErrors),
windowTitle);
DialogWindow.Show(dialogPage);
});
}

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2018, Lars Brubaker, John Lewin
Copyright (c) 2019, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -32,7 +32,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets;
@ -66,11 +65,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.PopupVAnchor = VAnchor.Fit;
this.MakeScrollable = false;
var errorImage = AggContext.StaticData.LoadIcon("SettingsGroupError_16x.png", 16, 16, theme.InvertIcons);
var warningImage = AggContext.StaticData.LoadIcon("SettingsGroupWarning_16x.png", 16, 16, theme.InvertIcons);
var infoImage = AggContext.StaticData.LoadIcon("StatusInfoTip_16x.png", 16, 16);
var fixIcon = AggContext.StaticData.LoadIcon("noun_1306.png", 16, 16, theme.InvertIcons);
this.DynamicPopupContent = () =>
{
var menuTheme = ApplicationController.Instance.MenuTheme;
@ -231,66 +225,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (hasErrorsOrWarnings)
{
var errorsPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
{
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Fit | VAnchor,
BackgroundColor = theme.ResolveColor(menuTheme.BackgroundColor, theme.PrimaryAccentColor.WithAlpha(30)),
Width = 350,
Name = "errorsPanel"
};
foreach (var validationError in errors.OrderByDescending(e => e.ErrorLevel))
{
string errorText, errorDetails;
var settingsValidationError = validationError as SettingsValidationError;
if (settingsValidationError != null)
{
errorText = string.Format(
"{0} {1}",
settingsValidationError.PresentationName,
validationError.ErrorLevel == ValidationErrorLevel.Error ? "Error".Localize() : "Warning".Localize());
errorDetails = validationError.Error;
}
else
{
errorText = validationError.Error;
errorDetails = validationError.Details ?? "";
}
var row = new SettingsRow(errorText, errorDetails, theme, validationError.ErrorLevel == ValidationErrorLevel.Error ? errorImage : warningImage)
{
ArrowDirection = ArrowDirection.Left
};
if (validationError.FixAction is NamedAction action)
{
// Show fix button
var button = new IconButton(fixIcon, theme)
{
ToolTipText = action.Title
};
button.Click += (s, e) =>
{
action.Action.Invoke();
};
row.AddChild(button);
}
else
{
// Show info indicator hinting that hover will reveal additional details
var button = new IconButton(infoImage, theme)
{
Selectable = false
};
row.AddChild(button);
}
errorsPanel.AddChild(row);
}
var errorsPanel = new ValidationErrorsPanel(errors, menuTheme);
// Conditional layout for right or bottom errors panel alignment
var layoutStyle = FlowDirection.TopToBottom;

View file

@ -0,0 +1,106 @@
/*
Copyright (c) 2019, Lars Brubaker, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System.Collections.Generic;
using System.Linq;
using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class ValidationErrorsPanel : FlowLayoutWidget
{
public ValidationErrorsPanel(IEnumerable<ValidationError> errors, ThemeConfig theme)
{
this.HAnchor = HAnchor.Absolute;
this.VAnchor = VAnchor.Fit | VAnchor;
this.BackgroundColor = theme.ResolveColor(theme.BackgroundColor, theme.PrimaryAccentColor.WithAlpha(30));
var errorImage = AggContext.StaticData.LoadIcon("SettingsGroupError_16x.png", 16, 16, theme.InvertIcons);
var warningImage = AggContext.StaticData.LoadIcon("SettingsGroupWarning_16x.png", 16, 16, theme.InvertIcons);
var infoImage = AggContext.StaticData.LoadIcon("StatusInfoTip_16x.png", 16, 16);
var fixIcon = AggContext.StaticData.LoadIcon("noun_1306.png", 16, 16, theme.InvertIcons);
foreach (var validationError in errors.OrderByDescending(e => e.ErrorLevel))
{
string errorText, errorDetails;
var settingsValidationError = validationError as SettingsValidationError;
if (settingsValidationError != null)
{
errorText = string.Format(
"{0} {1}",
settingsValidationError.PresentationName,
validationError.ErrorLevel == ValidationErrorLevel.Error ? "Error".Localize() : "Warning".Localize());
errorDetails = validationError.Error;
}
else
{
errorText = validationError.Error;
errorDetails = validationError.Details ?? "";
}
var row = new SettingsRow(errorText, errorDetails, theme, validationError.ErrorLevel == ValidationErrorLevel.Error ? errorImage : warningImage)
{
ArrowDirection = ArrowDirection.Left
};
if (validationError.FixAction is NamedAction action)
{
// Show fix button
var button = new IconButton(fixIcon, theme)
{
ToolTipText = action.Title
};
button.Click += (s, e) =>
{
action.Action.Invoke();
};
row.AddChild(button);
}
else
{
// Show info indicator hinting that hover will reveal additional details
var button = new IconButton(infoImage, theme)
{
Selectable = false
};
row.AddChild(button);
}
this.AddChild(row);
}
}
}
}

View file

@ -137,6 +137,9 @@ namespace MatterHackers.MatterControl
#endif
}
// Add public accessor for content panel
public FlowLayoutWidget ContentRow => contentRow;
public DialogWindow DialogWindow { get; set; }
public string WindowTitle { get; set; }

View file

@ -147,7 +147,8 @@ namespace MatterHackers.MatterControl.CustomWidgets
public override void OnLoad(EventArgs args)
{
systemWindow = this.Parents<SystemWindow>().FirstOrDefault();
// The top level SystemWindow - due to single window implementation details, multiple SystemWindow parents may exist - proceed to the topmost one
systemWindow = this.Parents<SystemWindow>().LastOrDefault();
base.OnLoad(args);
}

@ -1 +1 @@
Subproject commit a569521e61caab785d2bfc533cf1dee8a169a2ed
Subproject commit e4770e1e3db3612eaddde66fda77a79200fdd670