Gesten
Die Gestenschicht: eine Karte lässt sich mit einem Finger verschieben (mit Trägheit) und mit zwei Fingern skalieren und drehen; Tippen, Doppeltippen und Wischen werden gemeldet. Mit „Maus erlaubt“ verschiebt auch die Maus.


KXAML
GestenSeite.kxaml
<StackPanel xmlns="https://ui.kuonen.org/kxaml"
xmlns:x="https://ui.kuonen.org/kxaml/x"
x:Class="Kuonen.UI.Galerie.Seiten.GestenVorfuehrung"
Spacing="12">
<!-- Das Innere (Einträge, Kopplungen, Ereignisse) baut GestenSeite.Fuelle, dieselbe Methode wie die C#-Fassung. -->
<CheckBox x:Name="Maus" Content="Maus erlaubt" />
<Canvas x:Name="Flaeche" Width="360" Height="220" />
<TextBlock x:Name="Meldung" Text="Noch keine Geste." />
</StackPanel>GestenSeite.kxaml.cs
using Kuonen.UI;
namespace Kuonen.UI.Galerie.Seiten;
public sealed partial class GestenSeite
{
protected override Func<UIElement>? KxamlFabrik => () => new GestenVorfuehrung();
}
/// <summary>KXAML-Fassung der Seite Gesten: das Gerüst steht in GestenSeite.kxaml, das Innere füllt GestenSeite.Fuelle.</summary>
public sealed partial class GestenVorfuehrung
{
public GestenVorfuehrung()
{
InitializeComponent();
GestenSeite.Fuelle(Maus, Flaeche, Meldung);
}
}C#
GestenSeite.cs
using Kuonen.UI;
using Kuonen.UI.Controls;
using Kuonen.UI.Eingabe;
using Kuonen.UI.Layout;
using Kuonen.UI.Media;
namespace Kuonen.UI.Galerie.Seiten;
/// <summary>Galerie-Seite: Gesten (Plan 6f).</summary>
public sealed partial class GestenSeite : GalerieSeite
{
public override string Titel => "Gesten";
public override string Beschreibung =>
"Die Gestenschicht: eine Karte lässt sich mit einem Finger verschieben (mit Trägheit) und mit zwei Fingern skalieren und drehen; Tippen, Doppeltippen und Wischen werden gemeldet. Mit „Maus erlaubt“ verschiebt auch die Maus.";
public override string Stichworte => "Gesten Manipulation Kneifen Pinch Drehen Rotate Trägheit Inertia Tippen Tapped DoubleTapped Wischen Swipe";
public override string Datei => nameof(GestenSeite);
public override UIElement Baue()
{
var seite = new StackPanel { Spacing = 12 };
var maus = new CheckBox { Content = "Maus erlaubt" };
var flaeche = new Canvas { Width = 360, Height = 220 };
var meldung = new TextBlock { Text = "Noch keine Geste." };
Fuelle(maus, flaeche, meldung);
seite.Children.Add(maus);
seite.Children.Add(flaeche);
seite.Children.Add(meldung);
return seite;
}
/// <summary>Die Karte und ihre Gesten (auch von der KXAML-Fassung benutzt).</summary>
public static void Fuelle(CheckBox maus, Canvas flaeche, TextBlock meldung)
{
flaeche.Background = new SolidColorBrush(Color.FromRgb(0xF0, 0xF0, 0xF0));
flaeche.ClipToBounds = true;
var karte = new Border
{
Width = 120, Height = 80, Background = new SolidColorBrush(Color.FromRgb(0x90, 0xCA, 0xF9)), ManipulationMode = ManipulationModes.All,
Child = new TextBlock { Text = "Karte", Margin = new Thickness(12) },
};
Canvas.SetLeft(karte, 120);
Canvas.SetTop(karte, 70);
flaeche.Children.Add(karte);
var lage = Matrix.Identity;
karte.ManipulationDelta += (_, e) =>
{
// Um den Schwerpunkt der Finger skalieren und drehen, dann verschieben (in Koordinaten der Fläche).
var p = e.PositionIn(flaeche);
var d = e.Delta;
lage *= Matrix.CreateTranslation(-p.X, -p.Y) * Matrix.CreateScale(d.Scale, d.Scale) * Matrix.CreateRotation(d.Rotation * Math.PI / 180)
* Matrix.CreateTranslation(p.X + d.Translation.X, p.Y + d.Translation.Y);
karte.RenderTransform = Matrix.CreateTranslation(-120, -70) * lage * Matrix.CreateTranslation(120, 70) is var m && double.IsFinite(m.M11) ? m : Matrix.Identity;
};
karte.Tapped += (_, _) => meldung.Text = "Getippt.";
karte.DoubleTapped += (_, _) =>
{
lage = Matrix.Identity;
karte.RenderTransform = Matrix.Identity;
meldung.Text = "Doppelt getippt: zurückgesetzt.";
};
flaeche.Gewischt += (_, e) => meldung.Text = $"Gewischt nach {e.Richtung}.";
maus.Checked += (_, _) => karte.ManipulationMode = ManipulationModes.All | ManipulationModes.Maus;
maus.Unchecked += (_, _) => karte.ManipulationMode = ManipulationModes.All;
}
}