Browse Source
# Conflicts: # src/Avalonia.Base/Input/IPointer.cs # src/Windows/Avalonia.Win32/WindowImpl.csStylus
534 changed files with 8328 additions and 4889 deletions
File diff suppressed because it is too large
@ -0,0 +1,2 @@ |
|||
T:Avalonia.Metadata.NotClientImplementableAttribute |
|||
T:Avalonia.Metadata.UnstableAttribute |
|||
@ -0,0 +1,5 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<AvaloniaPublicKey>0024000004800000940000000602000000240000525341310004000001000100c1bba1142285fe0419326fb25866ba62c47e6c2b5c1ab0c95b46413fad375471232cb81706932e1cef38781b9ebd39d5100401bacb651c6c5bbf59e571e81b3bc08d2a622004e08b1a6ece82a7e0b9857525c86d2b95fab4bc3dce148558d7f3ae61aa3a234086902aeface87d9dfdd32b9d2fe3c6dd4055b5ab4b104998bd87</AvaloniaPublicKey> |
|||
</PropertyGroup> |
|||
</Project> |
|||
@ -1,7 +1,7 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="HarfBuzzSharp" Version="2.8.2-preview.254" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2-preview.254" /> |
|||
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="2.8.2-preview.254"/> |
|||
<PackageReference Include="HarfBuzzSharp" Version="2.8.2" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2" /> |
|||
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="2.8.2" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -1,5 +1,5 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="JetBrains.DotMemoryUnit" Version="3.1.20200127.214830" /> |
|||
<PackageReference Include="JetBrains.DotMemoryUnit" Version="3.2.20220510" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -1,7 +1,6 @@ |
|||
<Project> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
|
|||
@ -1,7 +1,7 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="SkiaSharp" Version="2.88.0-preview.254" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.88.0-preview.254" /> |
|||
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="SkiaSharp.NativeAssets.WebAssembly" Version="2.88.0-preview.254"/> |
|||
<PackageReference Include="SkiaSharp" Version="2.88.1-preview.1" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="2.88.1-preview.1" /> |
|||
<PackageReference Condition="'$(IncludeWasmSkia)' == 'true'" Include="SkiaSharp.NativeAssets.WebAssembly" Version="2.88.1-preview.1" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -0,0 +1,35 @@ |
|||
using System; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Android; |
|||
using ControlCatalog.Pages; |
|||
|
|||
namespace ControlCatalog.Android; |
|||
|
|||
public class EmbedSampleAndroid : INativeDemoControl |
|||
{ |
|||
public IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func<IPlatformHandle> createDefault) |
|||
{ |
|||
var parentContext = (parent as AndroidViewControlHandle)?.View.Context |
|||
?? global::Android.App.Application.Context; |
|||
|
|||
if (isSecond) |
|||
{ |
|||
var webView = new global::Android.Webkit.WebView(parentContext); |
|||
webView.LoadUrl("https://www.android.com/"); |
|||
|
|||
return new AndroidViewControlHandle(webView); |
|||
} |
|||
else |
|||
{ |
|||
var button = new global::Android.Widget.Button(parentContext) { Text = "Hello world" }; |
|||
var clickCount = 0; |
|||
button.Click += (sender, args) => |
|||
{ |
|||
clickCount++; |
|||
button.Text = $"Click count {clickCount}"; |
|||
}; |
|||
|
|||
return new AndroidViewControlHandle(button); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using System.IO; |
|||
using System.Diagnostics; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Controls.Platform; |
|||
using System; |
|||
using ControlCatalog.Pages; |
|||
|
|||
namespace ControlCatalog.NetCore; |
|||
|
|||
public class EmbedSampleGtk : INativeDemoControl |
|||
{ |
|||
private Process _mplayer; |
|||
|
|||
public IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func<IPlatformHandle> createDefault) |
|||
{ |
|||
if (isSecond) |
|||
{ |
|||
var chooser = GtkHelper.CreateGtkFileChooser(parent.Handle); |
|||
if (chooser != null) |
|||
return chooser; |
|||
} |
|||
|
|||
var control = createDefault(); |
|||
var nodes = Path.GetFullPath(Path.Combine(typeof(EmbedSample).Assembly.GetModules()[0].FullyQualifiedName, |
|||
"..", |
|||
"nodes.mp4")); |
|||
_mplayer = Process.Start(new ProcessStartInfo("mplayer", |
|||
$"-vo x11 -zoom -loop 0 -wid {control.Handle.ToInt64()} \"{nodes}\"") |
|||
{ |
|||
UseShellExecute = false, |
|||
|
|||
}); |
|||
return control; |
|||
} |
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Avalonia.Controls.Platform; |
|||
using Avalonia.Platform.Interop; |
|||
using Avalonia.X11.NativeDialogs; |
|||
using static Avalonia.X11.NativeDialogs.Gtk; |
|||
using static Avalonia.X11.NativeDialogs.Glib; |
|||
|
|||
namespace ControlCatalog.NetCore; |
|||
|
|||
internal class GtkHelper |
|||
{ |
|||
private static Task<bool> s_gtkTask; |
|||
|
|||
class FileChooser : INativeControlHostDestroyableControlHandle |
|||
{ |
|||
private readonly IntPtr _widget; |
|||
|
|||
public FileChooser(IntPtr widget, IntPtr xid) |
|||
{ |
|||
_widget = widget; |
|||
Handle = xid; |
|||
} |
|||
|
|||
public IntPtr Handle { get; } |
|||
public string HandleDescriptor => "XID"; |
|||
|
|||
public void Destroy() |
|||
{ |
|||
RunOnGlibThread(() => |
|||
{ |
|||
gtk_widget_destroy(_widget); |
|||
return 0; |
|||
}).Wait(); |
|||
} |
|||
} |
|||
|
|||
|
|||
public static INativeControlHostDestroyableControlHandle CreateGtkFileChooser(IntPtr parentXid) |
|||
{ |
|||
if (s_gtkTask == null) |
|||
s_gtkTask = StartGtk(); |
|||
if (!s_gtkTask.Result) |
|||
return null; |
|||
return RunOnGlibThread(() => |
|||
{ |
|||
using (var title = new Utf8Buffer("Embedded")) |
|||
{ |
|||
var widget = gtk_file_chooser_dialog_new(title, IntPtr.Zero, GtkFileChooserAction.SelectFolder, |
|||
IntPtr.Zero); |
|||
gtk_widget_realize(widget); |
|||
var xid = gdk_x11_window_get_xid(gtk_widget_get_window(widget)); |
|||
gtk_window_present(widget); |
|||
return new FileChooser(widget, xid); |
|||
} |
|||
}).Result; |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System; |
|||
|
|||
using Avalonia.Platform; |
|||
using Avalonia.Threading; |
|||
|
|||
using ControlCatalog.Pages; |
|||
|
|||
using MonoMac.Foundation; |
|||
using MonoMac.WebKit; |
|||
|
|||
namespace ControlCatalog.NetCore; |
|||
|
|||
public class EmbedSampleMac : INativeDemoControl |
|||
{ |
|||
public IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func<IPlatformHandle> createDefault) |
|||
{ |
|||
// Note: We are using MonoMac for example purposes
|
|||
// It shouldn't be used in production apps
|
|||
MacHelper.EnsureInitialized(); |
|||
|
|||
var webView = new WebView(); |
|||
Dispatcher.UIThread.Post(() => |
|||
{ |
|||
webView.MainFrame.LoadRequest(new NSUrlRequest(new NSUrl( |
|||
isSecond ? "https://bing.com" : "https://google.com/"))); |
|||
}); |
|||
return new MacOSViewHandle(webView); |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using System; |
|||
|
|||
using Avalonia.Controls.Platform; |
|||
using MonoMac.AppKit; |
|||
|
|||
namespace ControlCatalog.NetCore; |
|||
|
|||
internal class MacHelper |
|||
{ |
|||
private static bool _isInitialized; |
|||
|
|||
public static void EnsureInitialized() |
|||
{ |
|||
if (_isInitialized) |
|||
return; |
|||
_isInitialized = true; |
|||
NSApplication.Init(); |
|||
} |
|||
} |
|||
|
|||
internal class MacOSViewHandle : INativeControlHostDestroyableControlHandle |
|||
{ |
|||
private NSView _view; |
|||
|
|||
public MacOSViewHandle(NSView view) |
|||
{ |
|||
_view = view; |
|||
} |
|||
|
|||
public IntPtr Handle => _view?.Handle ?? IntPtr.Zero; |
|||
public string HandleDescriptor => "NSView"; |
|||
|
|||
public void Destroy() |
|||
{ |
|||
_view.Dispose(); |
|||
_view = null; |
|||
} |
|||
} |
|||
@ -0,0 +1,45 @@ |
|||
using System; |
|||
using System.Text; |
|||
|
|||
using Avalonia.Controls.Platform; |
|||
using Avalonia.Platform; |
|||
|
|||
using ControlCatalog.Pages; |
|||
|
|||
namespace ControlCatalog.NetCore; |
|||
|
|||
public class EmbedSampleWin : INativeDemoControl |
|||
{ |
|||
private const string RichText = |
|||
@"{\rtf1\ansi\ansicpg1251\deff0\nouicompat\deflang1049{\fonttbl{\f0\fnil\fcharset0 Calibri;}}
|
|||
{\colortbl ;\red255\green0\blue0;\red0\green77\blue187;\red0\green176\blue80;\red155\green0\blue211;\red247\green150\blue70;\red75\green172\blue198;} |
|||
{\*\generator Riched20 6.3.9600}\viewkind4\uc1 |
|||
\pard\sa200\sl276\slmult1\f0\fs22\lang9 <PREFIX>I \i am\i0 a \cf1\b Rich Text \cf0\b0\fs24 control\cf2\fs28 !\cf3\fs32 !\cf4\fs36 !\cf1\fs40 !\cf5\fs44 !\cf6\fs48 !\cf0\fs44\par |
|||
}";
|
|||
|
|||
public IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func<IPlatformHandle> createDefault) |
|||
{ |
|||
WinApi.LoadLibrary("Msftedit.dll"); |
|||
var handle = WinApi.CreateWindowEx(0, "RICHEDIT50W", |
|||
@"Rich Edit", |
|||
0x800000 | 0x10000000 | 0x40000000 | 0x800000 | 0x10000 | 0x0004, 0, 0, 1, 1, parent.Handle, |
|||
IntPtr.Zero, WinApi.GetModuleHandle(null), IntPtr.Zero); |
|||
var st = new WinApi.SETTEXTEX { Codepage = 65001, Flags = 0x00000008 }; |
|||
var text = RichText.Replace("<PREFIX>", isSecond ? "\\qr " : ""); |
|||
var bytes = Encoding.UTF8.GetBytes(text); |
|||
WinApi.SendMessage(handle, 0x0400 + 97, ref st, bytes); |
|||
return new Win32WindowControlHandle(handle, "HWND"); |
|||
} |
|||
} |
|||
|
|||
internal class Win32WindowControlHandle : PlatformHandle, INativeControlHostDestroyableControlHandle |
|||
{ |
|||
public Win32WindowControlHandle(IntPtr handle, string descriptor) : base(handle, descriptor) |
|||
{ |
|||
} |
|||
|
|||
public void Destroy() |
|||
{ |
|||
_ = WinApi.DestroyWindow(Handle); |
|||
} |
|||
} |
|||
@ -0,0 +1,73 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
namespace ControlCatalog.NetCore; |
|||
|
|||
internal unsafe class WinApi |
|||
{ |
|||
public enum CommonControls : uint |
|||
{ |
|||
ICC_LISTVIEW_CLASSES = 0x00000001, // listview, header
|
|||
ICC_TREEVIEW_CLASSES = 0x00000002, // treeview, tooltips
|
|||
ICC_BAR_CLASSES = 0x00000004, // toolbar, statusbar, trackbar, tooltips
|
|||
ICC_TAB_CLASSES = 0x00000008, // tab, tooltips
|
|||
ICC_UPDOWN_CLASS = 0x00000010, // updown
|
|||
ICC_PROGRESS_CLASS = 0x00000020, // progress
|
|||
ICC_HOTKEY_CLASS = 0x00000040, // hotkey
|
|||
ICC_ANIMATE_CLASS = 0x00000080, // animate
|
|||
ICC_WIN95_CLASSES = 0x000000FF, |
|||
ICC_DATE_CLASSES = 0x00000100, // month picker, date picker, time picker, updown
|
|||
ICC_USEREX_CLASSES = 0x00000200, // comboex
|
|||
ICC_COOL_CLASSES = 0x00000400, // rebar (coolbar) control
|
|||
ICC_INTERNET_CLASSES = 0x00000800, |
|||
ICC_PAGESCROLLER_CLASS = 0x00001000, // page scroller
|
|||
ICC_NATIVEFNTCTL_CLASS = 0x00002000, // native font control
|
|||
ICC_STANDARD_CLASSES = 0x00004000, |
|||
ICC_LINK_CLASS = 0x00008000 |
|||
} |
|||
|
|||
[StructLayout(LayoutKind.Sequential)] |
|||
public struct INITCOMMONCONTROLSEX |
|||
{ |
|||
public int dwSize; |
|||
public uint dwICC; |
|||
} |
|||
|
|||
[DllImport("Comctl32.dll")] |
|||
public static extern void InitCommonControlsEx(ref INITCOMMONCONTROLSEX init); |
|||
|
|||
[DllImport("user32.dll", SetLastError = true)] |
|||
public static extern bool DestroyWindow(IntPtr hwnd); |
|||
|
|||
[DllImport("kernel32.dll")] |
|||
public static extern IntPtr LoadLibrary(string lib); |
|||
|
|||
|
|||
[DllImport("kernel32.dll")] |
|||
public static extern IntPtr GetModuleHandle(string lpModuleName); |
|||
|
|||
[DllImport("user32.dll", SetLastError = true)] |
|||
public static extern IntPtr CreateWindowEx( |
|||
int dwExStyle, |
|||
string lpClassName, |
|||
string lpWindowName, |
|||
uint dwStyle, |
|||
int x, |
|||
int y, |
|||
int nWidth, |
|||
int nHeight, |
|||
IntPtr hWndParent, |
|||
IntPtr hMenu, |
|||
IntPtr hInstance, |
|||
IntPtr lpParam); |
|||
|
|||
[StructLayout(LayoutKind.Sequential)] |
|||
public struct SETTEXTEX |
|||
{ |
|||
public uint Flags; |
|||
public uint Codepage; |
|||
} |
|||
|
|||
[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW")] |
|||
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, ref SETTEXTEX wParam, byte[] lParam); |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> |
|||
<assemblyIdentity version="1.0.0.0" name="ControlCatalog.app"/> |
|||
|
|||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> |
|||
<application> |
|||
<!-- A list of the Windows versions that this application has been tested on |
|||
and is designed to work with. Uncomment the appropriate elements |
|||
and Windows will automatically select the most compatible environment. --> |
|||
|
|||
<!-- Windows Vista --> |
|||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />--> |
|||
|
|||
<!-- Windows 7 --> |
|||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />--> |
|||
|
|||
<!-- Windows 8 --> |
|||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />--> |
|||
|
|||
<!-- Windows 8.1 --> |
|||
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />--> |
|||
|
|||
<!-- Windows 10 --> |
|||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> |
|||
|
|||
</application> |
|||
</compatibility> |
|||
</assembly> |
|||
@ -0,0 +1,34 @@ |
|||
using System; |
|||
|
|||
using Avalonia; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Web.Blazor; |
|||
|
|||
using ControlCatalog.Pages; |
|||
|
|||
using Microsoft.JSInterop; |
|||
|
|||
namespace ControlCatalog.Web; |
|||
|
|||
public class EmbedSampleWeb : INativeDemoControl |
|||
{ |
|||
public IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func<IPlatformHandle> createDefault) |
|||
{ |
|||
var runtime = AvaloniaLocator.Current.GetRequiredService<IJSInProcessRuntime>(); |
|||
|
|||
if (isSecond) |
|||
{ |
|||
var iframe = runtime.Invoke<IJSInProcessObjectReference>("document.createElement", "iframe"); |
|||
iframe.InvokeVoid("setAttribute", "src", "https://www.youtube.com/embed/kZCIporjJ70"); |
|||
|
|||
return new JSObjectControlHandle(iframe); |
|||
} |
|||
else |
|||
{ |
|||
// window.createAppButton source is defined in "app.js" file.
|
|||
var button = runtime.Invoke<IJSInProcessObjectReference>("window.createAppButton"); |
|||
|
|||
return new JSObjectControlHandle(button); |
|||
} |
|||
} |
|||
} |
|||
@ -1,70 +0,0 @@ |
|||
.page { |
|||
position: relative; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.main { |
|||
flex: 1; |
|||
} |
|||
|
|||
.sidebar { |
|||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); |
|||
} |
|||
|
|||
.top-row { |
|||
background-color: #f7f7f7; |
|||
border-bottom: 1px solid #d6d5d5; |
|||
justify-content: flex-end; |
|||
height: 3.5rem; |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.top-row ::deep a, .top-row .btn-link { |
|||
white-space: nowrap; |
|||
margin-left: 1.5rem; |
|||
} |
|||
|
|||
.top-row a:first-child { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
} |
|||
|
|||
@media (max-width: 640.98px) { |
|||
.top-row:not(.auth) { |
|||
display: none; |
|||
} |
|||
|
|||
.top-row.auth { |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.top-row a, .top-row .btn-link { |
|||
margin-left: 0; |
|||
} |
|||
} |
|||
|
|||
@media (min-width: 641px) { |
|||
.page { |
|||
flex-direction: row; |
|||
} |
|||
|
|||
.sidebar { |
|||
width: 250px; |
|||
height: 100vh; |
|||
position: sticky; |
|||
top: 0; |
|||
} |
|||
|
|||
.top-row { |
|||
position: sticky; |
|||
top: 0; |
|||
z-index: 1; |
|||
} |
|||
|
|||
.main > div { |
|||
padding-left: 2rem !important; |
|||
padding-right: 1.5rem !important; |
|||
} |
|||
} |
|||
@ -1 +1,10 @@ |
|||
|
|||
window.createAppButton = function () { |
|||
var button = document.createElement('button'); |
|||
button.innerText = 'Hello world'; |
|||
var clickCount = 0; |
|||
button.onclick = () => { |
|||
clickCount++; |
|||
button.innerText = 'Click count ' + clickCount; |
|||
}; |
|||
return button; |
|||
} |
|||
|
|||
@ -0,0 +1,38 @@ |
|||
using System; |
|||
using Avalonia.Platform; |
|||
using CoreGraphics; |
|||
using Foundation; |
|||
using UIKit; |
|||
using WebKit; |
|||
using Avalonia.iOS; |
|||
using ControlCatalog.Pages; |
|||
|
|||
namespace ControlCatalog; |
|||
|
|||
public class EmbedSampleIOS : INativeDemoControl |
|||
{ |
|||
public IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func<IPlatformHandle> createDefault) |
|||
{ |
|||
if (isSecond) |
|||
{ |
|||
var webView = new WKWebView(CGRect.Empty, new WKWebViewConfiguration()); |
|||
webView.LoadRequest(new NSUrlRequest(new NSUrl("https://www.apple.com/"))); |
|||
|
|||
return new UIViewControlHandle(webView); |
|||
} |
|||
else |
|||
{ |
|||
var button = new UIButton(); |
|||
var clickCount = 0; |
|||
button.SetTitle("Hello world", UIControlState.Normal); |
|||
button.BackgroundColor = UIColor.Blue; |
|||
button.AddTarget((_, _) => |
|||
{ |
|||
clickCount++; |
|||
button.SetTitle($"Click count {clickCount}", UIControlState.Normal); |
|||
}, UIControlEvent.TouchDown); |
|||
|
|||
return new UIViewControlHandle(button); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
<UserControl xmlns="https://github.com/avaloniaui" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
|||
xmlns:local="using:ControlCatalog.Pages" |
|||
d:DesignHeight="800" |
|||
d:DesignWidth="400" |
|||
x:Class="ControlCatalog.Pages.NativeEmbedPage"> |
|||
<DockPanel> |
|||
<Menu DockPanel.Dock="Top"> |
|||
<MenuItem Header="Test"> |
|||
<MenuItem Header="SubMenu"> |
|||
<MenuItem Header="Item 1"/> |
|||
<MenuItem Header="Item 2"/> |
|||
<MenuItem Header="Item 3"/> |
|||
</MenuItem> |
|||
<MenuItem Header="Item 1"/> |
|||
<MenuItem Header="Item 2"/> |
|||
<MenuItem Header="Item 3"/> |
|||
</MenuItem> |
|||
</Menu> |
|||
<DockPanel DockPanel.Dock="Top"> |
|||
<Button DockPanel.Dock="Right" Click="ShowPopupDelay">Show popup (delay)</Button> |
|||
<Button DockPanel.Dock="Right" Click="ShowPopup">Show popup</Button> |
|||
<Border DockPanel.Dock="Right" Background="#c0c0c0"> |
|||
<ToolTip.Tip> |
|||
<ToolTip> |
|||
<TextBlock>Text</TextBlock> |
|||
</ToolTip> |
|||
</ToolTip.Tip> |
|||
<TextBlock VerticalAlignment="Center">Tooltip</TextBlock> |
|||
</Border> |
|||
<TextBox Text="Lorem ipsum dolor sit amet"/> |
|||
|
|||
</DockPanel> |
|||
<Grid ColumnDefinitions="*,5,*" |
|||
RowDefinitions="*,5,*"> |
|||
<Grid.Styles> |
|||
<Style Selector="DockPanel#FirstPanel:not(.mobile), DockPanel#SecondPanel:not(.mobile)"> |
|||
<Setter Property="Grid.RowSpan" Value="3" /> |
|||
</Style> |
|||
<Style Selector="DockPanel#SecondPanel:not(.mobile)"> |
|||
<Setter Property="Grid.Column" Value="2" /> |
|||
</Style> |
|||
|
|||
<Style Selector="DockPanel#FirstPanel.mobile, DockPanel#SecondPanel.mobile"> |
|||
<Setter Property="Grid.ColumnSpan" Value="3" /> |
|||
</Style> |
|||
<Style Selector="DockPanel#SecondPanel.mobile"> |
|||
<Setter Property="Grid.Row" Value="2" /> |
|||
</Style> |
|||
</Grid.Styles> |
|||
|
|||
<DockPanel x:Name="FirstPanel"> |
|||
<CheckBox x:Name="firstVisible" DockPanel.Dock="Top" |
|||
IsChecked="True" Content="Visible" /> |
|||
<local:EmbedSample IsVisible="{Binding #firstVisible.IsChecked}"/> |
|||
</DockPanel> |
|||
<GridSplitter Grid.Row="0" Grid.RowSpan="3" Grid.Column="1" Width="5" HorizontalAlignment="Stretch" /> |
|||
<GridSplitter Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Height="5" VerticalAlignment="Stretch" /> |
|||
<DockPanel x:Name="SecondPanel"> |
|||
<CheckBox x:Name="secondVisible" DockPanel.Dock="Top" |
|||
IsChecked="True" Content="Visible" /> |
|||
<local:EmbedSample IsSecond="True" IsVisible="{Binding #secondVisible.IsChecked}"/> |
|||
</DockPanel> |
|||
</Grid> |
|||
</DockPanel> |
|||
</UserControl> |
|||
@ -0,0 +1,86 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
using Avalonia.Platform; |
|||
using Avalonia.Interactivity; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Platform; |
|||
using Avalonia.Markup.Xaml; |
|||
using Avalonia; |
|||
|
|||
namespace ControlCatalog.Pages |
|||
{ |
|||
public class NativeEmbedPage : UserControl |
|||
{ |
|||
public NativeEmbedPage() |
|||
{ |
|||
this.InitializeComponent(); |
|||
} |
|||
|
|||
private void InitializeComponent() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
|
|||
public async void ShowPopupDelay(object sender, RoutedEventArgs args) |
|||
{ |
|||
await Task.Delay(3000); |
|||
ShowPopup(sender, args); |
|||
} |
|||
|
|||
public void ShowPopup(object sender, RoutedEventArgs args) |
|||
{ |
|||
new ContextMenu() |
|||
{ |
|||
Items = new List<MenuItem> |
|||
{ |
|||
new MenuItem() { Header = "Test" }, new MenuItem() { Header = "Test" } |
|||
} |
|||
}.Open((Control)sender); |
|||
} |
|||
|
|||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) |
|||
{ |
|||
base.OnPropertyChanged(change); |
|||
|
|||
if (change.Property == BoundsProperty) |
|||
{ |
|||
var isMobile = change.GetNewValue<Rect>().Width < 1200; |
|||
this.Find<DockPanel>("FirstPanel")!.Classes.Set("mobile", isMobile); |
|||
this.Find<DockPanel>("SecondPanel")!.Classes.Set("mobile", isMobile); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public class EmbedSample : NativeControlHost |
|||
{ |
|||
public static INativeDemoControl? Implementation { get; set; } |
|||
|
|||
static EmbedSample() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public bool IsSecond { get; set; } |
|||
|
|||
protected override IPlatformHandle CreateNativeControlCore(IPlatformHandle parent) |
|||
{ |
|||
return Implementation?.CreateControl(IsSecond, parent, () => base.CreateNativeControlCore(parent)) |
|||
?? base.CreateNativeControlCore(parent); |
|||
} |
|||
|
|||
protected override void DestroyNativeControlCore(IPlatformHandle control) |
|||
{ |
|||
base.DestroyNativeControlCore(control); |
|||
} |
|||
} |
|||
|
|||
public interface INativeDemoControl |
|||
{ |
|||
/// <param name="isSecond">Used to specify which control should be displayed as a demo</param>
|
|||
/// <param name="parent"></param>
|
|||
/// <param name="createDefault"></param>
|
|||
IPlatformHandle CreateControl(bool isSecond, IPlatformHandle parent, Func<IPlatformHandle> createDefault); |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue