void VideoSlider::OnMouse(wxMouseEvent &event) { int x = event.GetX(); if (event.ButtonIsDown(wxMOUSE_BTN_LEFT)) { // If the slider didn't already have focus, don't seek if the user // clicked very close to the current location as they were probably // just trying to focus the slider if (wxWindow::FindFocus() != this && abs(x - GetXAtValue(val)) < 4) { SetFocus(); return; } // Shift click to snap to keyframe if (event.m_shiftDown) { int clickedFrame = GetValueAtX(x); std::vector<int>::const_iterator pos = lower_bound(keyframes.begin(), keyframes.end(), clickedFrame); if (pos == keyframes.end()) --pos; else if (pos + 1 != keyframes.end() && clickedFrame - *pos > (*pos + 1) - clickedFrame) ++pos; if (*pos == val) return; SetValue(*pos); } // Normal click else { int go = GetValueAtX(x); if (go == val) return; SetValue(go); } if (c->videoController->IsPlaying()) { c->videoController->Stop(); c->videoController->JumpToFrame(val); c->videoController->Play(); } else c->videoController->JumpToFrame(val); SetFocus(); return; } if (event.ButtonDown(wxMOUSE_BTN_RIGHT) || event.ButtonDown(wxMOUSE_BTN_MIDDLE)) { SetFocus(); } else if (!c->videoController->IsPlaying()) event.Skip(); }
bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, double h, double pps, bool dB, float zoomMin, float zoomMax) { bool upper; int ctr = (int)(r.height * zoomMax / (zoomMax - zoomMin)); upper = (event.m_y - r.y < ctr); int clip_y = event.m_y - r.y; if(clip_y < 0) clip_y = 0; if(clip_y > r.height) clip_y = r.height; mIsDeleting = false; double tleft = h - mOffset; double tright = tleft + (r.width / pps); int bestNum = -1; int bestDist = 10; // Must be within 10 pixel radius. double dBr = gPrefs->Read("/GUI/EnvdBRange", ENV_DB_RANGE); mContourOffset = false; // wxLogDebug("Y:%i Height:%i Offset:%i", y, height, mContourOffset ); int len = mEnv.Count(); for (int i = 0; i < len; i++) { if (mEnv[i]->t >= tleft && mEnv[i]->t <= tright) { int x = int ((mEnv[i]->t + mOffset - h) * pps) + r.x; int y[4]; int numControlPoints; // Outer control points y[0] = GetWaveYPosNew( mEnv[i]->val, zoomMin, zoomMax, r.height, dB, true, dBr, false); y[1] = GetWaveYPosNew( -mEnv[i]->val, zoomMin, zoomMax, r.height, dB, true, dBr, false); // Inner control points(contour) y[2] = GetWaveYPosNew( mEnv[i]->val, zoomMin, zoomMax, r.height, dB, false, dBr, false); y[3] = GetWaveYPosNew( -mEnv[i]->val-.00000001, zoomMin, zoomMax, r.height, dB, false, dBr, false); numControlPoints = 4; if (y[2] > y[3]) numControlPoints = 2; if (!mMirror) numControlPoints = 1; for(int j=0; j<numControlPoints; j++){ int d = (int)(sqrt((double)(SQR(x-event.m_x) + SQR(y[j]-(event.m_y-r.y)))) + 0.5); if (d < bestDist) { bestNum = i; bestDist = d; mContourOffset = (bool)(j > 1); } } } } if (bestNum >= 0) { mDragPoint = bestNum; } else { // Create new point double when = h + (event.m_x - r.x) / pps - mOffset; // if (when <= 0 || when >= mTrackLen) // return false; double v = GetValueAtX( event.m_x, r, h, pps ); int ct = GetWaveYPosNew( v, zoomMin, zoomMax, r.height, dB, false, dBr, false) ; int cb = GetWaveYPosNew( -v-.000000001, zoomMin, zoomMax, r.height, dB, false, dBr, false) ; if( ct <= cb || !mMirror ){ int t = GetWaveYPosNew( v, zoomMin, zoomMax, r.height, dB, true, dBr, false) ; int b = GetWaveYPosNew( -v, zoomMin, zoomMax, r.height, dB, true, dBr, false) ; ct = (t + ct) / 2; cb = (b + cb) / 2; if(mMirror && (event.m_y - r.y) > ct && ((event.m_y - r.y) < cb)) mContourOffset = true; else mContourOffset = false; } double newVal = ValueOfPixel(clip_y, r.height, upper, dB, zoomMin, zoomMax); //float MaxAmplify = ( mContourOffset ) ? 1.4 : 1.0; float MaxAmplify = 2.0; if (newVal > MaxAmplify) newVal = MaxAmplify; mDragPoint = Insert(when, newVal); mDirty = true; } mUpper = upper; mInitialWhen = mEnv[mDragPoint]->t; mInitialVal = mEnv[mDragPoint]->val; mInitialX = event.m_x; mInitialY = event.m_y+mContourOffset; return true; }
/// HandleMouseButtonDown either finds an existing control point or adds a new one /// which is then recorded as the point to drag. /// This is slightly complicated by there possibly being four control points for /// a given time value: /// We have an upper and lower envelope line. /// Also we may be showing an inner envelope (at 0.5 the range). bool Envelope::HandleMouseButtonDown(wxMouseEvent & event, wxRect & r, double h, double pps, bool dB, float zoomMin, float zoomMax) { int ctr = (int)(r.height * zoomMax / (zoomMax - zoomMin)); bool upper = !mMirror || (zoomMin >= 0.0) || (event.m_y - r.y < ctr); int clip_y = event.m_y - r.y; if(clip_y < 0) clip_y = 0; //keeps point in rect r, even if mouse isn't if(clip_y > r.GetBottom()) clip_y = r.GetBottom(); double tleft = h - mOffset; double tright = tleft + (r.width / pps); int bestNum = -1; int bestDist = 10; // Must be within 10 pixel radius. // TODO: Cache the gPrefs value. Reading it every time is inefficient. double dBr = gPrefs->Read(wxT("/GUI/EnvdBRange"), ENV_DB_RANGE); // Member variables hold state that will be needed in dragging. mButton = event.GetButton(); mIsDeleting = false; mContourOffset = false; // wxLogDebug(wxT("Y:%i Height:%i Offset:%i"), y, height, mContourOffset ); int len = mEnv.Count(); // TODO: extract this into a function FindNearestControlPoint() // TODO: also fix it so that we can drag the last point on an envelope. for (int i = 0; i < len; i++) { //search for control point nearest click if (mEnv[i]->GetT() >= tleft && mEnv[i]->GetT() <= tright) { int x = int ((mEnv[i]->GetT() + mOffset - h) * pps) + r.x; int y[4]; int numControlPoints; // Outer control points y[0] = GetWaveYPos( mEnv[i]->GetVal(), zoomMin, zoomMax, r.height, dB, true, dBr, false); y[1] = GetWaveYPos( -mEnv[i]->GetVal(), zoomMin, zoomMax, r.height, dB, true, dBr, false); // Inner control points(contour) y[2] = GetWaveYPos( mEnv[i]->GetVal(), zoomMin, zoomMax, r.height, dB, false, dBr, false); y[3] = GetWaveYPos( -mEnv[i]->GetVal()-.00000001, zoomMin, zoomMax, r.height, dB, false, dBr, false); numControlPoints = 4; if (y[2] > y[3]) numControlPoints = 2; if (!mMirror) numControlPoints = 1; for(int j=0; j<numControlPoints; j++){ int d = (int)(sqrt((double)(SQR(x-event.m_x) + SQR(y[j]-(event.m_y-r.y)))) + 0.5); if (d < bestDist) { bestNum = i; bestDist = d; mContourOffset = (bool)(j > 1); } } } } if (bestNum >= 0) { mDragPoint = bestNum; } else { // TODO: Extract this into a function CreateNewPoint double when = h + (event.m_x - r.x) / pps - mOffset; // if (when <= 0 || when >= mTrackLen) // return false; double v = GetValueAtX( event.m_x, r, h, pps ); int ct = GetWaveYPos( v, zoomMin, zoomMax, r.height, dB, false, dBr, false) ; int cb = GetWaveYPos( -v-.000000001, zoomMin, zoomMax, r.height, dB, false, dBr, false) ; if( ct <= cb || !mMirror ){ int t = GetWaveYPos( v, zoomMin, zoomMax, r.height, dB, true, dBr, false) ; int b = GetWaveYPos( -v, zoomMin, zoomMax, r.height, dB, true, dBr, false) ; ct = (t + ct) / 2; cb = (b + cb) / 2; if(mMirror && (event.m_y - r.y) > ct && ((event.m_y - r.y) < cb)) mContourOffset = true; else mContourOffset = false; } double newVal = ValueOfPixel(clip_y, r.height, upper, dB, zoomMin, zoomMax); mDragPoint = Insert(when, newVal); mDirty = true; } mUpper = upper; mInitialWhen = mEnv[mDragPoint]->GetT(); mInitialVal = mEnv[mDragPoint]->GetVal(); mInitialX = event.m_x; mInitialY = event.m_y+mContourOffset; return true; }
//////////////// // Mouse events void VideoSlider::OnMouse(wxMouseEvent &event) { // Coordinates int x = event.GetX(); int y = event.GetY(); bool shift = event.m_shiftDown; // Left click if (event.ButtonIsDown(wxMOUSE_BTN_LEFT)) { // Check if it's OK to drag bool canDrag = wxWindow::FindFocus() == this; if (!canDrag) { int tolerance = 4; int curX = GetXAtValue(GetValue()); if (x-curX < -tolerance || x-curX > tolerance) canDrag = true; } // Drag if (canDrag) { // Shift click to snap to keyframe if (shift && Display) { wxArrayInt KeyFrames = Display->GetKeyFrames(); int keys = KeyFrames.Count(); int clickedFrame = GetValueAtX(x); int closest = 0; int cur; // Find closest for (int i=0;i<keys;i++) { cur = KeyFrames[i]; if (abs(cur-clickedFrame) < abs(closest-clickedFrame)) { closest = cur; } } // Jump to frame if (closest == GetValue()) return; SetValue(closest); } // Normal click else { int go = GetValueAtX(x); if (go == GetValue()) return; SetValue(go); } Refresh(false); // Playing? if (Display->IsPlaying) { Display->Stop(); UpdateVideo(); Display->Play(); } else UpdateVideo(); } // Get focus SetFocus(); } // Right/middle click if (event.ButtonDown(wxMOUSE_BTN_RIGHT) || event.ButtonDown(wxMOUSE_BTN_MIDDLE)) { SetFocus(); } // Something else else if (!Display->IsPlaying) event.Skip(); }