안녕하세요. 이동규(LiveDK)입니다.

그림1. Windows Phone Touch

 이번 포스팅에서는 Windows Phone의 터치에 관련해서 다루어 보려고 합니다. 첫번째 포스팅한 Windows Phone - #1 Hardware Chassis 에서 "멀티터치를 지원하는 정전용량-터치 디스플레이를 사용해야 하며 4개의 멀티터치를 지원해야하는..."라고 언급한바 있듯이 사용자 인터페이스의 기본 베이스인 터치는 굉장히 중요한 요소입니다. 사용되는 클래스 그리고 예제를 통해 알아 보겠습니다.(설명 기준은 Silverlight for Windows Phone 입니다.)

 멀티 터치 작업(개발)을 함에 있어서 Windows Phone에서는 두개의 서로다른 방법(인터페이스)을를 제공합니다. 이해하기 쉽게 카테고리를 나누자면 low-level / high-level 입니다.
low-level 인터페이스는 Touch.FrameReported 정적 이벤트에서 작업할 수 있지만 제스쳐는 지원 하지 않습니다.
high-level 인터페이스는 UIElement 클래스에 정의되 세가지 이벤트로 구성된 곳에서 처리할 수 있습니다. ManipulationStarted, ManipulationDelta, ManipulationCompleted 이 이벤트들은 Manipulation이라 불리고 여기서는 다중 손가락의 인식과 동작(제스쳐)을 작업할 수 있습니다.

Silverlight에서 low-level 터치에 가장 핵심적인 클래스는 TouchPoint 입니다. 이 클래스에는 4개의 읽기전용 속성을 가지고 있는데 아래에서 살펴 보겠습니다.

  • Action: TouchPoint 타입으로 action(up,down,move) 열거형 멤버를 가지고 있습니다.
  • Position: Point 타입으로 왼쪽-상단을 기준으로 특정 element의 위치를 나타냅니다.
  • Size: Size 타입으로 터치가된 구역을 나타내며 손가락 압력등의 정보로 사용될 수 있습니다.
  • TouchDevice: TouchDevice 타입으로 이 속성은 다시 두가지 읽기전용 속성을 가지고 있습니다.
    • ID: int 타입으로 손가락을 구별하거나 Down에서 Up에 이르는 일련의 이벤트에서 특정한 id를 값을 가지고 연결됩니다.
    • DirectlyOver: UIElement 타입으로 터치된 손가락 바로아래 가장 위에 있는 element 를 가져옵니다.

이 속성들 중에서 TouchDevice 의 DirectlyOver 프로퍼티는 어떤 element가 터치되어있는지 알 수 있기때문에 굉장히 유용하게 사용될 수 있습니다.

위에서 언급했듯이 low-level 터치 인터페이스를 이용하려면 아래 코드와 같이 Touch.FrameReported 이벤트를 만들어야 합니다.

Touch.FrameReported += Touch_FrameReported;
void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{    
}

Code1. FrameReported 이벤트

 

이 이벤트 핸들러는 어플리케이션에서 발생하는 모든 터치를 가져옵니다. 이 곳에서 살펴봐야 할 사항은 바로 TouchFrameEventArgs입니다. 이 클래스에는 3가지 중요한 매서드를 가지고 있습니다.

  • GetTouchPoints(refElement): refElement를 기준으로 Position들을 얻어옵니다. 만약 refElement에 null을 넣어주면 Application 왼쪽-상단을 기준으로 좌표들을 가져옵니다. 반환형은 TouchPointCollection
  • GetPrimaryTouchPoint(refElement): refElement를 기준으로 가장 주요한 Position을 가져 옵니다. 반환형은 TouchPoint입니다.
  • SuspendMousePromotionUntilTouchUp(): 터치포인트에서 Up 동작이 있기 전까지 마우스 이벤트를 비활성화 시킵니다.

 이제부터 실제로 간단한 코드를 작성해보면서 Touch에 대해서 정리해 보겠습니다. 디자인요소는 기본요소에 TextBlock을 하나 추가하여 위치정보를 받아 보겠습니다.. 

void Touch_FrameReported(object sender, TouchFrameEventArgs e)

{   

     TouchPoint touch = e.GetPrimaryTouchPoint(null); //하나의 TouchPoint

 

     TouchAction action = touch.Action; //터치상태 Up,Move,Down

     Size size = touch.Size; //에뮬레이터이므로 크기는 마우스포인트(1.1)

     TouchDevice device = touch.TouchDevice;

 

     int id = device.Id; //터치정보 ID

     UIElement element = device.DirectlyOver; //터치된 바로아래 Element

                       

     if (touch != null && touch.Action == TouchAction.Down)

     {

         tbPoint.Text = "Point: " + touch.Position;

     }
}

Code2. Touch 테스트 코드-비하인드

Code2 를 살펴보면 GetPrimaryTouchPoint(null) 메서드를 통해 Application의 왼쪽-상단을 0,0 기준으로 TouchPoint를 얻어오며 위에서 설명하였던 TouchAction, Size, TouchDevice, ID, DirectlyOver 속성의 값들을 확인하고 그 아래 TouchAction 상태를 비교하여 터치상태에서 Down 경우만 처리하였습니다. 이후 TouchPoint의 Position 속성을 TextBlock에 뿌려주는 내용입니다.

특히 DirectlyOver를 활용해보면 어떤 Element를 선택했는지 쉽게 알 수 있습니다. 예제에서 새로 추가한 TextBlock을 클릭하여 디버깅 해보면 DirectlyOver 를 통해 어떤 TextBlock 선택된것을 볼 수 있습니다.

이어서 high-level 터치 인터페이스에 대해서 알아 보겠습니다.

high-level 터치 인터페이스는 ManipulationStarted, ManipulationDelta, ManipulationCompleted 이벤트를 포함합니다. 이러한 이벤트 들을 통해 low-level과 다르게 멀티터치 작업을 처리할 수 있으며 속도 정보를 축적하여 관성에대한 활용을 가능하게 합니다.

low-level의 핵심적인 이벤트인 Touch.FrameReported 를 통해 전체 어플리케이션에서 터치 정보를 얻어 냈다면 high-level 에서는 Manipulation 이벤트들이 각각의 element로 부터 정보를 얻을 수 있습니다. 이번 포스팅에서는 ManipulationStarted를 위주로 설명하겠습니다. 아래 코드3는 각각의 element에 Manipulation 이벤트를 어떻게 주는지 볼 수 있습니다. 또한 전역으로 이벤트를 사용할 수 있는 override 코드를 추가하였습니다.

public MainPage()

{

    InitializeComponent();

    //tbTest 라는 TextBlock ManipulationStarted 이벤트 연결

    tbTest.ManipulationStarted += tbTest_ManipulationStarted;

}


//Case 1 

void tbTest_ManipulationStarted(object sender, ManipulationStartedEventArgs e)

{

}

//Case 2

protected override void OnManipulationStarted(ManipulationStartedEventArgs e)

{   

    if (tbTest == e.OriginalSource) //TextBlock 에서 발생했는가?

    {

    }

    Point point = e.ManipulationOrigin;

    base.OnManipulationStarted(e);

}

코드3. ManipulationStarted Event

코드3에서 (Case 2 를 기준으로) 매개변수로 넘어오는 (ManipulationStartedEventArgs e) 에대해 알아보겠습니다. 이 클래스에는 주로 사용하는 두개의 속성이 있는데 OriginalSourceManipulationOrigin 입니다. 우선 OriginalSource는 어디에서 이벤트 발생했는지에 대한 정보가 들어 있습니다. 코드3 에서처럼 TextBlock 에서 이 이벤트가 발생했는지를 구별 할 수 가 있습니다. ManipulationOrigin은 manipulation 이 발생한 곳의 포인트 위치 입니다. TextBlock을 선택하여 발생한경우 TextBlock 내에 좌측-상단을 기준으로 좌표점 입니다.

참고자료
Programming Windows Phone 7 by Charles Petzold - http://www.charlespetzold.com/phone/
MSDN - TouchPoint Members - http://bit.ly/fezrUf
MSDN - ManipulationStartedEventArgs - http://bit.ly/gfgjNu



Posted by Dongkyu
,