私はアップルのUIGestureRecognizerデザインが非常に素晴らしく、拡張可能であることがわかりました。
アイデアは、ジェスチャの認識(または相互作用)とトリガされるアクションを分離することです。
イベントに基づいて特定の相互作用またはジェスチャを認識できる、基本的または抽象的なGestureRecognizerクラスを実装する必要があります。MousePressEvent、MouseReleaseEvent MouseMoveEventまたはMouseWheelEventなどGestureRecongnizersは定期的に変更を報告するという目標を持っています。
たとえば、あなたの非常に基本的なクラスは以下のようになります:(申し訳ありません私の貧しい半C++擬似コード...最近、私はそれを使用していない多くのこと)
class Recognizer {
int state; // ex: 0:possible, 1:began, 2:changed, 3:ended/recognized 4:cancelled
protected:
void setTarget(void &theTarget); // or even better a touple, target/method. In this case target is assumed to have a method gestureHandle(Recognizer *r);
virtual void mouserPress() = 0;
virtual void mouserRelease() = 0;
virtual void mouserMove() = 0;
virtual void mouserWheel() = 0;
...
}
そして、あなたが検出したい場合メソッドが呼び出され、上記のイベントが起こっているとき、マウスでスワイプ
class SwipeRecognizer : Recognizer {
int direction; // ex: 0:left2right 1:bottom2top 2:...
private:
void mouserPress() {
state = 0; // possible. You don't know yet is the mouse is going to swipe, simple click, long press, etc.
// save some values so you can calculate the direction of the swipe later
target.gestureHandle(this);
};
void mouserMove() {
if (state == 0) {
state = 1; // it was possible now you know the swipe began!
direction = ... // calculate the swipe direction here
} else if (state == 1 || state == 2) {// state is began or changed
state = 2; // changed ... which means is still mouse dragging
// probably you want to make more checks here like you are still swiping in the same direction you started, maybe velocity thresholds, if any of your conditions are not met you should cancel the gesture recognizer by setting its state to 4
}
target.gestureHandler(this);
};
void mouserRelease() {
if (state == 2) { // is swipping
state = 3; // swipe ended
} else {
state = 4; // it was not swiping so simple cancel the tracking
}
target.gestureHandler(this);
};
void mouserWheel() {
// if this method is called then this is definitely not a swipe right?
state = 4; // cancelled
target.gestureHandler(this);
}
念、必要なときに、彼らはターゲットを呼び出す必要があります。
これは、ターゲットが私にどのように見えるかです:UIGestureRecognizerの
class Target {
...
void gestureHandler(Recognizer *r) {
if (r->state == 2) {
// Is swipping: move the opengl camera using some parameter your recognizer class brings
} else if (r->state == 3) {
// ended: stop moving the opengl camera
} else if (r->state == 4) {
// Cancelled, maybe restore camera to original position?
}
}
実装は非常にいいですし、同じビューに同じ認識機能と、いくつかの認識機能のために、いくつかのターゲット/メソッドを登録することができます。
を2つのジェスチャーを同時に検出することが可能であれば UIGestureRecognizersは、例えば、他のジェスチャー認識機能についての情報を取得するために使用されるデリゲートオブジェクトを持っている、または1つはすぐに他が検出されるように失敗しなければならない必要がある、などいくつかのジェスチャーレコグナイザは、他のものよりも多くのオーバーライドを必要としますが、これの大きなPROは、出力が同じであることです:現在の状態(およびその他の情報)を通知するハンドラメソッド。私はそれ
見てみる価値はあると思い
は、それが、返信に感謝を:)
あなたの詳細な答えはアンソニーありがとうございます。私はシグナル/スロット機構と組み合わせたファクトリメソッドを実装しようとします。さもなければ、私は実際のオブジェクトで私にいくつかのIDを与えるだけのOpenGLピッキングをどのように接続できるのか分かりません。 – mike