Skip to content

Commit

Permalink
Added support to override URL clicks in PopupViewer (#584)
Browse files Browse the repository at this point in the history
* Added support to override URL clicks in PopupViewer

* Added samples for reference

* Refactor PopupViewer and event handling

* Refactor hyperlink event handling and cleanup

- Corrected the event name from `HyperLinkClicked` to `HyperlinkClicked` in both XAML and code-behind files for consistency and to meet case sensitivity requirements.

* Refactor GetPopupViewerParent to generic

* Refactor GetParent<T> generic constraint

* Broaden type check in Tapped event handler

* Refine type checks and adjust imports

* Refactor PopupViewer parent traversal logic
  • Loading branch information
prathameshnarkhede authored Jul 16, 2024
1 parent ac1bc3e commit 789e346
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<Border Background="#99ffffff" x:Name="popupPanel" IsVisible="False">
<Border HorizontalOptions="Center" VerticalOptions="Center" Background="{AppThemeBinding Dark=Black, Light=White}" Margin="0,32" Padding="12">
<Grid>
<esriTK:PopupViewer x:Name="popupViewer" Padding="12" MaximumWidthRequest="400" MaximumHeightRequest="400" PopupAttachmentClicked="popupViewer_PopupAttachmentClicked" />
<esriTK:PopupViewer x:Name="popupViewer" Padding="12" MaximumWidthRequest="400" MaximumHeightRequest="400" PopupAttachmentClicked="popupViewer_PopupAttachmentClicked" HyperlinkClicked="popupViewer_HyperlinkClicked" />
<Button BorderWidth="0" Text="X" HorizontalOptions="End" VerticalOptions="Start" Clicked="CloseButton_Click" BackgroundColor="Transparent" TextColor="{AppThemeBinding Dark=White, Light=Black}" Margin="5" />
</Grid>
</Border>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Mapping.Popups;
using Esri.ArcGISRuntime.Maui;
using Esri.ArcGISRuntime.Security;
using Esri.ArcGISRuntime.UI;
using Microsoft.Maui.Controls.Shapes;
using System.Diagnostics;

namespace Toolkit.SampleApp.Maui.Samples
{
Expand Down Expand Up @@ -117,5 +115,14 @@ private void popupViewer_PopupAttachmentClicked(object sender, Esri.ArcGISRuntim
_ = Microsoft.Maui.ApplicationModel.Launcher.Default.OpenAsync(
new Microsoft.Maui.ApplicationModel.OpenFileRequest(e.Attachment.Name, new ReadOnlyFile(e.Attachment.Filename!, e.Attachment.ContentType)));
}

private void popupViewer_HyperlinkClicked(object sender, Esri.ArcGISRuntime.Toolkit.Maui.HyperlinkClickedEventArgs e)
{
// Include below line if you want to prevent the default action
// e.Handled = true;

// Perform custom action when a link is clicked
Debug.WriteLine(e.Uri);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

<Grid Background="#AA333333" Visibility="Collapsed" x:Name="PopupBackground" MouseDown="PopupBackground_MouseDown">
<Border BorderBrush="Black" BorderThickness="1" Background="White" HorizontalAlignment="Center" VerticalAlignment="Center" >
<esri:PopupViewer x:Name="popupViewer" Margin="5" Width="400" MaxHeight="400" PopupAttachmentClicked="popupViewer_PopupAttachmentClicked" />
<esri:PopupViewer x:Name="popupViewer" Margin="5" Width="400" MaxHeight="400" PopupAttachmentClicked="popupViewer_PopupAttachmentClicked" HyperlinkClicked="popupViewer_LinkClicked" />
</Border>
</Grid>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Esri.ArcGISRuntime.UI.Controls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
Expand Down Expand Up @@ -154,5 +155,14 @@ private async void popupViewer_PopupAttachmentClicked(object sender, UI.Controls
}
}
}

private void popupViewer_LinkClicked(object sender, UI.Controls.HyperlinkClickedEventArgs e)
{
// Include below line if you want to prevent the default action
// e.Handled = true;

// Perform custom action when a link is clicked
Debug.WriteLine(e.Uri);
}
}
}
12 changes: 12 additions & 0 deletions src/Toolkit/Toolkit/UI/Controls/PopupViewer/PopupViewer.Maui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,18 @@ internal static Style GetStyle(string resourceKey, Style defaultStyle)
internal static Style GetPopupViewerTitleStyle() => GetStyle(PopupViewerTitleStyleName, DefaultPopupViewerTitleStyle);

internal static Style GetPopupViewerCaptionStyle() => GetStyle(PopupViewerCaptionStyleName, DefaultPopupViewerCaptionStyle);

internal static PopupViewer? GetPopupViewerParent(Element element) => GetParent<PopupViewer>(element);

private static T? GetParent<T>(Element element) where T : Element
{
var parent = element.Parent;
while (parent is not null and not T)
{
parent = parent.Parent;
}
return parent as T;
}
}
}
#endif
28 changes: 28 additions & 0 deletions src/Toolkit/Toolkit/UI/Controls/PopupViewer/PopupViewer.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,34 @@ private static void OnPopupManagerPropertyChanged(DependencyObject d, Dependency
((PopupViewer)d).Popup = ((PopupViewer)d).PopupManager?.Popup;
#pragma warning restore CS0618 // Type or member is obsolete
}

internal static PopupViewer? GetPopupViewerParent(DependencyObject? child) => GetParent<PopupViewer>(child);

private static T? GetParent<T>(DependencyObject? child) where T : DependencyObject
{
if (child is FrameworkContentElement elm)
{
child = GetVisualParent(elm);
}
if (child is null)
return default;
var parent = VisualTreeHelper.GetParent(child);
while (parent is not null and not T)
{
parent = VisualTreeHelper.GetParent(parent);
}
return parent as T;
}

private static Visual? GetVisualParent(FrameworkContentElement child)
{
var parent = child.Parent;
while (parent is FrameworkContentElement elm)
{
parent = elm.Parent;
}
return parent as Visual;
}
}
}
#endif
47 changes: 45 additions & 2 deletions src/Toolkit/Toolkit/UI/Controls/PopupViewer/PopupViewer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

#if MAUI
using Esri.ArcGISRuntime.Toolkit.Maui.Primitives;
using DependencyObject = Microsoft.Maui.Controls.BindableObject;
using ScrollViewer = Microsoft.Maui.Controls.ScrollView;
#else
using Esri.ArcGISRuntime.Toolkit.Primitives;
Expand Down Expand Up @@ -244,11 +243,34 @@ internal bool OnPopupAttachmentClicked(PopupAttachment attachment)
if (handler is not null)
{
var args = new PopupAttachmentClickedEventArgs(attachment);
PopupAttachmentClicked?.Invoke(this, args);
handler.Invoke(this, args);
return args.Handled;
}
return false;
}

/// <summary>
/// Raised when a link is clicked
/// </summary>
/// <remarks>
/// <para>By default, when an link is clicked, the default application (Browser) for the file type (if any) is launched. To override this,
/// listen to this event, set the <see cref="HyperlinkClickedEventArgs.Handled"/> property to <c>true</c> and perform
/// your own logic. </para>
/// </remarks>
public event EventHandler<HyperlinkClickedEventArgs>? HyperlinkClicked;

internal void OnHyperlinkClicked(Uri uri)
{
var handler = HyperlinkClicked;
if (handler is not null)
{
var args = new HyperlinkClickedEventArgs(uri);
handler.Invoke(this, args);
if (args.Handled)
return;
}
Launcher.LaunchUriAsync(uri);
}
}

/// <summary>
Expand All @@ -271,5 +293,26 @@ internal PopupAttachmentClickedEventArgs(PopupAttachment attachment)
/// </summary>
public PopupAttachment Attachment { get; }
}

/// <summary>
/// Event argument for the <see cref="PopupViewer.HyperlinkClicked"/> event.
/// </summary>
public sealed class HyperlinkClickedEventArgs : EventArgs
{
internal HyperlinkClickedEventArgs(Uri uri)
{
Uri = uri;
}

/// <summary>
/// Gets or sets a value indicating whether the event handler has handled the event and the default action should be prevented.
/// </summary>
public bool Handled { get; set; }

/// <summary>
/// Gets the URI that was clicked.
/// </summary>
public Uri Uri { get; }
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,10 @@ private static IEnumerable<Span> VisitInline(MarkupNode node)
var tapRecognizer = new TapGestureRecognizer();
tapRecognizer.Tapped += (s, e) =>
{
try
if (s is Element element)
{
Browser.OpenAsync(node.Content, BrowserLaunchMode.SystemPreferred);
PopupViewer.GetPopupViewerParent(element)?.OnHyperlinkClicked(linkUri);
}
catch { }
};
foreach (var subNode in node.Children)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#if WPF
using Esri.ArcGISRuntime.Mapping.Popups;
using Esri.ArcGISRuntime.Toolkit.Internal;
using Esri.ArcGISRuntime.Toolkit.UI.Controls;
using Esri.ArcGISRuntime.UI;
using System.Windows.Documents;
using System.Windows.Input;
Expand Down Expand Up @@ -287,9 +288,9 @@ private static System.Windows.Media.Color ConvertColor(System.Drawing.Color colo
_ => TextAlignment.Left,
};

private static async void NavigateToUri(object sender, RequestNavigateEventArgs ea)
private static void NavigateToUri(object sender, RequestNavigateEventArgs ea)
{
await Launcher.LaunchUriAsync(ea.Uri);
PopupViewer.GetPopupViewerParent(sender as DependencyObject)?.OnHyperlinkClicked(ea.Uri);
}
}
}
Expand Down

0 comments on commit 789e346

Please sign in to comment.