diff --git a/MatterControl.csproj b/MatterControl.csproj
index 1f210f4cc..e2ca59fc1 100644
--- a/MatterControl.csproj
+++ b/MatterControl.csproj
@@ -117,7 +117,9 @@
+
+
diff --git a/PartPreviewWindow/PlusTab/ExploreItem.cs b/PartPreviewWindow/PlusTab/ExploreItem.cs
new file mode 100644
index 000000000..f5af1d9a5
--- /dev/null
+++ b/PartPreviewWindow/PlusTab/ExploreItem.cs
@@ -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);
+ };
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/PartPreviewWindow/PlusTab/ExplorePanel.cs b/PartPreviewWindow/PlusTab/ExplorePanel.cs
index a1d4142a0..e97f716c7 100644
--- a/PartPreviewWindow/PlusTab/ExplorePanel.cs
+++ b/PartPreviewWindow/PlusTab/ExplorePanel.cs
@@ -39,78 +39,6 @@ using Newtonsoft.Json;
namespace MatterHackers.MatterControl.PartPreviewWindow.PlusTab
{
- public class ExploreFeedContent
- {
- public string content_type;
- public List 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 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 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 allIconViews = new List();
- 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
}
\ No newline at end of file
diff --git a/PartPreviewWindow/PlusTab/ExploreSection.cs b/PartPreviewWindow/PlusTab/ExploreSection.cs
new file mode 100644
index 000000000..b6ce8a895
--- /dev/null
+++ b/PartPreviewWindow/PlusTab/ExploreSection.cs
@@ -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 allIconViews = new List();
+ 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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp
index 0d8468bd3..0d57ebf6a 160000
--- a/Submodules/agg-sharp
+++ b/Submodules/agg-sharp
@@ -1 +1 @@
-Subproject commit 0d8468bd3f43708eb921d677e4a0e35b8b6dcbd3
+Subproject commit 0d57ebf6abaa365881fd9f9b18562c288ab8cb66