Wacom Stylus SDKを利用したサインアプリの実装③
2013年10月31日
今回はパームリジェクションの実装と、サイドスイッチのイベントを取得し、パームリジェクションのオン/オフを切り替える方法を紹介します。
まずは、パームリジェクションの処理を紹介します。パームリジェクションとは、ペンで入力する際に手のひらがiPadの画面上に触れても無視する機能です。
この機能を実装するには、iOSのタッチイベントで取得できるtouchesを利用せず、[[WacomManager getManager] currentlyTrackedTouches]から取得できるTrackedTouchesオブジェクトを利用してタッチ処理を実装する必要があります。
1. タッチ情報の登録
touchesBeganにタッチ情報を登録する処理を記述します。
タッチ情報を登録することで、TrackedTouchesで登録したタッチ情報を扱えるようになります。
// タッチ開始 - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // タッチ情報の登録 [[[WacomManager getManager] currentlyTrackedTouches] addTouches:touches knownTouches:[event touchesForView:self.view] view:self.view]; }
2. 移動情報の設定
touchesMovedに移動したタッチ情報を設定する処理を記述します。
[[[WacomManager getManager] currentlyTrackedTouches] moveTouches:touches knownTouches:[event touchesForView:self.view] view:self.view]; でタッチ情報を更新し、[[[WacomManager getManager] currentlyTrackedTouches] getTouches];でペンでタッチした情報のみを取得することができます。
また、パームリジェクションは、タッチ情報を識別し、ペン以外の情報を除外しているので、タッチ情報が0個の場合も考慮してプログラムを組む必要があります。
// 移動イベント - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { // 移動したタッチ情報を設定 [[[WacomManager getManager] currentlyTrackedTouches] moveTouches:touches knownTouches:[event touchesForView:self.view] view:self.view]; NSArray *theTrackedTouches = [[[WacomManager getManager] currentlyTrackedTouches] getTouches]; if ([theTrackedTouches count] != 0) { if (self.bezierPath == nil) { // パスが初期化されていない場合は、初期化を行う CGPoint currentPoint = [[touches anyObject] locationInView:self.view]; // パスの作成 self.bezierPath = [UIBezierPath bezierPath]; self.bezierPath.lineCapStyle = kCGLineCapRound; [self.bezierPath moveToPoint:currentPoint]; // 現在位置 lastPoint = currentPoint; return; } // パームリジェクションを使うためにはtouchesは直接利用しない //CGPoint currentPoint = [[touches anyObject] locationInView:self.view]; CGPoint currentPoint = [[theTrackedTouches objectAtIndex:0] locationInView:self.view]; // 現在の筆圧で線の太さを決定する self.bezierPath.lineWidth = [self getLineWidth]; // 線の描画 [self.bezierPath addQuadCurveToPoint:currentPoint controlPoint:lastPoint]; [self drawLine:self.bezierPath]; // 描画した画像の保持 self.lastImage = self.drawView.image; // パスの作成 self.bezierPath = [UIBezierPath bezierPath]; self.bezierPath.lineCapStyle = kCGLineCapRound; [self.bezierPath moveToPoint:currentPoint]; // 最後に描画した位置の保存 lastPoint = currentPoint; } }
3. タッチ情報の削除
タッチが終了・キャンセルされた時点で、タッチ情報を削除する処理を追加します。
イベントの最後で実行している[[[WacomManager getManager] currentlyTrackedTouches] removeTouches:touches knownTouches:[event touchesForView:self.view] view:self.view]でTrackedTouchesからタッチ情報を削除しています。
それ以外は、touchesMovedと同じようにタッチ情報を取得し、線を描画しています。
// タッチ終了 - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [[[WacomManager getManager] currentlyTrackedTouches] moveTouches:touches knownTouches:[event touchesForView:self.view] view:self.view]; NSArray *theTrackedTouches = [[[WacomManager getManager] currentlyTrackedTouches] getTouches]; if ([theTrackedTouches count] != 0) { CGPoint currentPoint = [[theTrackedTouches objectAtIndex:0] locationInView:self.view]; // パームリジェクションを使うためにはtouchesは直接利用しない //CGPoint currentPoint = [[touches anyObject] locationInView:self.view]; [self drawEnd:currentPoint]; } // タッチ情報の削除 [[[WacomManager getManager] currentlyTrackedTouches] removeTouches:touches knownTouches:[event touchesForView:self.view] view:self.view]; } // タッチのキャンセル - (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [[[WacomManager getManager] currentlyTrackedTouches] moveTouches:touches knownTouches:[event touchesForView:self.view] view:self.view]; NSArray *theTrackedTouches = [[[WacomManager getManager] currentlyTrackedTouches] getTouches]; if ([theTrackedTouches count] != 0) { CGPoint currentPoint = [[theTrackedTouches objectAtIndex:0] locationInView:self.view]; // パームリジェクションを使うためにはtouchesは直接利用しない //CGPoint currentPoint = [[touches anyObject] locationInView:self.view]; [self drawEnd:currentPoint]; } // タッチ情報の削除 [[[WacomManager getManager] currentlyTrackedTouches] removeTouches:touches knownTouches:[event touchesForView:self.view] view:self.view]; }
以上で、パームリジェクションを動作させるための準備は整いましたが、
これだけではパームリジェクションは有効になりません。
今回は、アプリケーション起動時にパームリジェクションをオンにするために、
viewDidLoadに以下のコードを追加します。
// パームリジェクションを有効 [[WacomManager getManager] currentlyTrackedTouches].touchRejectionEnabled = YES;
また、忘れずにマルチタッチを有効化しておきます。
// マルチタッチの有効化 [self.view setMultipleTouchEnabled:YES];
アプリを起動し、指で線を書いてみると指では線を書けず、ペンでのみ線を書くことができるようになっています。
最後に、サイドスイッチでパームリジェクションのオン/オフを切り替える処理を追加します。
サイドスイッチのイベントは、筆圧と同じくstylusEventで取得することができ、
押した時と離した時の2種類のイベントを取得することができます。
また、getButtonでどのボタンが押されたかを識別することができます。
// スタイラスイベント - (void) stylusEvent:(WacomStylusEvent *)stylusEvent { if ([stylusEvent getType] == eStylusEventType_PressureChange) { // 筆圧の変更イベント currentPressure = [stylusEvent getPressure]; NSLog(@"Pressure : %f", currentPressure); } else if ([stylusEvent getType] == eStylusEventType_ButtonPressed) { // サイドスイッチが押された NSLog(@"SideSwitch Pressed : %d", [stylusEvent getButton]); } else if ([stylusEvent getType] == eStylusEventType_ButtonReleased) { // サイドスイッチが離された if ([stylusEvent getButton] == 1) { // 下のスイッチ [[WacomManager getManager] currentlyTrackedTouches].touchRejectionEnabled = YES; } else if ([stylusEvent getButton] == 1) { // 上のスイッチ [[WacomManager getManager] currentlyTrackedTouches].touchRejectionEnabled = NO; } NSLog(@"SideSwitch Released : %d", [stylusEvent getButton]); } }
アプリを実行し、下のスイッチを押すとパームリジェクションが有効、上のスイッチでパームリジェクションが無効になります。
次回は、ペンのIDの利用方法と注意点を紹介します。
今回実装したソースコードはこちらからダウンロードできます。
実際に、ダウンロードして試していただければと思います。
ソースコードには、Wacom Stylus SDKは付属しておりませんので、以下のページからWacom Stylus SDKを入手し、WacomDevice.frameworkを追加してください。