Work on print history widget.
This commit is contained in:
parent
4e4f257737
commit
2faec9d1c0
10 changed files with 191 additions and 47 deletions
|
|
@ -48,7 +48,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage
|
|||
|
||||
this.textImageButtonFactory.disabledTextColor = RGBA_Bytes.DarkGray;
|
||||
this.textImageButtonFactory.hoverTextColor = ActiveTheme.Instance.PrimaryTextColor;
|
||||
this.textImageButtonFactory.normalTextColor = RGBA_Bytes.Black;
|
||||
this.textImageButtonFactory.normalTextColor = ActiveTheme.Instance.SecondaryTextColor;
|
||||
this.textImageButtonFactory.pressedTextColor = ActiveTheme.Instance.PrimaryTextColor;
|
||||
|
||||
this.linkButtonFactory.fontSize = 11;
|
||||
|
|
|
|||
|
|
@ -304,13 +304,14 @@ namespace MatterHackers.MatterControl
|
|||
public DoubleSolidSlider(Vector2 positionOfTrackFirstValue, double widthInPixels, double minimum = 0, double maximum = 1, Orientation orientation = Orientation.Horizontal)
|
||||
{
|
||||
View = new DoubleSolidSlideView(this);
|
||||
View.TrackHeight = widthInPixels;
|
||||
OriginRelativeParent = positionOfTrackFirstValue;
|
||||
TotalWidthInPixels = widthInPixels;
|
||||
Orientation = orientation;
|
||||
Minimum = minimum;
|
||||
Maximum = maximum;
|
||||
ThumbWidth = 10;
|
||||
ThumbHeight = 14;
|
||||
ThumbWidth = widthInPixels;
|
||||
ThumbHeight = widthInPixels * 1.4;
|
||||
|
||||
MinimumSize = new Vector2(Width, Height);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,13 +246,14 @@ namespace MatterHackers.MatterControl
|
|||
public SolidSlider(Vector2 positionOfTrackFirstValue, double widthInPixels, double minimum = 0, double maximum = 1, Orientation orientation = Orientation.Horizontal)
|
||||
{
|
||||
View = new SolidSlideView(this);
|
||||
View.TrackHeight = widthInPixels;
|
||||
OriginRelativeParent = positionOfTrackFirstValue;
|
||||
TotalWidthInPixels = widthInPixels;
|
||||
//TotalWidthInPixels = widthInPixels;
|
||||
Orientation = orientation;
|
||||
Minimum = minimum;
|
||||
Maximum = maximum;
|
||||
ThumbWidth = 10;
|
||||
ThumbHeight = 14;
|
||||
ThumbWidth = widthInPixels;
|
||||
ThumbHeight = widthInPixels * 1.4;
|
||||
|
||||
MinimumSize = new Vector2(Width, Height);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
|
||||
protected static SolidSlider InsertUiForSlider(FlowLayoutWidget wordOptionContainer, string header, double min = 0, double max = .5)
|
||||
{
|
||||
double scrollBarWidth = 100;
|
||||
double scrollBarWidth = 10;
|
||||
TextWidget spacingText = new TextWidget(header, textColor: ActiveTheme.Instance.PrimaryTextColor);
|
||||
spacingText.Margin = new BorderDouble(10, 3, 3, 5);
|
||||
spacingText.HAnchor = HAnchor.ParentLeft;
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
Vector2 bedCenter;
|
||||
Vector3 viewerVolume;
|
||||
MeshViewerWidget.BedShape bedShape;
|
||||
int sliderWidth;
|
||||
|
||||
public ViewGcodeBasic(PrintItemWrapper printItem, Vector3 viewerVolume, Vector2 bedCenter, MeshViewerWidget.BedShape bedShape, bool addCloseButton)
|
||||
{
|
||||
|
|
@ -89,6 +90,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
widgetHasCloseButton = addCloseButton;
|
||||
this.printItem = printItem;
|
||||
|
||||
if (ActiveTheme.Instance.DisplayMode == ActiveTheme.ApplicationDisplayType.Touchscreen)
|
||||
{
|
||||
sliderWidth = 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
sliderWidth = 10;
|
||||
}
|
||||
|
||||
CreateAndAddChildren(null);
|
||||
|
||||
SliceSettingsWidget.PartPreviewSettingsChanged.RegisterEvent(RecreateBedAndPartPosition, ref unregisterEvents);
|
||||
|
|
@ -753,12 +763,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
navigationWidget.Margin = new BorderDouble(0, 0, 20, 0);
|
||||
layerSelectionButtonsPanel.AddChild(navigationWidget);
|
||||
|
||||
selectLayerSlider = new SolidSlider(new Vector2(), 10, 0, gcodeViewWidget.LoadedGCode.NumChangesInZ - 1, Orientation.Vertical);
|
||||
selectLayerSlider = new SolidSlider(new Vector2(), sliderWidth, 0, gcodeViewWidget.LoadedGCode.NumChangesInZ - 1, Orientation.Vertical);
|
||||
selectLayerSlider.ValueChanged += new EventHandler(selectLayerSlider_ValueChanged);
|
||||
gcodeViewWidget.ActiveLayerChanged += new EventHandler(gcodeViewWidget_ActiveLayerChanged);
|
||||
AddChild(selectLayerSlider);
|
||||
|
||||
layerRenderRatioSlider = new DoubleSolidSlider(new Vector2(), 10);
|
||||
layerRenderRatioSlider = new DoubleSolidSlider(new Vector2(), sliderWidth);
|
||||
layerRenderRatioSlider.FirstValue = 0;
|
||||
layerRenderRatioSlider.FirstValueChanged += new EventHandler(layerStartRenderRatioSlider_ValueChanged);
|
||||
layerRenderRatioSlider.SecondValue = 1;
|
||||
|
|
@ -814,7 +824,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
|
|||
selectLayerSlider.OriginRelativeParent = new Vector2(gcodeDisplayWidget.Width - 20, 70);
|
||||
selectLayerSlider.TotalWidthInPixels = gcodeDisplayWidget.Height - 80;
|
||||
|
||||
layerRenderRatioSlider.OriginRelativeParent = new Vector2(60, 60);
|
||||
layerRenderRatioSlider.OriginRelativeParent = new Vector2(60, 70);
|
||||
layerRenderRatioSlider.TotalWidthInPixels = gcodeDisplayWidget.Width - 100;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,9 +65,9 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
public bool isHoverItem = false;
|
||||
bool showTimestamp;
|
||||
TextWidget partLabel;
|
||||
Button printAgainLink;
|
||||
public CheckBox selectionCheckBox;
|
||||
FlowLayoutWidget buttonContainer;
|
||||
FlowLayoutWidget actionButtonColumn;
|
||||
LinkButtonFactory linkButtonFactory = new LinkButtonFactory();
|
||||
|
||||
public PrintHistoryListItem(PrintTask printTask, bool showTimestamp)
|
||||
|
|
@ -97,7 +97,7 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
|
||||
FlowLayoutWidget middleColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
|
||||
middleColumn.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
|
||||
middleColumn.Padding = new BorderDouble(6,3);
|
||||
middleColumn.Padding = new BorderDouble(6, 3);
|
||||
{
|
||||
FlowLayoutWidget labelContainer = new FlowLayoutWidget();
|
||||
labelContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
|
||||
|
|
@ -113,13 +113,13 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
middleColumn.AddChild(labelContainer);
|
||||
}
|
||||
|
||||
RGBA_Bytes timeTextColor = RGBA_Bytes.Gray;
|
||||
RGBA_Bytes timeTextColor = new RGBA_Bytes(34, 34, 34);
|
||||
|
||||
buttonContainer = new FlowLayoutWidget();
|
||||
buttonContainer.Margin = new BorderDouble(0);
|
||||
buttonContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
|
||||
{
|
||||
TextWidget statusIndicator = new TextWidget("Status: Completed".Localize(), pointSize:8);
|
||||
TextWidget statusIndicator = new TextWidget("Status: Completed".Localize(), pointSize: 8);
|
||||
statusIndicator.Margin = new BorderDouble(right: 3);
|
||||
//buttonContainer.AddChild(statusIndicator);
|
||||
|
||||
|
|
@ -148,18 +148,7 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
|
||||
buttonContainer.AddChild(timeLabel);
|
||||
buttonContainer.AddChild(timeIndicator);
|
||||
|
||||
printAgainLink = linkButtonFactory.Generate("Print Again".Localize());
|
||||
printAgainLink.Margin = new BorderDouble(left: 0, right: 0);
|
||||
printAgainLink.VAnchor = VAnchor.ParentCenter;
|
||||
|
||||
printAgainLink.Click += (sender, e) =>
|
||||
{
|
||||
QueueData.Instance.AddItem(new PrintItemWrapper(printTask.PrintItemId));
|
||||
};
|
||||
|
||||
buttonContainer.AddChild(new HorizontalSpacer());
|
||||
buttonContainer.AddChild(printAgainLink);
|
||||
middleColumn.AddChild(buttonContainer);
|
||||
}
|
||||
|
||||
|
|
@ -167,11 +156,56 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
this.AddChild(middleColumn);
|
||||
|
||||
|
||||
actionButtonColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
|
||||
actionButtonColumn.VAnchor = VAnchor.ParentBottomTop;
|
||||
actionButtonColumn.Visible = false;
|
||||
|
||||
FlowLayoutWidget rightMiddleColumnContainer = new FlowLayoutWidget(Agg.UI.FlowDirection.LeftToRight);
|
||||
rightMiddleColumnContainer.VAnchor = VAnchor.ParentBottomTop;
|
||||
{
|
||||
ClickWidget viewButton = new ClickWidget();
|
||||
viewButton.VAnchor = VAnchor.ParentBottomTop;
|
||||
viewButton.BackgroundColor = ActiveTheme.Instance.SecondaryAccentColor;
|
||||
viewButton.Width = 80;
|
||||
|
||||
TextWidget viewLabel = new TextWidget("View".Localize());
|
||||
viewLabel.TextColor = RGBA_Bytes.White;
|
||||
viewLabel.VAnchor = VAnchor.ParentCenter;
|
||||
viewLabel.HAnchor = HAnchor.ParentCenter;
|
||||
|
||||
viewButton.AddChild(viewLabel);
|
||||
viewButton.Click += ViewButton_Click;
|
||||
rightMiddleColumnContainer.AddChild(viewButton);
|
||||
|
||||
ClickWidget printButton = new ClickWidget();
|
||||
printButton.VAnchor = VAnchor.ParentBottomTop;
|
||||
printButton.BackgroundColor = ActiveTheme.Instance.PrimaryAccentColor;
|
||||
printButton.Width = 80;
|
||||
|
||||
TextWidget printLabel = new TextWidget("Print".Localize());
|
||||
printLabel.TextColor = RGBA_Bytes.White;
|
||||
printLabel.VAnchor = VAnchor.ParentCenter;
|
||||
printLabel.HAnchor = HAnchor.ParentCenter;
|
||||
|
||||
printButton.AddChild(printLabel);
|
||||
printButton.Click += (sender, e) =>
|
||||
{
|
||||
QueueData.Instance.AddItem(new PrintItemWrapper(printTask.PrintItemId));
|
||||
};
|
||||
rightMiddleColumnContainer.AddChild(printButton);
|
||||
|
||||
|
||||
}
|
||||
actionButtonColumn.AddChild(rightMiddleColumnContainer);
|
||||
|
||||
this.AddChild(actionButtonColumn);
|
||||
|
||||
if (showTimestamp)
|
||||
{
|
||||
FlowLayoutWidget rightColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
|
||||
rightColumn.BackgroundColor = RGBA_Bytes.LightGray;
|
||||
rightColumn.Padding = new BorderDouble(6, 0);
|
||||
FlowLayoutWidget timestampColumn = new FlowLayoutWidget(FlowDirection.TopToBottom);
|
||||
timestampColumn.VAnchor = Agg.UI.VAnchor.ParentBottomTop;
|
||||
timestampColumn.BackgroundColor = RGBA_Bytes.LightGray;
|
||||
timestampColumn.Padding = new BorderDouble(6, 0);
|
||||
|
||||
FlowLayoutWidget startTimeContainer = new FlowLayoutWidget();
|
||||
startTimeContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
|
||||
|
|
@ -182,7 +216,7 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
startLabel.TextColor = timeTextColor;
|
||||
|
||||
string startTimeString = printTask.PrintStart.ToString("MMM d yyyy h:mm ") + printTask.PrintStart.ToString("tt").ToLower();
|
||||
TextWidget startDate = new TextWidget(startTimeString, pointSize: 12);
|
||||
TextWidget startDate = new TextWidget(startTimeString, pointSize: 10);
|
||||
startDate.TextColor = timeTextColor;
|
||||
|
||||
startTimeContainer.AddChild(startLabel);
|
||||
|
|
@ -208,7 +242,7 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
endTimeString = "Unknown".Localize();
|
||||
}
|
||||
|
||||
TextWidget endDate = new TextWidget(endTimeString, pointSize: 12);
|
||||
TextWidget endDate = new TextWidget(endTimeString, pointSize: 10);
|
||||
endDate.TextColor = timeTextColor;
|
||||
|
||||
endTimeContainer.AddChild(endLabel);
|
||||
|
|
@ -218,15 +252,13 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
HorizontalLine horizontalLine = new HorizontalLine();
|
||||
horizontalLine.BackgroundColor = RGBA_Bytes.Gray;
|
||||
|
||||
rightColumn.AddChild(endTimeContainer);
|
||||
rightColumn.AddChild(horizontalLine);
|
||||
rightColumn.AddChild(startTimeContainer);
|
||||
timestampColumn.AddChild(endTimeContainer);
|
||||
timestampColumn.AddChild(horizontalLine);
|
||||
timestampColumn.AddChild(startTimeContainer);
|
||||
|
||||
rightColumn.Width = 220;
|
||||
this.AddChild(rightColumn);
|
||||
timestampColumn.Width = 220;
|
||||
this.AddChild(timestampColumn);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -244,8 +276,94 @@ namespace MatterHackers.MatterControl.PrintHistory
|
|||
void AddHandlers()
|
||||
{
|
||||
ActiveTheme.Instance.ThemeChanged.RegisterEvent(ThemeChanged, ref unregisterEvents);
|
||||
MouseEnterBounds += new EventHandler(HistoryItem_MouseEnterBounds);
|
||||
MouseLeaveBounds += new EventHandler(HistoryItem_MouseLeaveBounds);
|
||||
}
|
||||
|
||||
void ViewButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
PrintItem printItem = DataStorage.Datastore.Instance.dbSQLite.Table<DataStorage.PrintItem>().Where(v => v.Id == this.printTask.PrintItemId).Take(1).FirstOrDefault();
|
||||
|
||||
if (printItem != null)
|
||||
{
|
||||
string pathAndFile = printItem.FileLocation;
|
||||
if (File.Exists(pathAndFile))
|
||||
{
|
||||
bool shiftKeyDown = Keyboard.IsKeyDown(Keys.ShiftKey);
|
||||
if (shiftKeyDown)
|
||||
{
|
||||
OpenPartPreviewWindow(printItem, View3DTransformPart.AutoRotate.Disabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
OpenPartPreviewWindow(printItem, View3DTransformPart.AutoRotate.Enabled);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintItemWrapper itemWrapper = new PrintItemWrapper(printItem);
|
||||
ShowCantFindFileMessage(itemWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowCantFindFileMessage(PrintItemWrapper printItemWrapper)
|
||||
{
|
||||
UiThread.RunOnIdle((state) =>
|
||||
{
|
||||
string maxLengthName = printItemWrapper.FileLocation;
|
||||
int maxLength = 43;
|
||||
if (maxLengthName.Length > maxLength)
|
||||
{
|
||||
string start = maxLengthName.Substring(0, 15) + "...";
|
||||
int amountRemaining = (maxLength - start.Length);
|
||||
string end = maxLengthName.Substring(maxLengthName.Length - amountRemaining, amountRemaining);
|
||||
maxLengthName = start + end;
|
||||
}
|
||||
string notFoundMessage = LocalizedString.Get("Oops! Could not find this file:");
|
||||
string message = "{0}:\n'{1}'".FormatWith(notFoundMessage, maxLengthName);
|
||||
string titleLabel = LocalizedString.Get("Item not Found");
|
||||
if (StyledMessageBox.ShowMessageBox(message, titleLabel, StyledMessageBox.MessageType.OK))
|
||||
{
|
||||
QueueData.Instance.RemoveIndexOnIdle(QueueData.Instance.GetIndex(printItemWrapper));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PartPreviewMainWindow partPreviewWindow;
|
||||
private void OpenPartPreviewWindow(PrintItem printItem, View3DTransformPart.AutoRotate autoRotate)
|
||||
{
|
||||
|
||||
PrintItemWrapper itemWrapper = new PrintItemWrapper(printItem.Id);
|
||||
if (partPreviewWindow == null)
|
||||
{
|
||||
partPreviewWindow = new PartPreviewMainWindow(itemWrapper, autoRotate);
|
||||
partPreviewWindow.Closed += new EventHandler(PartPreviewWindow_Closed);
|
||||
}
|
||||
else
|
||||
{
|
||||
partPreviewWindow.BringToFront();
|
||||
}
|
||||
}
|
||||
|
||||
void PartPreviewWindow_Closed(object sender, EventArgs e)
|
||||
{
|
||||
this.partPreviewWindow = null;
|
||||
}
|
||||
|
||||
|
||||
void HistoryItem_MouseLeaveBounds(object sender, EventArgs e)
|
||||
{
|
||||
actionButtonColumn.Visible = false;
|
||||
}
|
||||
|
||||
void HistoryItem_MouseEnterBounds(object sender, EventArgs e)
|
||||
{
|
||||
actionButtonColumn.Visible = true;
|
||||
}
|
||||
|
||||
|
||||
public override void OnClosed(EventArgs e)
|
||||
{
|
||||
if (unregisterEvents != null)
|
||||
|
|
|
|||
|
|
@ -70,8 +70,15 @@ namespace MatterHackers.MatterControl.PrintQueue
|
|||
public PrintItemWrapper(int printItemId)
|
||||
{
|
||||
this.PrintItem = DataStorage.Datastore.Instance.dbSQLite.Table<DataStorage.PrintItem>().Where(v => v.Id == printItemId).Take(1).FirstOrDefault();
|
||||
try
|
||||
{
|
||||
this.fileType = Path.GetExtension(this.PrintItem.FileLocation).ToUpper();
|
||||
}
|
||||
catch
|
||||
{
|
||||
//file not found
|
||||
}
|
||||
}
|
||||
|
||||
bool doneSlicing;
|
||||
static string slicingError = "Slicing Error".Localize();
|
||||
|
|
|
|||
|
|
@ -414,6 +414,10 @@ namespace MatterHackers.MatterControl
|
|||
tuningRatiosLayout.HAnchor = HAnchor.ParentLeftRight;
|
||||
tuningRatiosLayout.Padding = new BorderDouble(3, 0, 3, 0)* TextWidget.GlobalPointSizeScaleRatio;
|
||||
|
||||
|
||||
int slideHeight = 10;
|
||||
|
||||
|
||||
TextWidget subheader = new TextWidget("Fine-tune adjustment while actively printing", pointSize: 8, textColor: ActiveTheme.Instance.PrimaryTextColor);
|
||||
subheader.Margin = new BorderDouble(bottom:6);
|
||||
tuningRatiosLayout.AddChild(subheader);
|
||||
|
|
@ -430,7 +434,7 @@ namespace MatterHackers.MatterControl
|
|||
feedRateDescription.TextColor = ActiveTheme.Instance.PrimaryTextColor;
|
||||
feedRateDescription.VAnchor = VAnchor.ParentCenter;
|
||||
feedRateLeftToRight.AddChild(feedRateDescription);
|
||||
feedRateRatioSlider = new SolidSlider(new Vector2(), 300* TextWidget.GlobalPointSizeScaleRatio, minFeedRateRatio, maxFeedRateRatio);
|
||||
feedRateRatioSlider = new SolidSlider(new Vector2(), slideHeight, minFeedRateRatio, maxFeedRateRatio);
|
||||
feedRateRatioSlider.Margin = new BorderDouble(5, 0);
|
||||
feedRateRatioSlider.Value = PrinterConnectionAndCommunication.Instance.FeedRateRatio;
|
||||
feedRateRatioSlider.View.BackgroundColor = new RGBA_Bytes();
|
||||
|
|
@ -472,7 +476,7 @@ namespace MatterHackers.MatterControl
|
|||
extrusionDescription.TextColor = ActiveTheme.Instance.PrimaryTextColor;
|
||||
extrusionDescription.VAnchor = VAnchor.ParentCenter;
|
||||
leftToRight.AddChild(extrusionDescription);
|
||||
extrusionRatioSlider = new SolidSlider(new Vector2(), 300* TextWidget.GlobalPointSizeScaleRatio, minExtrutionRatio, maxExtrusionRatio);
|
||||
extrusionRatioSlider = new SolidSlider(new Vector2(), slideHeight, minExtrutionRatio, maxExtrusionRatio);
|
||||
extrusionRatioSlider.Margin = new BorderDouble(5, 0)* TextWidget.GlobalPointSizeScaleRatio;
|
||||
extrusionRatioSlider.Value = PrinterConnectionAndCommunication.Instance.ExtrusionRatio;
|
||||
extrusionRatioSlider.View.BackgroundColor = new RGBA_Bytes();
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ namespace MatterHackers.MatterControl
|
|||
|
||||
this.textImageButtonFactory.disabledTextColor = RGBA_Bytes.Gray;
|
||||
this.textImageButtonFactory.hoverTextColor = ActiveTheme.Instance.PrimaryTextColor;
|
||||
this.textImageButtonFactory.normalTextColor = RGBA_Bytes.Black;
|
||||
this.textImageButtonFactory.normalTextColor = ActiveTheme.Instance.SecondaryTextColor;
|
||||
this.textImageButtonFactory.pressedTextColor = ActiveTheme.Instance.PrimaryTextColor;
|
||||
|
||||
this.HAnchor = HAnchor.ParentLeftRight;
|
||||
|
|
|
|||
|
|
@ -2600,3 +2600,6 @@ Translated:Enable Cloud Monitoring (disabled)
|
|||
English:Warning - Moving Too Low
|
||||
Translated:Warning - Moving Too Low
|
||||
|
||||
English:Oops! Could not find this file:
|
||||
Translated:Oops! Could not find this file:
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue