- 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
+103 -89
View File
@@ -139,6 +139,14 @@ ObjectView::ObjectView(BRect r, char *name, ulong resizingMode, ulong options)
fLastYXRatio(1), fLastYXRatio(1),
fYxRatio(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; fLastObjectDistance = fObjectDistance = depthOfView/8;
quittingSem = create_sem(1,"quitting sem"); quittingSem = create_sem(1,"quitting sem");
drawEvent = create_sem(0,"draw event"); drawEvent = create_sem(0,"draw event");
@@ -392,102 +400,108 @@ ObjectView::ObjectAtPoint(BPoint p)
void void
ObjectView::MouseDown(BPoint p) ObjectView::MouseDown(BPoint point)
{ {
BPoint op = p, np = p; GLObject* object = NULL;
BRect bounds = Bounds();
float lastDx = 0,lastDy = 0;
GLObject* o = NULL;
uint32 mods;
BMessage *m = Window()->CurrentMessage(); BMessage *msg = Window()->CurrentMessage();
uint32 buttons = m->FindInt32("buttons"); uint32 buttons = msg->FindInt32("buttons");
o = ((GLObject*)fObjects.ItemAt(ObjectAtPoint(p))); object = ((GLObject*)fObjects.ItemAt(ObjectAtPoint(point)));
long locks = 0; if (object != NULL){
if (buttons == B_PRIMARY_MOUSE_BUTTON || buttons == B_SECONDARY_MOUSE_BUTTON) {
while (Window()->IsLocked()) { fTrackingInfo.pickedObject = object;
locks++; fTrackingInfo.buttons = buttons;
Window()->Unlock(); fTrackingInfo.isTracking = true;
} fTrackingInfo.lastX = point.x;
fTrackingInfo.lastY = point.y;
if (buttons == B_SECONDARY_MOUSE_BUTTON) { fTrackingInfo.lastDx = 0.0f;
if (o) { fTrackingInfo.lastDy = 0.0f;
while (buttons) { fTrackingInfo.pickedObject->spinX = 0.0f;
lastDx = np.x - op.x; fTrackingInfo.pickedObject->spinY = 0.0f;
lastDy = np.y - op.y;
SetMouseEventMask(B_POINTER_EVENTS,
if (lastDx || lastDy) { B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY);
float xinc = (lastDx * 2 * displayScale / bounds.Width()); } else {
float yinc = (-lastDy * 2 * displayScale / bounds.Height()); ConvertToScreen(&point);
float zinc = 0; object->MenuInvoked(point);
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();
}
} }
} 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) { //spin the teapot on release, TODO: use a marching sum and divide by time
o->spinX = 0; if (fTrackingInfo.buttons == B_PRIMARY_MOUSE_BUTTON
o->spinY = 0; && fTrackingInfo.pickedObject != NULL
while (buttons) { && (fabs(fTrackingInfo.lastDx) > 1.0f
llx = lastDx; || fabs(fTrackingInfo.lastDy) > 1.0f) ) {
lly = lastDy;
lastDx = np.x - op.x; fTrackingInfo.pickedObject->spinX = 0.5f * fTrackingInfo.lastDy;
lastDy = np.y - op.y; 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) { if (fTrackingInfo.buttons == B_PRIMARY_MOUSE_BUTTON) {
o->rotY += lastDx;
o->rotX += lastDy; fTrackingInfo.pickedObject->spinX = 0;
op = np; fTrackingInfo.pickedObject->spinY = 0;
setEvent(drawEvent); fTrackingInfo.pickedObject->rotY += dx;
} fTrackingInfo.pickedObject->rotX += dy;
fTrackingInfo.lastDx = dx;
snooze(25000); fTrackingInfo.lastDy = dy;
Window()->Lock(); setEvent(drawEvent);
GetMouse(&np, &buttons, true);
Window()->Unlock(); } 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; fTrackingInfo.pickedObject->x += xinc;
} if (modifiers() & B_SHIFT_KEY)
} else { fTrackingInfo.pickedObject->z += zinc;
if (o) { else
BPoint point = p; fTrackingInfo.pickedObject->y += yinc;
Window()->Lock();
ConvertToScreen(&point); fForceRedraw = true;
Window()->Unlock(); setEvent(drawEvent);
o->MenuInvoked(point); }
} }
}
while (locks--)
Window()->Lock();
setEvent(drawEvent);
} }
+15
View File
@@ -33,6 +33,17 @@ enum lights {
#define HISTSIZE 10 #define HISTSIZE 10
class ResScroll; class ResScroll;
class GLObject;
struct TrackingInfo {
float lastX;
float lastY;
float lastDx;
float lastDy;
bool isTracking;
GLObject *pickedObject;
uint32 buttons;
};
class ObjectView : public BGLView { class ObjectView : public BGLView {
public: public:
@@ -41,6 +52,9 @@ class ObjectView : public BGLView {
~ObjectView(); ~ObjectView();
virtual void MouseDown(BPoint p); 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 MessageReceived(BMessage* msg);
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
@@ -69,6 +83,7 @@ class ObjectView : public BGLView {
bool fLastFog, fFog, fForceRedraw; bool fLastFog, fFog, fForceRedraw;
float fLastYXRatio, fYxRatio, fFpsHistory[HISTSIZE]; float fLastYXRatio, fYxRatio, fFpsHistory[HISTSIZE];
float fObjectDistance,fLastObjectDistance; float fObjectDistance,fLastObjectDistance;
TrackingInfo fTrackingInfo;
}; };
#endif // OBJECT_VIEW_H #endif // OBJECT_VIEW_H