mattercontrol/MatterControlLib/Utilities/MarkdigAgg/Inlines/AggLinkInlineRenderer.cs

298 lines
7.3 KiB
C#
Raw Normal View History

// Copyright (c) 2016-2017 Nicolas Musset. All rights reserved.
// This file is licensed under the MIT license.
// See the LICENSE.md file in the project root for more information.
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using Markdig.Agg;
using Markdig.Syntax.Inlines;
using MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl;
using MatterHackers.VectorMath;
namespace Markdig.Renderers.Agg.Inlines
{
public class TextLinkX : FlowLayoutWidget
{
private LinkInline linkInline;
private string url;
private AggRenderer aggRenderer;
public TextLinkX(AggRenderer renderer, string url, LinkInline linkInline)
{
this.HAnchor = HAnchor.Fit;
this.VAnchor = VAnchor.Fit;
this.Cursor = Cursors.Hand;
this.linkInline = linkInline;
this.url = url;
this.aggRenderer = renderer;
}
protected override void OnClick(MouseEventArgs mouseEvent)
{
if (linkInline.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
2020-09-22 17:52:57 -07:00
ApplicationController.LaunchBrowser(linkInline.Url);
}
else
{
if (aggRenderer.RootWidget.Parents<MarkdownWidget>().FirstOrDefault() is MarkdownWidget markdownWidget)
{
markdownWidget.LoadUri(new Uri(url));
}
}
base.OnClick(mouseEvent);
}
2020-06-05 12:16:37 -07:00
public override GuiWidget AddChild(GuiWidget childToAdd, int indexInChildrenList = -1)
{
if (childToAdd is TextWidget textWidget)
{
// Underline TextWidget children of TextLink nodes
textWidget.Underline = true;
}
// Allow link parent to own mouse events
childToAdd.Selectable = false;
2020-06-05 12:16:37 -07:00
return base.AddChild(childToAdd, indexInChildrenList);
}
}
public class ImageLinkSimpleX : FlowLayoutWidget
{
private static ImageBuffer icon = StaticData.Instance.LoadIcon("internet.png", 16, 16);
public ImageLinkSimpleX(AggRenderer renderer, string imageUrl, string linkUrl = null)
{
this.HAnchor = HAnchor.Stretch;
this.VAnchor = VAnchor.Fit;
this.Selectable = false;
this.ImageUrl = imageUrl;
this.LinkUrl = linkUrl;
this.aggRenderer = renderer;
if (linkUrl != null)
{
this.Selectable = true;
}
sequenceWidget = new ResponsiveImageSequenceWidget(new ImageSequence(icon))
{
Cursor = Cursors.Hand,
};
2020-08-16 19:58:22 -07:00
sequenceWidget.MaximumSizeChanged += (s, e) =>
{
this.MinStretchOrFitHorizontal(20 * GuiWidget.DeviceScale, sequenceWidget.MaximumSize.X);
if (aggRenderer.RootWidget.Parents<MarkdownWidget>().FirstOrDefault() is MarkdownWidget markdownWidget)
{
markdownWidget.Width += 1;
}
};
sequenceWidget.Click += SequenceWidget_Click;
this.AddChild(sequenceWidget);
}
private void SequenceWidget_Click(object sender, MouseEventArgs e)
{
if (this.LinkUrl != null)
{
if (LinkUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
2020-09-22 17:52:57 -07:00
ApplicationController.LaunchBrowser(LinkUrl);
}
else
{
2020-06-27 19:21:04 -07:00
try
{
if (aggRenderer.RootWidget.Parents<MarkdownWidget>().FirstOrDefault() is MarkdownWidget markdownWidget)
{
markdownWidget.LoadUri(new Uri(LinkUrl));
}
}
catch
{
}
}
}
}
public override void OnDraw(Graphics2D graphics2D)
{
if (!hasBeenLoaded)
{
if (ImageUrl.StartsWith("http"))
{
2020-08-16 19:58:22 -07:00
WebCache.RetrieveImageSquenceAsync(sequenceWidget.ImageSequence, ImageUrl);
}
hasBeenLoaded = true;
}
base.OnDraw(graphics2D);
}
2020-05-30 16:50:36 -07:00
/// <summary>
/// Sets this control to Stretch and all direct parent FlowLayoutWidgets to Stretch, it then ensures
/// this and all direct parent FlowLayouts have a max width of the contents of this.
/// </summary>
/// <param name="absoluteMinWidth">The minimum size will be set to the larger of the existing minimum size or this value.</param>
/// <param name="absoluteMaxWidth">The maximum size will be set to this value.</param>
private void MinStretchOrFitHorizontal(double absoluteMinWidth, double absoluteMaxWidth)
{
this.HAnchor = HAnchor.Stretch;
MinimumSize = new Vector2(Math.Max(absoluteMinWidth, MinimumSize.X), MinimumSize.Y);
2020-05-30 16:50:36 -07:00
MaximumSize = new Vector2(absoluteMaxWidth, MaximumSize.Y);
}
public string ImageUrl { get; }
private string LinkUrl { get; }
private AggRenderer aggRenderer;
private bool hasBeenLoaded;
private ResponsiveImageSequenceWidget sequenceWidget;
}
public class ImageLinkAdvancedX : FlowLayoutWidget
{
private static HttpClient client = new HttpClient();
private static ImageBuffer icon = StaticData.Instance.LoadIcon("internet.png", 16, 16);
public string Url { get; }
public ImageLinkAdvancedX(string url)
{
HAnchor = HAnchor.Fit;
VAnchor = VAnchor.Fit;
this.Url = url;
var imageBuffer = new ImageBuffer(icon);
var imageWidget = new ImageWidget(imageBuffer);
this.AddChild(imageWidget);
try
{
if (url.StartsWith("http"))
{
client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ContinueWith(task =>
{
var response = task.Result;
if (response.IsSuccessStatusCode)
{
response.Content.ReadAsStreamAsync().ContinueWith(streamTask =>
{
// response.Headers.TryGetValues("", s[""] == "" ||
if (string.Equals(Path.GetExtension(url), ".svg", StringComparison.OrdinalIgnoreCase))
{
// Load svg into SvgWidget, swap for ImageWidget
try
{
var svgWidget = new SvgWidget(streamTask.Result, 1)
{
Border = 1,
BorderColor = Color.YellowGreen
};
this.ReplaceChild(imageWidget, svgWidget);
}
catch (Exception svgEx)
{
Debug.WriteLine("Error loading svg: {0} :: {1}", url, svgEx.Message);
}
}
else
{
// Load img
2020-11-24 18:08:49 -08:00
if (!ImageIO.LoadImageData(streamTask.Result, imageBuffer))
{
Debug.WriteLine("Error loading image: " + url);
}
}
});
}
});
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
/// <summary>
/// A Agg renderer for a <see cref="LinkInline"/>.
/// </summary>
/// <seealso cref="Markdig.Renderers.Agg.AggObjectRenderer{Markdig.Syntax.Inlines.LinkInline}" />
public class AggLinkInlineRenderer : AggObjectRenderer<LinkInline>
{
/// <inheritdoc/>
protected override void Write(AggRenderer renderer, LinkInline link)
{
var url = link.GetDynamicUrl != null ? link.GetDynamicUrl() ?? link.Url : link.Url;
if (!Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute))
{
url = "#";
}
if (!url.StartsWith("http"))
{
var pageID = url;
url = new Uri(renderer.BaseUri, url).AbsoluteUri;
renderer.ChildLinks.Add(new MarkdownDocumentLink()
{
Uri = new Uri(url),
LinkInline = link,
PageID = pageID
});
}
if (link.IsImage)
{
2020-06-27 13:12:26 -07:00
if (link.Parent is LinkInline linkInLine)
{
renderer.WriteInline(new ImageLinkSimpleX(renderer, url, linkInLine.Url));
}
else
{
renderer.WriteInline(new ImageLinkSimpleX(renderer, url));
}
}
else
{
if (link.FirstChild is LinkInline linkInLine
&& linkInLine.IsImage)
{
2020-06-27 13:12:26 -07:00
renderer.WriteChildren(link);
}
else
{
renderer.Push(new TextLinkX(renderer, url, link));
renderer.WriteChildren(link);
renderer.Pop();
}
}
}
}
}