Fixed layout and colors
This commit is contained in:
parent
cf9b827ec0
commit
2adffdc9f5
5 changed files with 282 additions and 197 deletions
|
|
@ -117,7 +117,9 @@
|
|||
<Compile Include="Library\Widgets\InsertionGroup.cs" />
|
||||
<Compile Include="PartPreviewWindow\NewTabButton.cs" />
|
||||
<Compile Include="PartPreviewWindow\PartTabPage.cs" />
|
||||
<Compile Include="PartPreviewWindow\PlusTab\ExploreItem.cs" />
|
||||
<Compile Include="PartPreviewWindow\PlusTab\ExplorePanel.cs" />
|
||||
<Compile Include="PartPreviewWindow\PlusTab\ExploreSection.cs" />
|
||||
<Compile Include="PartPreviewWindow\PopupMenu.cs" />
|
||||
<Compile Include="PartPreviewWindow\PopupMenuButton.cs" />
|
||||
<Compile Include="PartPreviewWindow\PopupButton.cs" />
|
||||
|
|
|
|||
94
PartPreviewWindow/PlusTab/ExploreItem.cs
Normal file
94
PartPreviewWindow/PlusTab/ExploreItem.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
Copyright (c) 2017, 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 MatterHackers.Agg;
|
||||
using MatterHackers.Agg.Image;
|
||||
using MatterHackers.Agg.UI;
|
||||
|
||||
namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
|
||||
{
|
||||
public class ExploreItem : FlowLayoutWidget
|
||||
{
|
||||
public ExploreItem(ExplorerFeedItem item)
|
||||
{
|
||||
var content = new FlowLayoutWidget()
|
||||
{
|
||||
Border = new BorderDouble(2),
|
||||
BorderColor = ActiveTheme.Instance.PrimaryTextColor,
|
||||
HAnchor = HAnchor.Absolute,
|
||||
Width = 220 * GuiWidget.DeviceScale,
|
||||
Margin = new BorderDouble(5),
|
||||
};
|
||||
this.AddChild(content);
|
||||
|
||||
if (item.icon != null)
|
||||
{
|
||||
ImageBuffer image = new ImageBuffer((int)(64 * GuiWidget.DeviceScale), (int)(64 * GuiWidget.DeviceScale));
|
||||
ImageWidget imageWidget = new ImageWidget(image)
|
||||
{
|
||||
Selectable = false,
|
||||
VAnchor = VAnchor.Top,
|
||||
Margin = new BorderDouble(3)
|
||||
};
|
||||
|
||||
imageWidget.Load += (s, e) => ApplicationController.Instance.DownloadToImageAsync(image, item.icon, true, new BlenderPreMultBGRA());
|
||||
content.AddChild(imageWidget);
|
||||
}
|
||||
|
||||
var wrappedText = new WrappedTextWidget(item.title, textColor: ActiveTheme.Instance.PrimaryTextColor)
|
||||
{
|
||||
Selectable = false,
|
||||
VAnchor = VAnchor.Center | VAnchor.Fit,
|
||||
Margin = new BorderDouble(3)
|
||||
};
|
||||
content.AddChild(wrappedText);
|
||||
wrappedText.Load += (s, e) =>
|
||||
{
|
||||
wrappedText.VAnchor = VAnchor.Top | VAnchor.Fit;
|
||||
};
|
||||
|
||||
if (item.url != null)
|
||||
{
|
||||
content.Cursor = Cursors.Hand;
|
||||
content.Click += (s, e) =>
|
||||
{
|
||||
MatterControlApplication.Instance.LaunchBrowser("http://www.matterhackers.com/" + item.url);
|
||||
};
|
||||
}
|
||||
else if (item.reference != null)
|
||||
{
|
||||
content.Cursor = Cursors.Hand;
|
||||
content.Click += (s, e) =>
|
||||
{
|
||||
MatterControlApplication.Instance.LaunchBrowser(item.reference);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -39,78 +39,6 @@ using Newtonsoft.Json;
|
|||
|
||||
namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
|
||||
{
|
||||
public class ExploreFeedContent
|
||||
{
|
||||
public string content_type;
|
||||
public List<ExplorerFeedItem> group_items;
|
||||
public string group_link;
|
||||
public string group_subtitle;
|
||||
public string group_title;
|
||||
public string icon_url;
|
||||
public string image_url;
|
||||
public string link;
|
||||
public string theme_filter;
|
||||
}
|
||||
|
||||
public class ExploreItem : FlowLayoutWidget
|
||||
{
|
||||
public ExploreItem(ExplorerFeedItem item)
|
||||
{
|
||||
var content = new FlowLayoutWidget()
|
||||
{
|
||||
Border = new BorderDouble(2),
|
||||
BorderColor = ActiveTheme.Instance.PrimaryTextColor,
|
||||
HAnchor = HAnchor.Absolute,
|
||||
Width = 220 * GuiWidget.DeviceScale,
|
||||
Margin = new BorderDouble(5),
|
||||
};
|
||||
this.AddChild(content);
|
||||
|
||||
if (item.icon != null)
|
||||
{
|
||||
ImageBuffer image = new ImageBuffer((int)(64 * GuiWidget.DeviceScale), (int)(64 * GuiWidget.DeviceScale));
|
||||
ImageWidget imageWidget = new ImageWidget(image)
|
||||
{
|
||||
Selectable = false,
|
||||
VAnchor = VAnchor.Top,
|
||||
Margin = new BorderDouble(3)
|
||||
};
|
||||
|
||||
imageWidget.Load += (s, e) => ApplicationController.Instance.DownloadToImageAsync(image, item.icon, true, new BlenderPreMultBGRA());
|
||||
content.AddChild(imageWidget);
|
||||
}
|
||||
|
||||
var wrappedText = new WrappedTextWidget(item.title)
|
||||
{
|
||||
Selectable = false,
|
||||
VAnchor = VAnchor.Center | VAnchor.Fit,
|
||||
Margin = new BorderDouble(3)
|
||||
};
|
||||
content.AddChild(wrappedText);
|
||||
wrappedText.Load += (s, e) =>
|
||||
{
|
||||
wrappedText.VAnchor = VAnchor.Top | VAnchor.Fit;
|
||||
};
|
||||
|
||||
if (item.url != null)
|
||||
{
|
||||
content.Cursor = Cursors.Hand;
|
||||
content.Click += (s, e) =>
|
||||
{
|
||||
MatterControlApplication.Instance.LaunchBrowser("http://www.matterhackers.com/" + item.url);
|
||||
};
|
||||
}
|
||||
else if(item.reference != null)
|
||||
{
|
||||
content.Cursor = Cursors.Hand;
|
||||
content.Click += (s, e) =>
|
||||
{
|
||||
MatterControlApplication.Instance.LaunchBrowser(item.reference);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ExplorePanel : ScrollableWidget
|
||||
{
|
||||
public ExplorePanel()
|
||||
|
|
@ -138,6 +66,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
|
|||
|
||||
// add a bunch of content
|
||||
AddControlsForContent(content);
|
||||
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
// Force layout to change to get it working
|
||||
var oldMargin = this.Margin;
|
||||
this.Margin = new BorderDouble(20);
|
||||
this.Margin = oldMargin;
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -202,6 +138,21 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
|
|||
}
|
||||
}
|
||||
|
||||
#region json expand classes
|
||||
|
||||
public class ExploreFeedContent
|
||||
{
|
||||
public string content_type;
|
||||
public List<ExplorerFeedItem> group_items;
|
||||
public string group_link;
|
||||
public string group_subtitle;
|
||||
public string group_title;
|
||||
public string icon_url;
|
||||
public string image_url;
|
||||
public string link;
|
||||
public string theme_filter;
|
||||
}
|
||||
|
||||
public class ExplorerFeed
|
||||
{
|
||||
public List<ExploreFeedContent> Content;
|
||||
|
|
@ -216,132 +167,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
|
|||
public string description;
|
||||
public string hero;
|
||||
public string icon;
|
||||
public string reference;
|
||||
public string title;
|
||||
public string url;
|
||||
public string reference;
|
||||
}
|
||||
|
||||
public class ExploreSection : FlowLayoutWidget
|
||||
{
|
||||
private List<ExploreItem> allIconViews = new List<ExploreItem>();
|
||||
private int cellIndex = 0;
|
||||
private int columnCount = 1;
|
||||
private ExploreFeedContent content;
|
||||
private int lastReflowWidth = -1;
|
||||
private int leftRightMargin;
|
||||
private FlowLayoutWidget rowButtonContainer = null;
|
||||
|
||||
public ExploreSection(ExploreFeedContent content)
|
||||
: base(FlowDirection.TopToBottom)
|
||||
{
|
||||
this.content = content;
|
||||
this.HAnchor = HAnchor.Stretch;
|
||||
|
||||
foreach (var item in content.group_items)
|
||||
{
|
||||
allIconViews.Add(new ExploreItem(item));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnBoundsChanged(EventArgs e)
|
||||
{
|
||||
int currentWidth = (int)this.Size.X;
|
||||
if (lastReflowWidth != currentWidth)
|
||||
{
|
||||
lastReflowWidth = currentWidth;
|
||||
|
||||
int newColumnCount = RecomputeFlowValues();
|
||||
if (newColumnCount != columnCount)
|
||||
{
|
||||
columnCount = newColumnCount;
|
||||
|
||||
// Reflow Children
|
||||
foreach (var iconView in allIconViews)
|
||||
{
|
||||
iconView.Parent?.RemoveChild(iconView);
|
||||
iconView.Margin = new BorderDouble(leftRightMargin, 0);
|
||||
}
|
||||
|
||||
this.CloseAllChildren();
|
||||
|
||||
if (content.group_title != null)
|
||||
{
|
||||
this.AddChild(new TextWidget(content.group_title, pointSize: 16, textColor: ActiveTheme.Instance.PrimaryTextColor)
|
||||
{
|
||||
HAnchor = HAnchor.Left,
|
||||
Margin = new BorderDouble(5)
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var iconView in allIconViews)
|
||||
{
|
||||
iconView.ClearRemovedFlag();
|
||||
AddColumnAndChild(iconView);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var iconView in allIconViews)
|
||||
{
|
||||
iconView.Margin = new BorderDouble(leftRightMargin, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnBoundsChanged(e);
|
||||
}
|
||||
|
||||
private void AddColumnAndChild(ExploreItem iconView)
|
||||
{
|
||||
if (rowButtonContainer == null)
|
||||
{
|
||||
rowButtonContainer = new FlowLayoutWidget(FlowDirection.LeftToRight)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Padding = 0
|
||||
};
|
||||
this.AddChild(rowButtonContainer);
|
||||
}
|
||||
|
||||
rowButtonContainer.AddChild(iconView);
|
||||
|
||||
if (cellIndex++ >= columnCount - 1)
|
||||
{
|
||||
rowButtonContainer = null;
|
||||
cellIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int RecomputeFlowValues()
|
||||
{
|
||||
int padding = 4;
|
||||
int itemWidth = (int)allIconViews[0].Width + (padding * 2);
|
||||
|
||||
int newColumnCount = (int)Math.Floor(this.LocalBounds.Width / itemWidth);
|
||||
int remainingSpace = (int)this.LocalBounds.Width - columnCount * itemWidth;
|
||||
|
||||
// Reset position before reflow
|
||||
cellIndex = 0;
|
||||
rowButtonContainer = null;
|
||||
|
||||
// There should always be at least one visible column
|
||||
if (newColumnCount < 1)
|
||||
{
|
||||
newColumnCount = 1;
|
||||
}
|
||||
|
||||
// Only center items if extra space exists
|
||||
|
||||
// we find the space we want between each column and the sides
|
||||
double spacePerColumn = (remainingSpace > 0) ? remainingSpace / (newColumnCount + 1) : 0;
|
||||
|
||||
// set the margin to be 1/2 the space (it will happen on each side of each icon)
|
||||
leftRightMargin = (int)(remainingSpace > 0 ? spacePerColumn / 2 : 0);
|
||||
|
||||
// put in padding to get the "other" side of the outside icons
|
||||
this.Padding = new BorderDouble(leftRightMargin, 0);
|
||||
|
||||
return newColumnCount;
|
||||
}
|
||||
}
|
||||
#endregion json expand classes
|
||||
}
|
||||
160
PartPreviewWindow/PlusTab/ExploreSection.cs
Normal file
160
PartPreviewWindow/PlusTab/ExploreSection.cs
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
Copyright (c) 2017, 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;
|
||||
using System.Collections.Generic;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
|
||||
namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
|
||||
{
|
||||
public class ExploreSection : FlowLayoutWidget
|
||||
{
|
||||
private List<ExploreItem> allIconViews = new List<ExploreItem>();
|
||||
private int cellIndex = 0;
|
||||
private int columnCount = 1;
|
||||
private ExploreFeedContent content;
|
||||
private int lastReflowWidth = -1;
|
||||
private int leftRightMargin;
|
||||
private FlowLayoutWidget rowButtonContainer = null;
|
||||
|
||||
public ExploreSection(ExploreFeedContent content)
|
||||
: base(FlowDirection.TopToBottom)
|
||||
{
|
||||
this.content = content;
|
||||
this.HAnchor = HAnchor.Stretch;
|
||||
|
||||
foreach (var item in content.group_items)
|
||||
{
|
||||
allIconViews.Add(new ExploreItem(item));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnBoundsChanged(EventArgs e)
|
||||
{
|
||||
int currentWidth = (int)this.Size.X;
|
||||
if (lastReflowWidth != currentWidth)
|
||||
{
|
||||
lastReflowWidth = currentWidth;
|
||||
|
||||
int newColumnCount = RecomputeFlowValues();
|
||||
if (newColumnCount != columnCount)
|
||||
{
|
||||
columnCount = newColumnCount;
|
||||
|
||||
// Reflow Children
|
||||
foreach (var iconView in allIconViews)
|
||||
{
|
||||
iconView.Parent?.RemoveChild(iconView);
|
||||
iconView.Margin = new BorderDouble(leftRightMargin, 0);
|
||||
}
|
||||
|
||||
this.CloseAllChildren();
|
||||
|
||||
if (content.group_title != null)
|
||||
{
|
||||
this.AddChild(new TextWidget(content.group_title, pointSize: 16, textColor: ActiveTheme.Instance.PrimaryTextColor)
|
||||
{
|
||||
HAnchor = HAnchor.Left,
|
||||
Margin = new BorderDouble(5)
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var iconView in allIconViews)
|
||||
{
|
||||
iconView.ClearRemovedFlag();
|
||||
AddColumnAndChild(iconView);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var iconView in allIconViews)
|
||||
{
|
||||
iconView.Margin = new BorderDouble(leftRightMargin, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnBoundsChanged(e);
|
||||
}
|
||||
|
||||
private void AddColumnAndChild(ExploreItem iconView)
|
||||
{
|
||||
if (rowButtonContainer == null)
|
||||
{
|
||||
rowButtonContainer = new FlowLayoutWidget(FlowDirection.LeftToRight)
|
||||
{
|
||||
HAnchor = HAnchor.Stretch,
|
||||
Padding = 0
|
||||
};
|
||||
this.AddChild(rowButtonContainer);
|
||||
}
|
||||
|
||||
rowButtonContainer.AddChild(iconView);
|
||||
|
||||
if (cellIndex++ >= columnCount - 1)
|
||||
{
|
||||
rowButtonContainer = null;
|
||||
cellIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private int RecomputeFlowValues()
|
||||
{
|
||||
int padding = 4;
|
||||
int itemWidth = (int)allIconViews[0].Width + (padding * 2);
|
||||
|
||||
int newColumnCount = (int)Math.Floor(this.LocalBounds.Width / itemWidth);
|
||||
int remainingSpace = (int)this.LocalBounds.Width - columnCount * itemWidth;
|
||||
|
||||
// Reset position before reflow
|
||||
cellIndex = 0;
|
||||
rowButtonContainer = null;
|
||||
|
||||
// There should always be at least one visible column
|
||||
if (newColumnCount < 1)
|
||||
{
|
||||
newColumnCount = 1;
|
||||
}
|
||||
|
||||
// Only center items if extra space exists
|
||||
|
||||
// we find the space we want between each column and the sides
|
||||
double spacePerColumn = (remainingSpace > 0) ? remainingSpace / (newColumnCount + 1) : 0;
|
||||
|
||||
// set the margin to be 1/2 the space (it will happen on each side of each icon)
|
||||
leftRightMargin = (int)(remainingSpace > 0 ? spacePerColumn / 2 : 0);
|
||||
|
||||
// put in padding to get the "other" side of the outside icons
|
||||
this.Padding = new BorderDouble(leftRightMargin, 0);
|
||||
|
||||
return newColumnCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 0d8468bd3f43708eb921d677e4a0e35b8b6dcbd3
|
||||
Subproject commit 0d57ebf6abaa365881fd9f9b18562c288ab8cb66
|
||||
Loading…
Add table
Add a link
Reference in a new issue