123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include "EditorDefs.h"
- #include "SplineCtrl.h"
- // Qt
- #include <QPainter>
- #include <QPainterPath>
- #include <QToolTip>
- // Editor
- #include "TimelineCtrl.h"
- #define MIN_TIME_EPSILON 0.01f
- //////////////////////////////////////////////////////////////////////////
- CSplineCtrl::CSplineCtrl(QWidget* parent)
- : QWidget(parent)
- {
- m_nActiveKey = -1;
- m_nHitKeyIndex = -1;
- m_nKeyDrawRadius = 3;
- m_bTracking = false;
- m_pSpline = nullptr;
- m_gridX = 10;
- m_gridY = 10;
- m_fMinTime = -1;
- m_fMaxTime = 1;
- m_fMinValue = -1;
- m_fMaxValue = 1;
- m_fTooltipScaleX = 1;
- m_fTooltipScaleY = 1;
- m_bLockFirstLastKey = false;
- m_pTimelineCtrl = nullptr;
- m_bSelectedKeys.reserve(0);
- m_fTimeMarker = -10;
- setMouseTracking(true);
- }
- CSplineCtrl::~CSplineCtrl()
- {
- }
- /////////////////////////////////////////////////////////////////////////////
- // CSplineCtrl message handlers
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::resizeEvent([[maybe_unused]] QResizeEvent* event)
- {
- m_rcSpline = rect();
- if (m_pTimelineCtrl)
- {
- QRect rct = m_rcSpline;
- rct.setHeight(20);
- m_rcSpline.setTop(rct.bottom() + 1);
- m_pTimelineCtrl->setGeometry(rct);
- }
- m_rcSpline.adjust(2, 2, -2, -2);
- }
- //////////////////////////////////////////////////////////////////////////
- QPoint CSplineCtrl::KeyToPoint(int nKey)
- {
- if (nKey >= 0)
- {
- return TimeToPoint(m_pSpline->GetKeyTime(nKey));
- }
- return QPoint(0, 0);
- }
- //////////////////////////////////////////////////////////////////////////
- QPoint CSplineCtrl::TimeToPoint(float time)
- {
- QPoint point;
- point.setX(static_cast<int>((time - m_fMinTime) * (m_rcSpline.width() / (m_fMaxTime - m_fMinTime)) + m_rcSpline.left()));
- float val = 0;
- if (m_pSpline)
- {
- m_pSpline->InterpolateFloat(time, val);
- }
- point.setY(static_cast<int>((floor((m_fMaxValue - val) * (m_rcSpline.height() / (m_fMaxValue - m_fMinValue)) + 0.5f) + m_rcSpline.top())));
- return point;
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::PointToTimeValue(const QPoint& point, float& time, float& value)
- {
- time = XOfsToTime(point.x());
- float t = float(m_rcSpline.bottom() - point.y()) / m_rcSpline.height();
- value = AZ::Lerp(m_fMinValue, m_fMaxValue, t);
- }
- //////////////////////////////////////////////////////////////////////////
- float CSplineCtrl::XOfsToTime(int x)
- {
- // m_fMinTime to m_fMaxTime time range.
- float t = float(x - m_rcSpline.left()) / m_rcSpline.width();
- return AZ::Lerp(m_fMinTime, m_fMaxTime, t);
- }
- //////////////////////////////////////////////////////////////////////////
- QPoint CSplineCtrl::XOfsToPoint(int x)
- {
- return TimeToPoint(XOfsToTime(x));
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::paintEvent(QPaintEvent* event)
- {
- QPainter painter(this);
- if (m_pSpline)
- {
- m_bSelectedKeys.resize(m_pSpline->GetKeyCount());
- }
- {
- if (m_TimeUpdateRect != event->rect())
- {
- painter.fillRect(event->rect(), QColor(140, 140, 140));
- //Draw Grid
- DrawGrid(&painter);
- //Draw Keys and Curve
- if (m_pSpline)
- {
- DrawSpline(&painter);
- DrawKeys(&painter);
- }
- }
- m_TimeUpdateRect = QRect();
- }
- DrawTimeMarker(&painter);
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::DrawGrid(QPainter* painter)
- {
- QPen pOldPen = painter->pen();
- int cx = m_rcSpline.width();
- int cy = m_rcSpline.height();
- QPen pen(QColor(90, 90, 90), 1, Qt::DotLine);
- pen.setCosmetic(true);
- painter->setPen(pen);
- //Draw Vertical Grid Lines
- for (int y = 1; y < m_gridX; y++)
- {
- painter->drawLine(m_rcSpline.left() + y * cx / m_gridX, m_rcSpline.top() + cy, m_rcSpline.left() + y * cx / m_gridX, m_rcSpline.top());
- }
- //Draw Horizontal Grid Lines
- for (int x = 1; x < m_gridY; x++)
- {
- painter->drawLine(m_rcSpline.left(), m_rcSpline.top() + x * cy / m_gridY, m_rcSpline.left() + cx, m_rcSpline.top() + x * cy / m_gridY);
- }
- painter->setPen(QColor(75, 75, 75));
- painter->drawLine(m_rcSpline.left() + (m_gridX / 2) * cx / m_gridX, m_rcSpline.top() + cy, m_rcSpline.left() + (m_gridX / 2) * cx / m_gridX, m_rcSpline.top() + 0);
- painter->drawLine(m_rcSpline.left() + 0, m_rcSpline.left() + (m_gridY / 2) * cy / m_gridY, m_rcSpline.left() + cx, m_rcSpline.left() + (m_gridY / 2) * cy / m_gridY);
- painter->drawRect(m_rcSpline);
- painter->setPen(pOldPen);
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::DrawSpline(QPainter* painter)
- {
- //Draw Curve
- // create and select a thick, white pen
- const QPen pOldPen = painter->pen();
- painter->setPen(QColor(128, 255, 128));
- const QRect rcClip = painter->hasClipping() ? painter->clipBoundingRect().intersected(m_rcSpline).toRect() : m_rcSpline;
- bool bFirst = true;
- QPainterPath path;
- for (int x = rcClip.left(); x < rcClip.right(); x++)
- {
- QPoint pt = XOfsToPoint(x);
- if (!bFirst)
- {
- path.lineTo(pt);
- }
- else
- {
- path.moveTo(pt);
- bFirst = false;
- }
- }
- painter->drawPath(path);
- // Put back the old objects
- painter->setPen(pOldPen);
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::DrawKeys(QPainter* painter)
- {
- if (!m_pSpline)
- {
- return;
- }
- // create and select a white pen
- const QPen pOldPen = painter->pen();
- painter->setPen(Qt::black);
- m_bSelectedKeys.resize(m_pSpline->GetKeyCount());
- for (int i = 0; i < m_pSpline->GetKeyCount(); i++)
- {
- float time = m_pSpline->GetKeyTime(i);
- const QPoint pt = TimeToPoint(time);
- QColor clr(220, 220, 0);
- if (m_bSelectedKeys[i])
- {
- clr = QColor(255, 0, 0);
- }
- const QBrush pOldBrush = painter->brush();
- painter->setBrush(clr);
- // Draw this key.
- painter->drawRect(QRect(QPoint(pt.x() - m_nKeyDrawRadius, pt.y() - m_nKeyDrawRadius), QPoint(pt.x() + m_nKeyDrawRadius - 1, pt.y() + m_nKeyDrawRadius - 1)));
- painter->setBrush(pOldBrush);
- }
- painter->setPen(pOldPen);
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::DrawTimeMarker(QPainter* painter)
- {
- painter->setPen(QColor(255, 0, 255));
- const QPoint pt = TimeToPoint(m_fTimeMarker);
- painter->drawLine(pt.x(), m_rcSpline.top() + 1, pt.x(), m_rcSpline.bottom() - 1);
- }
- void CSplineCtrl::UpdateToolTip()
- {
- if (m_nHitKeyIndex >= 0 && m_pSpline)
- {
- float time = m_pSpline->GetKeyTime(m_nHitKeyIndex);
- float val;
- m_pSpline->GetKeyValueFloat(m_nHitKeyIndex, val);
- int cont_s = (m_pSpline->GetKeyFlags(m_nHitKeyIndex) >> SPLINE_KEY_TANGENT_IN_SHIFT) & SPLINE_KEY_TANGENT_LINEAR ? 1 : 2;
- int cont_d = (m_pSpline->GetKeyFlags(m_nHitKeyIndex) >> SPLINE_KEY_TANGENT_OUT_SHIFT) & SPLINE_KEY_TANGENT_LINEAR ? 1 : 2;
- const QString tipText = tr("%1, %2, [%3|%4").arg(time * m_fTooltipScaleX, 3, 'f').arg(val * m_fTooltipScaleY, 3, 'f').arg(cont_s).arg(cont_d);
- QToolTip::showText(QCursor::pos(), tipText, this);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- //Mouse Message Handlers
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::mousePressEvent(QMouseEvent* event)
- {
- switch (event->button())
- {
- case Qt::LeftButton:
- OnLButtonDown(event->pos(), event->modifiers());
- break;
- case Qt::RightButton:
- OnRButtonDown(event->pos(), event->modifiers());
- break;
- }
- }
- void CSplineCtrl::mouseReleaseEvent(QMouseEvent* event)
- {
- switch (event->button())
- {
- case Qt::LeftButton:
- OnLButtonUp(event->pos(), event->modifiers());
- break;
- }
- }
- void CSplineCtrl::OnLButtonDown([[maybe_unused]] const QPoint& point, [[maybe_unused]] Qt::KeyboardModifiers modifiers)
- {
- if (m_bTracking)
- {
- return;
- }
- if (!m_pSpline)
- {
- return;
- }
- setFocus();
- switch (m_hitCode)
- {
- case HIT_KEY:
- StartTracking();
- SetActiveKey(m_nHitKeyIndex);
- break;
- case HIT_SPLINE:
- // Cycle the spline slope of the nearest key.
- ToggleKeySlope(m_nHitKeyIndex, m_nHitKeyDist);
- SetActiveKey(-1);
- break;
- case HIT_NOTHING:
- SetActiveKey(-1);
- break;
- }
- update();
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::OnRButtonDown([[maybe_unused]] const QPoint& point, [[maybe_unused]] Qt::KeyboardModifiers modifiers)
- {
- setFocus();
- if (!m_pSpline)
- {
- return;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::mouseDoubleClickEvent(QMouseEvent* event)
- {
- if (!m_pSpline || event->button() != Qt::LeftButton)
- {
- return;
- }
- switch (m_hitCode)
- {
- case HIT_NOTHING:
- {
- int iIndex = InsertKey(event->pos());
- SetActiveKey(iIndex);
- update();
- }
- break;
- case HIT_KEY:
- {
- RemoveKey(m_nHitKeyIndex);
- }
- break;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::mouseMoveEvent(QMouseEvent* event)
- {
- OnSetCursor();
- if (!m_pSpline)
- {
- return;
- }
- if (m_bTracking)
- {
- TrackKey(event->pos());
- UpdateToolTip();
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::OnLButtonUp([[maybe_unused]] const QPoint& point, [[maybe_unused]] Qt::KeyboardModifiers modifiers)
- {
- if (!m_pSpline)
- {
- return;
- }
- if (m_bTracking)
- {
- StopTracking();
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::SetActiveKey(int nIndex)
- {
- ClearSelection();
- // Activate New Key
- if (nIndex >= 0)
- {
- m_bSelectedKeys[nIndex] = true;
- }
- m_nActiveKey = nIndex;
- update();
- }
- /////////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::SetSpline(ISplineInterpolator* pSpline, bool bRedraw)
- {
- if (pSpline != m_pSpline)
- {
- m_pSpline = pSpline;
- }
- ValidateSpline();
- ClearSelection();
- if (bRedraw)
- {
- update();
- }
- }
- void CSplineCtrl::ValidateSpline()
- {
- // Add initial control points (will be serialised only if edited).
- if (m_pSpline->GetKeyCount() == 0)
- {
- m_pSpline->InsertKeyFloat(0.f, 1.f);
- m_pSpline->InsertKeyFloat(1.f, 1.f);
- m_pSpline->Update();
- }
- }
- //////////////////////////////////////////////////////////////////////////
- ISplineInterpolator* CSplineCtrl::GetSpline()
- {
- return m_pSpline;
- }
- /////////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::OnSetCursor()
- {
- const QPoint point = mapFromGlobal(QCursor::pos());
- const int hitKey = m_nHitKeyIndex;
- switch (HitTest(point))
- {
- case HIT_SPLINE:
- {
- setCursor(CMFCUtils::LoadCursor(IDC_ARRWHITE));
- } break;
- case HIT_KEY:
- {
- setCursor(CMFCUtils::LoadCursor(IDC_ARRBLCK));
- } break;
- default:
- unsetCursor();
- break;
- }
- if (m_bTracking)
- {
- m_nHitKeyIndex = hitKey;
- }
- if (m_pSpline)
- {
- if (m_nHitKeyIndex >= 0)
- {
- UpdateToolTip();
- }
- else if (!m_bTracking)
- {
- QToolTip::hideText();
- }
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::keyPressEvent(QKeyEvent* event)
- {
- bool bProcessed = false;
- if (m_nActiveKey != -1 && m_pSpline)
- {
- switch (event->key())
- {
- case Qt::Key_Space:
- {
- ToggleKeySlope(m_nActiveKey, 0);
- bProcessed = true;
- } break;
- case Qt::Key_Delete:
- {
- RemoveKey(m_nActiveKey);
- bProcessed = true;
- } break;
- case Qt::Key_Up:
- {
- CUndo undo("Move Spline Key");
- QPoint point = KeyToPoint(m_nActiveKey);
- point.ry() -= 1;
- emit beforeChange();
- TrackKey(point);
- bProcessed = true;
- } break;
- case Qt::Key_Down:
- {
- CUndo undo("Move Spline Key");
- QPoint point = KeyToPoint(m_nActiveKey);
- point.ry() += 1;
- emit beforeChange();
- TrackKey(point);
- bProcessed = true;
- } break;
- case Qt::Key_Left:
- {
- CUndo undo("Move Spline Key");
- QPoint point = KeyToPoint(m_nActiveKey);
- point.rx() -= 1;
- emit beforeChange();
- TrackKey(point);
- bProcessed = true;
- } break;
- case Qt::Key_Right:
- {
- CUndo undo("Move Spline Key");
- QPoint point = KeyToPoint(m_nActiveKey);
- point.ry() += 1;
- emit beforeChange();
- TrackKey(point);
- bProcessed = true;
- } break;
- default:
- break; //do nothing
- }
- update();
- }
- event->setAccepted(bProcessed);
- }
- //////////////////////////////////////////////////////////////////////////////
- CSplineCtrl::EHitCode CSplineCtrl::HitTest(const QPoint& point)
- {
- if (!m_pSpline)
- {
- return HIT_NOTHING;
- }
- float time, val;
- PointToTimeValue(point, time, val);
- m_nHitKeyIndex = -1;
- m_nHitKeyDist = 0xFFFF;
- m_hitCode = HIT_NOTHING;
- QPoint splinePt = TimeToPoint(time);
- if (abs(splinePt.y() - point.y()) < 4)
- {
- m_hitCode = HIT_SPLINE;
- for (int i = 0; i < m_pSpline->GetKeyCount(); i++)
- {
- const QPoint splinePt2 = TimeToPoint(m_pSpline->GetKeyTime(i));
- if (abs(point.x() - splinePt2.x()) < abs(m_nHitKeyDist))
- {
- m_nHitKeyIndex = i;
- m_nHitKeyDist = point.x() - splinePt2.x();
- }
- }
- if (abs(m_nHitKeyDist) < 4)
- {
- m_hitCode = HIT_KEY;
- }
- }
- return m_hitCode;
- }
- ///////////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::StartTracking()
- {
- m_bTracking = true;
- GetIEditor()->BeginUndo();
- emit beforeChange();
- setCursor(CMFCUtils::LoadCursor(IDC_ARRBLCKCROSS));
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::TrackKey(const QPoint& p)
- {
- int nKey = m_nHitKeyIndex;
- QPoint point = p;
- if (nKey >= 0)
- {
- float time, val;
- // Editing time & value.
- Limit(point.rx(), m_rcSpline.left(), m_rcSpline.right());
- Limit(point.ry(), m_rcSpline.top(), m_rcSpline.bottom());
- PointToTimeValue(point, time, val);
- int i;
- for (i = 0; i < m_pSpline->GetKeyCount(); i++)
- {
- // Switch to next key.
- if (fabs(m_pSpline->GetKeyTime(i) - time) < MIN_TIME_EPSILON)
- {
- if (i != nKey)
- {
- return;
- }
- }
- }
- m_pSpline->SetKeyValueFloat(nKey, val);
- if ((nKey != 0 && nKey != m_pSpline->GetKeyCount() - 1) || !m_bLockFirstLastKey)
- {
- m_pSpline->SetKeyTime(nKey, time);
- }
- else if (m_bLockFirstLastKey)
- {
- int first = 0;
- int last = m_pSpline->GetKeyCount() - 1;
- if (nKey == first)
- {
- m_pSpline->SetKeyValueFloat(last, val);
- }
- else if (nKey == last)
- {
- m_pSpline->SetKeyValueFloat(first, val);
- }
- }
- m_pSpline->Update();
- emit change();
- if (m_updateCallback)
- {
- m_updateCallback(this);
- }
- update();
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::StopTracking()
- {
- if (!m_bTracking)
- {
- return;
- }
- GetIEditor()->AcceptUndo("Spline Move");
- m_bTracking = false;
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::RemoveKey(int nKey)
- {
- if (!m_pSpline)
- {
- return;
- }
- if (nKey)
- {
- if (m_bLockFirstLastKey)
- {
- if (nKey == 0 || nKey == m_pSpline->GetKeyCount() - 1)
- {
- return;
- }
- }
- }
- CUndo undo("Remove Spline Key");
- emit beforeChange();
- m_nActiveKey = -1;
- m_nHitKeyIndex = -1;
- if (m_pSpline)
- {
- m_pSpline->RemoveKey(nKey);
- m_pSpline->Update();
- ValidateSpline();
- }
- emit change();
- if (m_updateCallback)
- {
- m_updateCallback(this);
- }
- update();
- }
- //////////////////////////////////////////////////////////////////////////
- int CSplineCtrl::InsertKey(const QPoint& point)
- {
- CUndo undo("Spline Insert Key");
- float time, val;
- PointToTimeValue(point, time, val);
- int i;
- for (i = 0; i < m_pSpline->GetKeyCount(); i++)
- {
- // Skip if any key already have time that is very close.
- if (fabs(m_pSpline->GetKeyTime(i) - time) < MIN_TIME_EPSILON)
- {
- return i;
- }
- }
- emit beforeChange();
- m_pSpline->InsertKeyFloat(time, val);
- m_pSpline->Update();
- ClearSelection();
- update();
- emit change();
- if (m_updateCallback)
- {
- m_updateCallback(this);
- }
- for (i = 0; i < m_pSpline->GetKeyCount(); i++)
- {
- // Find key with added time.
- if (m_pSpline->GetKeyTime(i) == time)
- {
- return i;
- }
- }
- return -1;
- }
- void CSplineCtrl::ToggleKeySlope(int nIndex, int nDir)
- {
- if (nIndex >= 0)
- {
- int flags = m_pSpline->GetKeyFlags(nIndex);
- if (nDir <= 0)
- {
- // Toggle left side.
- flags ^= SPLINE_KEY_TANGENT_LINEAR << SPLINE_KEY_TANGENT_IN_SHIFT;
- }
- if (nDir >= 0)
- {
- // Toggle right side.
- flags ^= SPLINE_KEY_TANGENT_LINEAR << SPLINE_KEY_TANGENT_OUT_SHIFT;
- }
- m_pSpline->SetKeyFlags(nIndex, flags);
- m_pSpline->Update();
- emit change();
- if (m_updateCallback)
- {
- m_updateCallback(this);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::ClearSelection()
- {
- m_nActiveKey = -1;
- if (m_pSpline)
- {
- m_bSelectedKeys.resize(m_pSpline->GetKeyCount());
- }
- for (int i = 0; i < (int)m_bSelectedKeys.size(); i++)
- {
- m_bSelectedKeys[i] = false;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::SetTimeMarker(float fTime)
- {
- if (!m_pSpline)
- {
- return;
- }
- if (fTime == m_fTimeMarker)
- {
- return;
- }
- // Erase old first.
- QPoint pt0 = TimeToPoint(m_fTimeMarker);
- QPoint pt1 = TimeToPoint(fTime);
- QRect rc(QPoint(pt0.x(), m_rcSpline.top()), QPoint(pt1.x(), m_rcSpline.bottom()));
- rc = rc.normalized();
- rc.adjust(-5, 0, 5, 0);
- rc = rc.intersected(m_rcSpline);
- m_TimeUpdateRect = rc;
- update(rc);
- m_fTimeMarker = fTime;
- }
- //////////////////////////////////////////////////////////////////////////
- void CSplineCtrl::SetTimelineCtrl(TimelineWidget* pTimelineCtrl)
- {
- m_pTimelineCtrl = pTimelineCtrl;
- if (m_pTimelineCtrl)
- {
- m_pTimelineCtrl->setParent(this);
- }
- }
- #include <Controls/moc_SplineCtrl.cpp>
|