Noesis Gui

教程17:触摸和操纵

2020-03-14  本文已影响0人  YottaYuan

触摸和操纵

教程数据

NoesisGUI使用户界面可以同时接收多个触摸。甲触摸是一种由触摸屏上的手指把生成的用户输入的。您可以在NoesisGUI中以以下三个不同级别来管理触摸事件,以下各节对此进行了解释:本机控件触摸事件操纵事件

本机控件

ScrollViewer定义了PanningMode附加属性,该属性使您可以指定水平,垂直,两者或两者都不启用触摸平移。该PanningDeceleration属性指定滚动的速度减慢,当用户拿起从触摸屏的手指。所述PanningRatio附加属性指定的滚动偏移至平移操纵偏移的比率。

PanningMode可以直接ScrollViewer上设置,也可以用作附加属性。当控制包含的ScrollViewer在其ControlTemplate中PanningMode被用作附加属性来指定的行为的ScrollViewerControlTemplate中。当您在ControlTemplate之外使用ScrollViewer时,将在ScrollViewer上直接设置PanningMode

以下示例创建一个ScrollViewer并向其中添加几个按钮。该示例将PanningMode设置为Both,以便用户可以使用手指水平和垂直滚动ScrollViewer

<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ScrollViewer HorizontalScrollBarVisibility="Auto" Height="250" Width="125" PanningMode="Both">
      <StackPanel>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
        <Button Width="150" Height="80">Push me if you dare</Button>
      </StackPanel>
    </ScrollViewer>

</Grid>

下一个示例创建一个TextBox并将PanningMode用作附加属性。它将PanningMode设置为VerticalOnly。这样,当用户在垂直移动手指之前水平移动手指时,文本将突出显示。

<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <TextBox Height="300" Width="300" Name="textBox1" TextWrapping="Wrap" IsReadOnly="True"
    ScrollViewer.PanningMode="VerticalOnly" ScrollViewer.VerticalScrollBarVisibility="Auto"
    ScrollViewer.HorizontalScrollBarVisibility="Auto">

      Hello world 1 Hello world 2 Hello world 3 Hello world 4 Hello world 5
      Hello world 6 Hello world 7 Hello world 8 Hello world 9 Hello world 10
      Hello world 11 Hello world 12 Hello world 13 Hello world 14 Hello world 15
      Hello world 16 Hello world 17 Hello world 18 Hello world 19 Hello world 20
      Hello world 21 Hello world 22 Hello world 23 Hello world 24 Hello world 25
      Hello world 26 Hello world 27 Hello world 28 Hello world 29 Hello world 30
      Hello world 31 Hello world 32 Hello world 33 Hello world 34 Hello world 35
      Hello world 36 Hello world 37 Hello world 38 Hello world 39 Hello world 40
      Hello world 41 Hello world 42 Hello world 43 Hello world 44 Hello world 45
      Hello world 46 Hello world 47 Hello world 48 Hello world 49 Hello world 50
      Hello world 51 Hello world 52 Hello world 53 Hello world 54 Hello world 55
      Hello world 56 Hello world 57 Hello world 58 Hello world 59 Hello world 60
      Hello world 61 Hello world 62 Hello world 63 Hello world 64 Hello world 65
      Hello world 66 Hello world 67 Hello world 68 Hello world 69 Hello world 70
      Hello world 71 Hello world 72 Hello world 73 Hello world 74 Hello world 75
      Hello world 76 Hello world 77 Hello world 78 Hello world 79 Hello world 80
      Hello world 81 Hello world 82 Hello world 83 Hello world 84 Hello world 85
      Hello world 86 Hello world 87 Hello world 88 Hello world 89 Hello world 90
      Hello world 91 Hello world 92 Hello world 93 Hello world 94 Hello world 95
      Hello world 96 Hello world 97 Hello world 98 Hello world 99 Hello world 100
      Hello world 101 Hello world 102 Hello world 103 Hello world 104 Hello world 105
      Hello world 106 Hello world 107 Hello world 108 Hello world 109 Hello world 110
      Hello world 111 Hello world 112 Hello world 113 Hello world 114 Hello world 115
      Hello world 116 Hello world 117 Hello world 118 Hello world 119 Hello world 120
      Hello world 121 Hello world 122 Hello world 123 Hello world 124 Hello world 125
      Hello world 126 Hello world 127 Hello world 128 Hello world 129 Hello world 130
      Hello world 131 Hello world 132 Hello world 133 Hello world 134 Hello world 135
      Hello world 136 Hello world 137 Hello world 138 Hello world 139 Hello world 140
      Hello world 141 Hello world 142 Hello world 143 Hello world 144 Hello world 145
      Hello world 146 Hello world 147 Hello world 148 Hello world 149 Hello world 150
      Hello world 151 Hello world 152 Hello world 153 Hello world 154 Hello world 155
      Hello world 156 Hello world 157 Hello world 158 Hello world 159 Hello world 160
      Hello world 161 Hello world 162 Hello world 163 Hello world 164 Hello world 165
      Hello world 166 Hello world 167 Hello world 168 Hello world 169 Hello world 170
      Hello world 171 Hello world 172 Hello world 173 Hello world 174 Hello world 175
      Hello world 176 Hello world 177 Hello world 178 Hello world 179 Hello world 180
      Hello world 181 Hello world 182 Hello world 183 Hello world 184 Hello world 185
      Hello world 186 Hello world 187 Hello world 188 Hello world 189 Hello world 190
      Hello world 191 Hello world 192 Hello world 193 Hello world 194 Hello world 195
      Hello world 196 Hello world 197 Hello world 198 Hello world 199 Hello world 200
  </TextBox>

</Grid>

触摸事件

UIElement定义了您可以订阅的以下事件,以便您的应用程序可以响应触摸:

请注意,每次触摸的坐标均在屏幕空间中给出。必须使用Visual :: PointFromScreen方法将它们转换为本地坐标。

与键盘和鼠标事件一样,触摸事件是路由事件。名称以Preview开头的事件是隧道事件,而以Touch开头的事件是冒泡事件。顺序如下:

当使用两个以上的手指时,每个手指都会发生事件。

注意

在NoeisGUI中,如果未处理触摸事件,则会将其提升为鼠标事件。

操作事件

对于应用程序使用户能够操纵对象的情况,UIElement类定义操纵事件。与仅报告触摸位置的触摸事件不同,操纵事件报告如何解释输入。共有三种类型的操纵:平移扩展旋转。下表描述了如何调用三种类型的操作:

UIElement定义了以下操作路由事件:

默认情况下,不会生成这些操作事件。要在UIElement上接收操纵事件,请在XAML中或通过代码将依赖项属性IsManipulationEnabled设置为true。

注意

如果使用了TouchDown事件(操作的成员设置为True),则操作逻辑不会生成操作事件。

操作开始

ManipulationStarting当用户将手指在对象上发生的事件。除其他事项外,此事件使您可以设置ManipulationContainer属性。在随后的事件中,操纵的位置将相对于此ManipulationContainer。您还可以设置Mode属性,以指示可能的操作类型(平移,旋转或缩放)。

操作开始

在ManipulationStarted发生旁事件ManipulationStarting。此事件报告操纵的来源。

操作三角

当用户的手指在触摸屏上移动时,会发生多次ManipulationDelta事件。ManipulationDeltaEventArgs类的DeltaManipulation属性报告该操作是解释为运动,扩展还是平移。在这里,您可以执行大部分操作对象的工作。请注意,ManipulationDelta发生在ManipulationInertiaStarting事件之前和之后。ManipulationDeltaEventArgs.isInertial属性报告在惯性期间是否发生ManipulationDelta事件,因此您可以检查该属性并根据其值执行不同的操作。

操纵惯性开始

在ManipulationInertiaStarting当用户的手指失去与物体发生接触的事件。此事件使您可以指定惯性期间操纵的减速度。这样,如果您选择,您的对象可以模拟不同的物理空间或属性。例如,假设您的应用程序有两个对象,它们代表物理世界中的项目,而一个对象比另一个重。您可以使较重的对象比较轻的对象减速更快。

操作完成

在ManipulationCompleted发生事件时的操作和任何惯性结束。也就是说,在所有ManipulationDelta事件发生之后,此事件表示操作已完成。

注意

您可以通过在任何操作事件中在事件参数上设置cancel属性来取消操作。设置为true时,不再引发操纵事件,并且针对已取消的操纵发生鼠标事件。

样品

C ++

<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="MyTouch">

  <Canvas x:Name="root">
    <Rectangle Fill="Red" Width="200" Height="200" RenderTransform="1 0 0 1 50 50"
               IsManipulationEnabled="True"/>
    <Rectangle Fill="Blue" Width="200" Height="200" RenderTransform="1 0 0 1 200 300"
               IsManipulationEnabled="True"/>
  </Canvas>

</Grid>
class MyTouch: public Grid
{
public:
    void OnManipulationStarting(const ManipulationStartingEventArgs& e)
    {
        e.mode = ManipulationModes_All;
        e.manipulationContainer = (Visual*)FindName("root");
        e.handled = true;
    }

    void OnManipulationInertiaStarting(const ManipulationInertiaStartingEventArgs& e)
    {
        e.translationBehavior.desiredDeceleration = 100.0f / (1000.0f * 1000.0f);
        e.rotationBehavior.desiredDeceleration = 360.0f / (1000.0f * 1000.0f);
        e.expansionBehavior.desiredDeceleration = 300.0f / (1000.0f * 1000.0f);
        e.handled = true;
    }

    void OnManipulationDelta(const ManipulationDeltaEventArgs& e)
    {
        UIElement* rectangle = (UIElement*)e.source;
        MatrixTransform* tr = (MatrixTransform*)rectangle->GetRenderTransform();
        Transform2f mtx = tr->GetMatrix();

        mtx.RotateAt(e.deltaManipulation.rotation * DegToRad_f, e.manipulationOrigin.x,
            e.manipulationOrigin.y);
        mtx.ScaleAt(e.deltaManipulation.scale, e.deltaManipulation.scale,
            e.manipulationOrigin.x, e.manipulationOrigin.y);
        mtx.Translate(e.deltaManipulation.translation.x, e.deltaManipulation.translation.y);

        tr->SetMatrix(mtx);
        e.handled = true;
    }

private:
     NS_IMPLEMENT_INLINE_REFLECTION(MyTouch, Grid)
     {
        NsMeta<TypeId>("MyTouch");
     }
};

Unity

<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Canvas x:Name="root">
    <Rectangle Fill="Red" Width="200" Height="200" RenderTransform="1 0 0 1 50 50"
               IsManipulationEnabled="True"/>
    <Rectangle Fill="Blue" Width="200" Height="200" RenderTransform="1 0 0 1 200 300"
              IsManipulationEnabled="True"/>
  </Canvas>

</Grid>
public class Touch: MonoBehaviour
{
    Grid _root;

    void Start()
    {
        _root = (Grid)GetComponent<NoesisView>().Content;
        _root.ManipulationStarting += this.ManipulationStarting;
        _root.ManipulationInertiaStarting += this.ManipulationInertiaStarting;
        _root.ManipulationDelta += this.ManipulationDelta;
    }

    void ManipulationStarting(object sender, ManipulationStartingEventArgs e)
    {
        e.Mode = Noesis.ManipulationModes.All;
        e.ManipulationContainer = (UIElement)_root.FindName("root");
        e.Handled = true;
    }

    void ManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)
    {
        e.TranslationBehavior.DesiredDeceleration = 100.0f / (1000.0f * 1000.0f);
        e.RotationBehavior.DesiredDeceleration = 360.0f / (1000.0f * 1000.0f);
        e.ExpansionBehavior.DesiredDeceleration = 300.0f / (1000.0f * 1000.0f);
        e.Handled = true;
    }

    void ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
        var rectangle = (Rectangle)e.Source;
        var transform = (MatrixTransform)rectangle.RenderTransform;
        var matrix = transform.Matrix;

        float rotation = e.DeltaManipulation.Rotation * Mathf.Deg2Rad;
        float originX = e.ManipulationOrigin.X;
        float originY = e.ManipulationOrigin.Y;
        float scale = e.DeltaManipulation.Scale;
        float translationX = e.DeltaManipulation.Translation.X;
        float translationY = e.DeltaManipulation.Translation.Y;

        matrix.RotateAt(rotation, originX, originY);
        matrix.ScaleAt(scale, scale, originX, originY);
        matrix.Translate(translationX, translationY);

        transform.Matrix = matrix;
        e.Handled = true;
    }
}
上一篇下一篇

猜你喜欢

热点阅读