SplineCtrlEx.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #ifndef CRYINCLUDE_EDITOR_CONTROLS_SPLINECTRLEX_H
  9. #define CRYINCLUDE_EDITOR_CONTROLS_SPLINECTRLEX_H
  10. #pragma once
  11. #if !defined(Q_MOC_RUN)
  12. #include <ISplines.h>
  13. #include "Controls/WndGridHelper.h"
  14. #include "IKeyTimeSet.h"
  15. #include "Undo/IUndoObject.h"
  16. #include <QWidget>
  17. #endif
  18. // Custom styles for this control.
  19. #define SPLINE_STYLE_NOGRID 0x0001
  20. #define SPLINE_STYLE_NO_TIME_MARKER 0x0002
  21. // Notify event sent when spline is being modified.
  22. #define SPLN_CHANGE (0x0001)
  23. // Notify event sent just before when spline is modified.
  24. #define SPLN_BEFORE_CHANGE (0x0002)
  25. // Notify when spline control is scrolled/zoomed.
  26. #define SPLN_SCROLL_ZOOM (0x0003)
  27. // Notify when time changed.
  28. #define SPLN_TIME_START_CHANGE (0x0001)
  29. #define SPLN_TIME_END_CHANGE (0x0002)
  30. #define SPLN_TIME_CHANGE (0x0004)
  31. // Notify event sent when a key selection changes
  32. #define SPLN_KEY_SELECTION_CHANGE (0x0005)
  33. #ifndef NM_CLICK
  34. // from commctrl.h
  35. #define NM_FIRST (0U - 0U)
  36. #define NM_CLICK (NM_FIRST - 2)
  37. #define NM_RCLICK (NM_FIRST - 5)
  38. #endif
  39. #ifdef LoadCursor
  40. #undef LoadCursor
  41. #endif
  42. class AbstractTimelineWidget;
  43. class TimelineWidget;
  44. class QRubberBand;
  45. class ISplineSet
  46. {
  47. public:
  48. virtual ISplineInterpolator* GetSplineFromID(const AZStd::string& id) = 0;
  49. virtual AZStd::string GetIDFromSpline(ISplineInterpolator* pSpline) = 0;
  50. virtual int GetSplineCount() const = 0;
  51. virtual int GetKeyCountAtTime(float time, float threshold) const = 0;
  52. };
  53. class ISplineCtrlUndo
  54. : public IUndoObject
  55. {
  56. public:
  57. virtual bool IsSelectionChanged() const = 0;
  58. };
  59. class AbstractSplineWidget
  60. : public IKeyTimeSet
  61. {
  62. friend class CUndoSplineCtrlEx;
  63. public:
  64. AbstractSplineWidget();
  65. virtual ~AbstractSplineWidget();
  66. int InsertKey(ISplineInterpolator* pSpline, ISplineInterpolator* pDetailSpline, const QPoint& point);
  67. virtual void update() = 0;
  68. virtual void update(const QRect& rect) = 0;
  69. virtual QPoint mapFromGlobal(const QPoint& point) const = 0;
  70. virtual void SetCapture() {}
  71. virtual QWidget* WidgetCast() = 0;
  72. void SetGrid(int numX, int numY) { m_gridX = numX; m_gridY = numY; };
  73. void SetTimeRange(const Range& range) { m_timeRange = range; }
  74. void SetValueRange(const Range& range) { m_valueRange = range; }
  75. void SetDefaultValueRange(const Range& range) { m_defaultValueRange = range; }
  76. void SetDefaultKeyTangentType(ESplineKeyTangentType type) { m_defaultKeyTangentType = type; }
  77. ESplineKeyTangentType GetDefaultKeyTangentType() const { return m_defaultKeyTangentType; }
  78. void SetTooltipValueScale(float x, float y) { m_fTooltipScaleX = x; m_fTooltipScaleY = y; };
  79. void SetSplineSet(ISplineSet* pSplineSet);
  80. void AddSpline(ISplineInterpolator* pSpline, ISplineInterpolator* pDetailSpline, const QColor& color);
  81. void AddSpline(ISplineInterpolator * pSpline, ISplineInterpolator * pDetailSpline, QColor anColorArray[4]);
  82. void RemoveSpline(ISplineInterpolator* pSpline);
  83. void RemoveAllSplines();
  84. int GetSplineCount() const { return static_cast<int>(m_splines.size()); }
  85. ISplineInterpolator* GetSpline(int nIndex) const { return m_splines[nIndex].pSpline; }
  86. void SetTimeMarker(float fTime);
  87. float GetTimeMarker() const { return m_fTimeMarker; }
  88. void SetTimeScale(float timeScale) { m_fTimeScale = timeScale; }
  89. void SetGridTimeScale(float fGridTimeScale) { m_fGridTimeScale = fGridTimeScale; }
  90. float GetGridTimeScale() { return m_fGridTimeScale; }
  91. void SetMinTimeEpsilon(float fMinTimeEpsilon) { m_fMinTimeEpsilon = fMinTimeEpsilon; }
  92. float GetMinTimeEpsilon() const { return m_fMinTimeEpsilon; }
  93. void SetSnapTime(bool bOn) { m_bSnapTime = bOn; }
  94. void SetSnapValue(bool bOn) { m_bSnapValue = bOn; }
  95. bool IsSnapTime() const { return m_bSnapTime; }
  96. bool IsSnapValue() const { return m_bSnapValue; }
  97. float SnapTimeToGridVertical(float time);
  98. void OnUserCommand(UINT cmd);
  99. void FitSplineToViewWidth();
  100. void FitSplineToViewHeight();
  101. void FitSplineHeightToValueRange();
  102. void CopyKeys();
  103. void PasteKeys();
  104. void StoreUndo();
  105. void ZeroAll();
  106. void KeyAll();
  107. void SelectAll();
  108. void RemoveSelectedKeyTimes();
  109. void RedrawWindowAroundMarker();
  110. void SplinesChanged();
  111. void SetControlAmplitude(bool controlAmplitude);
  112. bool GetControlAmplitude() const;
  113. //void SelectPreviousKey();
  114. //void SelectNextKey();
  115. void GotoNextKey(bool previousKey);
  116. void RemoveAllKeysButThis();
  117. //////////////////////////////////////////////////////////////////////////
  118. // Scrolling/Zooming.
  119. //////////////////////////////////////////////////////////////////////////
  120. Vec2 ClientToWorld(const QPoint& point);
  121. QPoint WorldToClient(Vec2 v);
  122. Vec2 GetZoom();
  123. void SetZoom(Vec2 zoom, const QPoint& center);
  124. void SetZoom(Vec2 zoom);
  125. void SetScrollOffset(Vec2 ofs);
  126. Vec2 GetScrollOffset();
  127. float SnapTime(float time);
  128. float SnapValue(float val);
  129. //////////////////////////////////////////////////////////////////////////
  130. // IKeyTimeSet Implementation
  131. int GetKeyTimeCount() const override;
  132. float GetKeyTime(int index) const override;
  133. void MoveKeyTimes(int numChanges, int* indices, float scale, float offset, bool copyKeys) override;
  134. bool GetKeyTimeSelected(int index) const override;
  135. void SetKeyTimeSelected(int index, bool selected) override;
  136. int GetKeyCount(int index) const override;
  137. int GetKeyCountBound() const override;
  138. void BeginEdittingKeyTimes() override;
  139. void EndEdittingKeyTimes() override;
  140. void SetEditLock(bool bLock) { m_bEditLock = bLock; }
  141. int leftBorderOffset() const
  142. {
  143. return m_nLeftOffset;
  144. }
  145. protected:
  146. enum EHitCode
  147. {
  148. HIT_NOTHING,
  149. HIT_KEY,
  150. HIT_SPLINE,
  151. HIT_TIMEMARKER,
  152. HIT_TANGENT_HANDLE
  153. };
  154. enum EEditMode
  155. {
  156. NothingMode = 0,
  157. SelectMode,
  158. TrackingMode,
  159. ScrollZoomMode,
  160. ScrollMode,
  161. ZoomMode,
  162. TimeMarkerMode,
  163. };
  164. struct SSplineInfo
  165. {
  166. QColor anColorArray[4];
  167. ISplineInterpolator* pSpline;
  168. ISplineInterpolator* pDetailSpline;
  169. };
  170. virtual bool GetTangentHandlePts(QPoint& inTangentPt, QPoint& pt, QPoint& outTangentPt, int nSpline, int nKey, int nDimension);
  171. EHitCode HitTest(const QPoint& point);
  172. ISplineInterpolator* HitSpline(const QPoint& point);
  173. //Tracking support helper functions
  174. void StartTracking(bool copyKeys);
  175. void StopTracking();
  176. void RemoveKey(ISplineInterpolator* pSpline, int nKey);
  177. void RemoveSelectedKeys();
  178. void RemoveSelectedKeyTimesImpl();
  179. void MoveSelectedKeys(Vec2 offset, bool copyKeys);
  180. void ScaleAmplitudeKeys(float time, float startValue, float offset);
  181. void TimeScaleKeys(float time, float startTime, float endTime);
  182. void ValueScaleKeys(float startValue, float endValue);
  183. void ModifySelectedKeysFlags(int nRemoveFlags, int nAddFlags);
  184. QPoint TimeToPoint(float time, ISplineInterpolator* pSpline);
  185. float TimeToXOfs(float x);
  186. void PointToTimeValue(QPoint point, float& time, float& value);
  187. float XOfsToTime(int x);
  188. QPoint XOfsToPoint(int x, ISplineInterpolator* pSpline);
  189. virtual void ClearSelection();
  190. virtual void SelectKey(ISplineInterpolator* pSpline, int nKey, int nDimension, bool bSelect);
  191. bool IsKeySelected(ISplineInterpolator* pSpline, int nKey, int nDimension) const;
  192. int GetNumSelected();
  193. void SetHorizontalExtent(int min, int max);
  194. virtual void SendNotifyEvent(const uint32_t nEvent) = 0;
  195. virtual void SelectRectangle(const QRect& rc, bool bSelect);
  196. //////////////////////////////////////////////////////////////////////////
  197. void UpdateKeyTimes() const;
  198. void ConditionalStoreUndo();
  199. void ClearSelectedKeys();
  200. void DuplicateSelectedKeys();
  201. Range GetSplinesRange();
  202. virtual void captureMouseImpl() = 0;
  203. virtual void releaseMouseImpl() = 0;
  204. virtual void setCursorImpl(UINT cursor) = 0;
  205. virtual ISplineCtrlUndo* CreateSplineCtrlUndoObject(std::vector<ISplineInterpolator*>& splineContainer);
  206. QRect m_rcClipRect;
  207. QRect m_rcSpline;
  208. QRect m_rcClient;
  209. QPoint m_cMousePos;
  210. QPoint m_cMouseDownPos;
  211. QPoint m_hitPoint;
  212. EHitCode m_hitCode;
  213. int m_nHitKeyIndex;
  214. int m_nHitDimension;
  215. int m_bHitIncomingHandle;
  216. ISplineInterpolator* m_pHitSpline;
  217. ISplineInterpolator* m_pHitDetailSpline;
  218. QPoint m_curvePoint;
  219. float m_fTimeMarker;
  220. int m_nKeyDrawRadius;
  221. bool m_bSnapTime;
  222. bool m_bSnapValue;
  223. bool m_bBitmapValid;
  224. int m_gridX;
  225. int m_gridY;
  226. float m_fMinTime, m_fMaxTime;
  227. float m_fMinValue, m_fMaxValue;
  228. float m_fTooltipScaleX, m_fTooltipScaleY;
  229. float m_fMinTimeEpsilon;
  230. QPoint m_lastToolTipPos;
  231. QString m_tooltipText;
  232. QRect m_rcSelect;
  233. QRect m_TimeUpdateRect;
  234. float m_fTimeScale;
  235. float m_fValueScale;
  236. float m_fGridTimeScale;
  237. Range m_timeRange;
  238. Range m_valueRange;
  239. Range m_defaultValueRange;
  240. //! This is how often to place ticks.
  241. //! value of 10 means place ticks every 10 second.
  242. double m_ticksStep;
  243. EEditMode m_editMode;
  244. int m_nLeftOffset;
  245. CWndGridHelper m_grid;
  246. //////////////////////////////////////////////////////////////////////////
  247. std::vector<SSplineInfo> m_splines;
  248. mutable bool m_bKeyTimesDirty;
  249. class KeyTime
  250. {
  251. public:
  252. KeyTime(float time, int count)
  253. : time(time)
  254. , oldTime(0.0f)
  255. , selected(false)
  256. , count(count) {}
  257. bool operator<(const KeyTime& other) const { return this->time < other.time; }
  258. float time;
  259. float oldTime;
  260. bool selected;
  261. int count;
  262. };
  263. mutable std::vector<KeyTime> m_keyTimes;
  264. mutable int m_totalSplineCount;
  265. static const float threshold;
  266. bool m_copyKeys;
  267. bool m_startedDragging;
  268. bool m_controlAmplitude;
  269. ESplineKeyTangentType m_defaultKeyTangentType;
  270. // Improving mouse control...
  271. bool m_boLeftMouseButtonDown;
  272. ISplineSet* m_pSplineSet;
  273. bool m_bEditLock;
  274. ISplineCtrlUndo* m_pCurrentUndo;
  275. AbstractTimelineWidget* m_pTimelineCtrl;
  276. };
  277. //////////////////////////////////////////////////////////////////////////
  278. // Spline control.
  279. //////////////////////////////////////////////////////////////////////////
  280. class SplineWidget
  281. : public QWidget
  282. , public AbstractSplineWidget
  283. {
  284. Q_OBJECT
  285. public:
  286. SplineWidget(QWidget* parent);
  287. virtual ~SplineWidget();
  288. void update() override { QWidget::update(); }
  289. void update(const QRect& rect) override { QWidget::update(rect); }
  290. QPoint mapFromGlobal(const QPoint& point) const override { return QWidget::mapFromGlobal(point); }
  291. void SetTimelineCtrl(TimelineWidget* pTimelineCtrl);
  292. QWidget* WidgetCast() override { return this; }
  293. Q_SIGNALS:
  294. void beforeChange();
  295. void change();
  296. void timeChange();
  297. void scrollZoomRequested();
  298. void clicked();
  299. void rightClicked();
  300. void keySelectionChange();
  301. protected:
  302. void paintEvent(QPaintEvent* event) override;
  303. void resizeEvent(QResizeEvent* event) override;
  304. void mousePressEvent(QMouseEvent* event) override;
  305. void mouseReleaseEvent(QMouseEvent* event) override;
  306. void mouseMoveEvent(QMouseEvent* event) override;
  307. void mouseDoubleClickEvent(QMouseEvent* event) override;
  308. void wheelEvent(QWheelEvent* event) override;
  309. void keyPressEvent(QKeyEvent* event) override;
  310. bool event(QEvent* event) override;
  311. void OnLButtonDown(const QPoint& point, Qt::KeyboardModifiers modifiers);
  312. void OnLButtonUp(const QPoint& point, Qt::KeyboardModifiers modifiers);
  313. void OnRButtonDown(const QPoint& point, Qt::KeyboardModifiers modifiers);
  314. void OnMButtonDown(const QPoint& point, Qt::KeyboardModifiers modifiers);
  315. void OnMButtonUp(const QPoint& point, Qt::KeyboardModifiers modifiers);
  316. void DrawGrid(QPainter* painter);
  317. void DrawSpline(QPainter* pDC, SSplineInfo& splineInfo, float startTime, float endTime);
  318. void DrawKeys(QPainter* painter, int splineIndex, float startTime, float endTime);
  319. void DrawTimeMarker(QPainter* pDC);
  320. void DrawTangentHandle(QPainter* pDC, int nSpline, int nKey, int nDimension);
  321. void SendNotifyEvent(const uint32_t nEvent) override;
  322. void captureMouseImpl() override { grabMouse(); }
  323. void releaseMouseImpl() override { releaseMouse(); }
  324. void setCursorImpl(UINT cursor) override { setCursor(CMFCUtils::LoadCursor(cursor)); }
  325. protected:
  326. QRubberBand* m_rubberBand;
  327. };
  328. #endif // CRYINCLUDE_EDITOR_CONTROLS_SPLINECTRLEX_H