- rewrote/enhanced mouse tracking

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24061 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexandre Deckner 2008-02-22 13:36:50 +00:00
parent 1abe02f02e
commit c226b06127
2 changed files with 118 additions and 89 deletions

View File

@ -139,6 +139,14 @@ ObjectView::ObjectView(BRect r, char *name, ulong resizingMode, ulong options)
fLastYXRatio(1),
fYxRatio(1)
{
fTrackingInfo.isTracking = false;
fTrackingInfo.pickedObject = NULL;
fTrackingInfo.buttons = 0;
fTrackingInfo.lastX = 0.0f;
fTrackingInfo.lastY = 0.0f;
fTrackingInfo.lastDx = 0.0f;
fTrackingInfo.lastDy = 0.0f;
fLastObjectDistance = fObjectDistance = depthOfView/8;
quittingSem = create_sem(1,"quitting sem");
drawEvent = create_sem(0,"draw event");
@ -392,102 +400,108 @@ ObjectView::ObjectAtPoint(BPoint p)
void
ObjectView::MouseDown(BPoint p)
ObjectView::MouseDown(BPoint point)
{
BPoint op = p, np = p;
BRect bounds = Bounds();
float lastDx = 0,lastDy = 0;
GLObject* o = NULL;
uint32 mods;
GLObject* object = NULL;
BMessage *m = Window()->CurrentMessage();
uint32 buttons = m->FindInt32("buttons");
o = ((GLObject*)fObjects.ItemAt(ObjectAtPoint(p)));
BMessage *msg = Window()->CurrentMessage();
uint32 buttons = msg->FindInt32("buttons");
object = ((GLObject*)fObjects.ItemAt(ObjectAtPoint(point)));
long locks = 0;
while (Window()->IsLocked()) {
locks++;
Window()->Unlock();
}
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
if (o) {
while (buttons) {
lastDx = np.x - op.x;
lastDy = np.y - op.y;
if (lastDx || lastDy) {
float xinc = (lastDx * 2 * displayScale / bounds.Width());
float yinc = (-lastDy * 2 * displayScale / bounds.Height());
float zinc = 0;
if (fPersp) {
zinc = yinc * (o->z / displayScale);
xinc *= -(o->z * 4 / zRatio);
yinc *= -(o->z * 4 / zRatio);
}
o->x += xinc;
mods = modifiers();
if (mods & B_SHIFT_KEY)
o->z += zinc;
else
o->y += yinc;
op = np;
fForceRedraw = true;
setEvent(drawEvent);
}
snooze(25000);
Window()->Lock();
GetMouse(&np, &buttons, true);
Window()->Unlock();
}
if (object != NULL){
if (buttons == B_PRIMARY_MOUSE_BUTTON || buttons == B_SECONDARY_MOUSE_BUTTON) {
fTrackingInfo.pickedObject = object;
fTrackingInfo.buttons = buttons;
fTrackingInfo.isTracking = true;
fTrackingInfo.lastX = point.x;
fTrackingInfo.lastY = point.y;
fTrackingInfo.lastDx = 0.0f;
fTrackingInfo.lastDy = 0.0f;
fTrackingInfo.pickedObject->spinX = 0.0f;
fTrackingInfo.pickedObject->spinY = 0.0f;
SetMouseEventMask(B_POINTER_EVENTS,
B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY);
} else {
ConvertToScreen(&point);
object->MenuInvoked(point);
}
} else if (buttons == B_PRIMARY_MOUSE_BUTTON) {
float llx = 0, lly = 0;
lastDx = lastDy = 0;
}
}
void
ObjectView::MouseUp(BPoint point)
{
if (fTrackingInfo.isTracking) {
if (o) {
o->spinX = 0;
o->spinY = 0;
while (buttons) {
llx = lastDx;
lly = lastDy;
lastDx = np.x - op.x;
lastDy = np.y - op.y;
//spin the teapot on release, TODO: use a marching sum and divide by time
if (fTrackingInfo.buttons == B_PRIMARY_MOUSE_BUTTON
&& fTrackingInfo.pickedObject != NULL
&& (fabs(fTrackingInfo.lastDx) > 1.0f
|| fabs(fTrackingInfo.lastDy) > 1.0f) ) {
fTrackingInfo.pickedObject->spinX = 0.5f * fTrackingInfo.lastDy;
fTrackingInfo.pickedObject->spinY = 0.5f * fTrackingInfo.lastDx;
setEvent(drawEvent);
}
//stop tracking
fTrackingInfo.isTracking = false;
fTrackingInfo.buttons = 0;
fTrackingInfo.pickedObject = NULL;
fTrackingInfo.lastX = 0.0f;
fTrackingInfo.lastY = 0.0f;
fTrackingInfo.lastDx = 0.0f;
fTrackingInfo.lastDy = 0.0f;
}
}
void
ObjectView::MouseMoved(BPoint point, uint32 transit, const BMessage *msg)
{
if (fTrackingInfo.isTracking && fTrackingInfo.pickedObject != NULL) {
float dx = point.x - fTrackingInfo.lastX;
float dy = point.y - fTrackingInfo.lastY;
fTrackingInfo.lastX = point.x;
fTrackingInfo.lastY = point.y;
if (lastDx || lastDy) {
o->rotY += lastDx;
o->rotX += lastDy;
op = np;
setEvent(drawEvent);
}
snooze(25000);
Window()->Lock();
GetMouse(&np, &buttons, true);
Window()->Unlock();
if (fTrackingInfo.buttons == B_PRIMARY_MOUSE_BUTTON) {
fTrackingInfo.pickedObject->spinX = 0;
fTrackingInfo.pickedObject->spinY = 0;
fTrackingInfo.pickedObject->rotY += dx;
fTrackingInfo.pickedObject->rotX += dy;
fTrackingInfo.lastDx = dx;
fTrackingInfo.lastDy = dy;
setEvent(drawEvent);
} else if (fTrackingInfo.buttons == B_SECONDARY_MOUSE_BUTTON) {
float xinc = (dx * 2 * displayScale / Bounds().Width());
float yinc = (-dy * 2 * displayScale / Bounds().Height());
float zinc = 0;
if (fPersp) {
zinc = yinc * (fTrackingInfo.pickedObject->z / displayScale);
xinc *= -(fTrackingInfo.pickedObject->z * 4 / zRatio);
yinc *= -(fTrackingInfo.pickedObject->z * 4 / zRatio);
}
o->spinY = lastDx + llx;
o->spinX = lastDy + lly;
}
} else {
if (o) {
BPoint point = p;
Window()->Lock();
ConvertToScreen(&point);
Window()->Unlock();
o->MenuInvoked(point);
}
}
while (locks--)
Window()->Lock();
setEvent(drawEvent);
fTrackingInfo.pickedObject->x += xinc;
if (modifiers() & B_SHIFT_KEY)
fTrackingInfo.pickedObject->z += zinc;
else
fTrackingInfo.pickedObject->y += yinc;
fForceRedraw = true;
setEvent(drawEvent);
}
}
}

View File

@ -33,6 +33,17 @@ enum lights {
#define HISTSIZE 10
class ResScroll;
class GLObject;
struct TrackingInfo {
float lastX;
float lastY;
float lastDx;
float lastDy;
bool isTracking;
GLObject *pickedObject;
uint32 buttons;
};
class ObjectView : public BGLView {
public:
@ -41,6 +52,9 @@ class ObjectView : public BGLView {
~ObjectView();
virtual void MouseDown(BPoint p);
virtual void MouseUp(BPoint p);
virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *msg);
virtual void MessageReceived(BMessage* msg);
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
@ -69,6 +83,7 @@ class ObjectView : public BGLView {
bool fLastFog, fFog, fForceRedraw;
float fLastYXRatio, fYxRatio, fFpsHistory[HISTSIZE];
float fObjectDistance,fLastObjectDistance;
TrackingInfo fTrackingInfo;
};
#endif // OBJECT_VIEW_H