Skip to content

Commit

Permalink
very basics working, osx support for dragging windows with pointing g…
Browse files Browse the repository at this point in the history
…estures
  • Loading branch information
revmischa committed Mar 12, 2013
1 parent 3b70f10 commit d29be67
Show file tree
Hide file tree
Showing 11 changed files with 918 additions and 98 deletions.
393 changes: 379 additions & 14 deletions flinger.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions flinger/FlingerDriver.cpp
@@ -0,0 +1,9 @@
//
// FlingerDriver.cpp
// flinger
//
// Created by Mischa Spiegelmock on 3/11/13.
//
//

#include "FlingerDriver.h"
31 changes: 31 additions & 0 deletions flinger/FlingerDriver.h
@@ -0,0 +1,31 @@
//
// FlingerDriver.h
// flinger
//
// Created by Mischa Spiegelmock on 3/11/13.
//
//

#ifndef __flinger__FlingerDriver__
#define __flinger__FlingerDriver__

#include <iostream>
#include <Leap.h>

namespace flinger {

typedef void* flingerWinRef;

class Driver {
public:
virtual ~Driver() {};

virtual void releaseWinRef(flingerWinRef win) = 0;
virtual const flingerWinRef getWindowAt(double x, double y) = 0;
virtual const Leap::Vector getWindowPosition(const flingerWinRef win) = 0;
virtual void setWindowPosition(const flingerWinRef win, Leap::Vector &pos) = 0;
};

}

#endif /* defined(__flinger__FlingerDriver__) */
171 changes: 171 additions & 0 deletions flinger/FlingerListener.cpp
@@ -0,0 +1,171 @@
//
// FlingerListener.cpp
// flinger
//
// Created by Mischa Spiegelmock on 3/10/13.
//
//

#include "FlingerListener.h"

using namespace std;

namespace flinger {

Listener::Listener() {
currentWin = NULL;

#ifdef FLINGER_MAC
driver = new MacDriver();
#else
#error "Platform undefined"
#endif
}

Listener::~Listener() {
setCurrentWin(NULL);
delete(driver);
}

void Listener::setCurrentWin(flingerWinRef win) {
if (currentWin)
driver->releaseWinRef(currentWin);
currentWin = win;
}


void Listener::onInit(const Leap::Controller &controller) {
// controller.enableGesture(Leap::Gesture::TYPE_KEY_TAP);
// controller.enableGesture(Leap::Gesture::TYPE_CIRCLE);
controller.enableGesture(Leap::Gesture::TYPE_SCREEN_TAP);
controller.enableGesture(Leap::Gesture::TYPE_SWIPE);
}

// where is this pointable pointing (on the screen, not in space)?
static Leap::Vector pointableScreenPos(const Leap::Pointable &pointable, const Leap::ScreenList &screens) {
// need to have screen info
if (screens.empty())
return Leap::Vector();

// get point location
// get screen associated with gesture
Leap::Screen screen = screens.closestScreenHit(pointable);

Leap::Vector cursorLoc = screen.intersect(pointable, true);
if (! cursorLoc.isValid()) {
cout << "failed to find intersection\n";
return Leap::Vector();
}

double screenX = cursorLoc.x * screen.widthPixels();
double screenY = (1.0 - cursorLoc.y) * screen.heightPixels();
// cout << "Screen tapped at " << screenX << "," << screenY << endl;

return Leap::Vector(screenX, screenY, 0);
}


void Listener::onFrame(const Leap::Controller &controller) {
Leap::Frame latestFrame = controller.frame();
Leap::Frame refFrame = controller.frame(handGestureFrameInterval);

if (refFrame.isValid() && latestFrame.hands().count() == 1) {
Leap::Hand hand = latestFrame.hands()[0];
// double scaleFactor = hand.scaleFactor(refFrame);
// cout << "Scale: " << scaleFactor << endl;
}

Leap::ScreenList screens = controller.calibratedScreens();
Leap::GestureList gestures = latestFrame.gestures();

// process gestures
const int gestureCount = gestures.count();
for (int i = 0; i < gestureCount; i++) {
Leap::Gesture gesture = gestures[i];

switch (gesture.type()) {
case Leap::Gesture::TYPE_SCREEN_TAP: {
// select new current window, or deselect current window
if (currentWin) {
setCurrentWin(NULL);
cout << "Deselected window\n";
break;
}

// get tap location in screen coords
if (gesture.pointables().empty()) continue;
Leap::Vector screenLoc = pointableScreenPos(gesture.pointables()[0], screens);
if (! screenLoc.isValid())
continue;

// find window at tap location
flingerWinRef win = driver->getWindowAt(screenLoc.x, screenLoc.y);
if (win == NULL)
continue;

// set new current window
currentWin = win;
currentWinOrigPosition = driver->getWindowPosition(win);
} break;

case Leap::Gesture::TYPE_SWIPE: {
// deal only with one-finger swipes... for now
if (latestFrame.pointables().count() > 1)
continue;

// move window

if (! currentWin)
continue;

// get tap location in screen coords
if (gesture.pointables().empty()) continue;
Leap::Vector screenLoc = pointableScreenPos(gesture.pointables()[0], screens);
if (! screenLoc.isValid())
continue;

// get gesture dir/magnitude
Leap::SwipeGesture swipe = Leap::SwipeGesture(gesture);
Leap::Vector swipeMagnitude = swipe.position() - swipe.startPosition();
if (swipe.state() == Leap::Gesture::STATE_STOP) {
cout << "Swipe mag(x)=" << swipeMagnitude.x << ", mag(y)=" << swipeMagnitude.y << endl;
cout << "Move to: " << screenLoc.x << "," << screenLoc.y << endl;
driver->setWindowPosition(currentWin, screenLoc);
onWindowMovedBy(controller, currentWin, swipeMagnitude.x, swipeMagnitude.y);
}
} break;

default:
break;
}
}

// one-finger pointing
if (currentWin && latestFrame.pointables().count() == 1) {
Leap::Vector hitPoint = pointableScreenPos(latestFrame.pointables()[0], screens);
driver->setWindowPosition(currentWin, hitPoint);
return;
}
/*
// move currently selected window with two-finger pointing
if (currentWin && latestFrame.pointables().count() == 2) {
float pointDistance = latestFrame.pointables()[0].tipPosition().distanceTo(latestFrame.pointables()[1].tipPosition());
cout << "distance: " << pointDistance << endl;
if (pointDistance < 35) {
// finger tips close together
Leap::Vector hitPoint1 = pointableScreenPos(latestFrame.pointables()[0], screens);
Leap::Vector hitPoint2 = pointableScreenPos(latestFrame.pointables()[1], screens);
if (hitPoint1.isValid() && hitPoint2.isValid()) {
// average x/y
Leap::Vector centerPoint;
centerPoint.x = (hitPoint1.x + hitPoint2.x) / 2;
centerPoint.y = (hitPoint1.y + hitPoint2.y) / 2;
// move window
driver->setWindowPosition(currentWin, centerPoint);
}
}
}*/
}

}
45 changes: 45 additions & 0 deletions flinger/FlingerListener.h
@@ -0,0 +1,45 @@
//
// FlingerListener.h
// flinger
//
// Created by Mischa Spiegelmock on 3/10/13.
//
//

#ifndef __flinger__FlingerListener__
#define __flinger__FlingerListener__

//#include <iostream.h>
#include <Leap.h>
#include "FlingerDriver.h"

#ifdef FLINGER_MAC
#include "FlingerMac.h"
#endif


namespace flinger {

static const unsigned int handGestureFrameInterval = 2;

class Listener : public Leap::Listener {
public:
Listener();
~Listener();

virtual void setCurrentWin(flingerWinRef win);

virtual void onInit(const Leap::Controller &);
virtual void onFrame(const Leap::Controller&);

virtual void onWindowMovedBy(const Leap::Controller&, const flingerWinRef &win, double dx, double dy) = 0;

protected:
Driver *driver;
flingerWinRef currentWin = NULL;
Leap::Vector currentWinOrigPosition;
};

}

#endif /* defined(__flinger__FlingerListener__) */
19 changes: 19 additions & 0 deletions flinger/FlingerTestListener.cpp
@@ -0,0 +1,19 @@
//
// FlingerTestListener.cpp
// flinger
//
// Created by Mischa Spiegelmock on 3/11/13.
//
//

#include "FlingerTestListener.h"

using namespace std;

namespace flinger {

void TestListener::onWindowMovedBy(const Leap::Controller&, const flingerWinRef &win, double dx, double dy) {
cout << "Moved window by " << dx << ", " << dy << endl;
}

}
27 changes: 27 additions & 0 deletions flinger/FlingerTestListener.h
@@ -0,0 +1,27 @@
//
// FlingerTestListener.h
// flinger
//
// Created by Mischa Spiegelmock on 3/11/13.
//
//

#ifndef __flinger__FlingerTestListener__
#define __flinger__FlingerTestListener__

#include <iostream>
#include <Leap.h>
#include "FlingerListener.h"

namespace flinger {

class TestListener : public Listener {
public:
virtual void onWindowMovedBy(const Leap::Controller&, const flingerWinRef &win, double dx, double dy);
virtual const flingerWinRef getWindowAt(double x, double y) { return NULL; };
virtual const Leap::Vector getWindowCoords(const flingerWinRef win) { return Leap::Vector(); };
};

}

#endif /* defined(__flinger__FlingerTestListener__) */
79 changes: 0 additions & 79 deletions flinger/flinger.1

This file was deleted.

0 comments on commit d29be67

Please sign in to comment.