BsGUICurves.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsEditorPrerequisites.h"
  5. #include "GUI/BsGUIElement.h"
  6. #include "GUI/BsGUITimeline.h"
  7. #include "GUI/BsGUIGraphTicks.h"
  8. #include "2D/BsImageSprite.h"
  9. #include "Animation/BsAnimationUtility.h"
  10. namespace bs
  11. {
  12. /** @addtogroup GUI-Editor
  13. * @{
  14. */
  15. /** Controls which elements should a GUICurves object draw. */
  16. enum class BS_SCRIPT_EXPORT(ed:true,m:GUIEditor,n:CurveDrawOptions) CurveDrawOption
  17. {
  18. /** Draws markers at specific time intervals. */
  19. DrawMarkers = 1 << 0,
  20. /** Draws elements representing individual keyframes. */
  21. DrawKeyframes = 1 << 1,
  22. /** Draws curves and the area between them. Only relevant if only two curves are provided for drawing. */
  23. DrawRange = 1 << 2
  24. };
  25. typedef Flags<CurveDrawOption> CurveDrawOptions;
  26. BS_FLAGS_OPERATORS(CurveDrawOption)
  27. /** Curve and a color to draw it in. */
  28. struct BS_SCRIPT_EXPORT(ed:true,pl:true,m:GUIEditor) CurveDrawInfo
  29. {
  30. CurveDrawInfo() = default;
  31. CurveDrawInfo(const TAnimationCurve<float>& curve, Color color)
  32. :curve(curve), color(color)
  33. { }
  34. TAnimationCurve<float> curve;
  35. Color color;
  36. };
  37. /** GUI element that displays one or multiple curves. */
  38. class BS_ED_EXPORT BS_SCRIPT_EXPORT(ed:true,m:GUIEditor) GUICurves : public GUITimeline
  39. {
  40. public:
  41. /** Returns type name of the GUI element used for finding GUI element styles. */
  42. static const String& getGUITypeName();
  43. /**
  44. * Creates a new GUI element.
  45. *
  46. * @param[in] styleName Optional style to use for the element. Style will be retrieved from GUISkin of the
  47. * GUIWidget the element is used on. If not specified default style is used.
  48. */
  49. BS_SCRIPT_EXPORT(ec:GUICurves)
  50. static GUICurves* create(const String& styleName = StringUtil::BLANK);
  51. /**
  52. * Creates a new GUI element.
  53. *
  54. * @param[in] drawOptions Options that control which additional elements to draw.
  55. * @param[in] styleName Optional style to use for the element. Style will be retrieved from GUISkin of the
  56. * GUIWidget the element is used on. If not specified default style is used.
  57. */
  58. BS_SCRIPT_EXPORT(ec:GUICurves)
  59. static GUICurves* create(CurveDrawOptions drawOptions, const String& styleName = StringUtil::BLANK);
  60. /**
  61. * Creates a new GUI element.
  62. *
  63. * @param[in] options Options that allow you to control how is the element positioned and sized. This will
  64. * override any similar options set by style.
  65. * @param[in] styleName Optional style to use for the element. Style will be retrieved from GUISkin of the
  66. * GUIWidget the element is used on. If not specified default style is used.
  67. */
  68. static GUICurves* create(const GUIOptions& options, const String& styleName = StringUtil::BLANK);
  69. /**
  70. * Creates a new GUI element.
  71. *
  72. * @param[in] drawOptions Options that control which additional elements to draw.
  73. * @param[in] options Options that allow you to control how is the element positioned and sized. This will
  74. * override any similar options set by style.
  75. * @param[in] styleName Optional style to use for the element. Style will be retrieved from GUISkin of the
  76. * GUIWidget the element is used on. If not specified default style is used.
  77. */
  78. static GUICurves* create(CurveDrawOptions drawOptions, const GUIOptions& options,
  79. const String& styleName = StringUtil::BLANK);
  80. /** Animation curves to display. */
  81. BS_SCRIPT_EXPORT(pr:setter,n:Curves)
  82. void setCurves(const Vector<CurveDrawInfo>& curves);
  83. /** @copydoc setCurves */
  84. BS_SCRIPT_EXPORT(pr:getter,n:Curves)
  85. const Vector<CurveDrawInfo>& getCurves() const { return mCurves; }
  86. /**
  87. * Changes the visible range that the GUI element displays.
  88. *
  89. * @param[in] xRange Range of the horizontal area. Displayed area will range from [0, xRange].
  90. * @param[in] yRange Range of the vertical area. Displayed area will range from [-yRange * 0.5, yRange * 0.5]
  91. */
  92. BS_SCRIPT_EXPORT()
  93. void setRange(float xRange, float yRange);
  94. /**
  95. * Returns the offset at which the displayed timeline values start at.
  96. *
  97. * @param[in] offset Value to start the timeline values at, where x = time, y = value.
  98. */
  99. BS_SCRIPT_EXPORT()
  100. void setOffset(const Vector2& offset);
  101. /** Centers and zooms the view to fully display the provided set of curves. */
  102. BS_SCRIPT_EXPORT()
  103. void centerAndZoom();
  104. /**
  105. * Converts pixel coordinates into coordinates in curve space.
  106. *
  107. * @param[in] pixelCoords Coordinates relative to this GUI element, in pixels.
  108. * @param[out] curveCoords Curve coordinates within the range as specified by setRange(). Only valid when
  109. * function returns true.
  110. * @param[in] padding Determines should coordinates over the area reserved for padding be registered.
  111. * @return True if the coordinates are within the curve area, false otherwise.
  112. */
  113. BS_SCRIPT_EXPORT()
  114. bool pixelToCurveSpace(const Vector2I& pixelCoords, Vector2& curveCoords, bool padding = false) const;
  115. /**
  116. * Converts coordinate in curve space (time, value) into pixel coordinates relative to this element's origin.
  117. *
  118. * @param[in] curveCoords Time and value of the location to convert.
  119. * @return Coordinates relative to this element's origin, in pixels.
  120. */
  121. BS_SCRIPT_EXPORT()
  122. Vector2I curveToPixelSpace(const Vector2& curveCoords) const;
  123. /**
  124. * Attempts to find a curve under the provided coordinates.
  125. *
  126. * @param[in] pixelCoords Coordinates relative to this GUI element in pixels.
  127. * @return Index of the curve, or -1 if none found.
  128. */
  129. BS_SCRIPT_EXPORT()
  130. UINT32 findCurve(const Vector2I& pixelCoords);
  131. /**
  132. * Attempts to find a keyframe under the provided coordinates.
  133. *
  134. * @param[in] pixelCoords Coordinates relative to this GUI element in pixels.
  135. * @param[out] keyframe Output object containing keyframe index and index of the curve it belongs to. Only
  136. * valid if method returns true.
  137. * @return True if there is a keyframe under the coordinates, false otherwise.
  138. */
  139. BS_SCRIPT_EXPORT()
  140. bool findKeyFrame(const Vector2I& pixelCoords, KeyframeRef& keyframe);
  141. /**
  142. * Attempts to find a a tangent handle under the provided coordinates.
  143. *
  144. * @param[in] pixelCoords Coordinates relative to this GUI element in pixels.
  145. * @param[in] tangent Output object containing keyframe information and tangent type. Only valid if method
  146. * returns true.
  147. * @return True if there is a tangent handle under the coordinates, false otherwise.
  148. */
  149. BS_SCRIPT_EXPORT()
  150. bool findTangent(const Vector2I& pixelCoords, TangentRef& tangent);
  151. /**
  152. * Marks the specified key-frame as selected, changing the way it is displayed.
  153. *
  154. * @param[in] keyframeRef Keyframe reference containing the curve and keyframe index.
  155. * @param[in] tangentMode Type of tangent to display on the selected keyframe.
  156. * @param[in] selected True to select it, false to deselect it.
  157. */
  158. BS_SCRIPT_EXPORT()
  159. void selectKeyframe(const KeyframeRef& keyframeRef, const TangentMode& tangentMode, bool selected);
  160. /** Clears any key-frames that were marked as selected. */
  161. BS_SCRIPT_EXPORT()
  162. void clearSelectedKeyframes();
  163. BS_SCRIPT_EXPORT(in:true)
  164. Event<void()> onClicked; /**< Triggered when the user clicks on the GUI element. */
  165. protected:
  166. GUICurves(CurveDrawOptions drawOptions, const String& styleName, const GUIDimensions& dimensions);
  167. ~GUICurves() override = default;
  168. /**
  169. * Converts a keyframe tangent (slope) value into a 2D normal vector.
  170. *
  171. * @param[in] tangent Keyframe tangent (slope).
  172. * @return Normalized 2D vector pointing in the direction of the tangent.
  173. */
  174. Vector2 tangentToNormal(float tangent) const;
  175. /**
  176. * Returns the position of the tangent, in element's pixel space.
  177. *
  178. * @param[in] keyFrame Keyframe that the tangent belongs to.
  179. * @param[in] type Which tangent to retrieve the position for.
  180. * @return Position of the tangent, relative to the this GUI element's origin, in pixels.
  181. */
  182. Vector2I getTangentPosition(const TKeyframe<float>& keyFrame, TangentType type) const;
  183. /**
  184. * Checks if the tangent should be displayed, depending on the active tangent mode.
  185. *
  186. * @param[in] mode Tangent mode for the keyframe.
  187. * @param[in] type Which tangent to check for.
  188. * @return True if the tangent should be displayed.
  189. */
  190. bool isTangentDisplayed(TangentMode mode, TangentType type) const;
  191. /**
  192. * Checks is the provided key-frame currently marked as selected.
  193. *
  194. * @param[in] curveIdx Index of the curve the keyframe is on.
  195. * @param[in] keyIdx Index of the keyframe.
  196. * @return True if selected, false otherwise.
  197. */
  198. bool isSelected(int curveIdx, int keyIdx) const;
  199. /**
  200. * Draws a vertical frame marker on the curve area.
  201. *
  202. * @param[in] t Time at which to draw the marker.
  203. * @param[in] color Color with which to draw the marker.
  204. * @param[in] onTop Determines should the marker be drawn above or below the curve.
  205. */
  206. void drawFrameMarker(float t, Color color, bool onTop);
  207. /** Draws a horizontal line representing the line at y = 0. */
  208. void drawCenterLine();
  209. /**
  210. * Draws a diamond shape of the specified size at the coordinates.
  211. *
  212. * @param[in] center Position at which to place the diamond's center, in pixel coordinates.
  213. * @param[in] size Determines number of pixels to extend the diamond in each direction.
  214. * @param[in] innerColor Color of the diamond's background.
  215. * @param[in] outerColor Color of the diamond's outline.
  216. */
  217. void drawDiamond(Vector2I center, int size, Color innerColor, Color outerColor);
  218. /**
  219. * Draws a keyframe a the specified time and value.
  220. *
  221. * @param[in] t Time to draw the keyframe at.
  222. * @param[in] y Y value to draw the keyframe at.
  223. * @param[in] selected Determines should the keyframe be drawing using the selected color scheme, or normally.
  224. */
  225. void drawKeyframe(float t, float y, bool selected);
  226. /**
  227. * Draws zero, one or two tangents for the specified keyframe. Whether tangents are drawn depends on the provided
  228. * mode.
  229. *
  230. * @param[in] keyFrame Keyframe to draw the tangents for.
  231. * @param[in] tangentMode Type of tangents in the keyframe.
  232. */
  233. void drawTangents(const TKeyframe<float>& keyFrame, TangentMode tangentMode);
  234. /**
  235. * Draws the curve using the provided color.
  236. *
  237. * @param[in] curve Curve to draw within the currently set range.
  238. * @param[in] color Color to draw the curve with.
  239. */
  240. void drawCurve(const TAnimationCurve<float>& curve, const Color& color);
  241. /*
  242. * Draws the area between two curves using the provided color.
  243. *
  244. * @param[in] curves Curves to draw within the currently set range.
  245. * @param[in] color Color to draw the area with.
  246. */
  247. void drawCurveRange(const Vector<TAnimationCurve<float>>& curves, Color color);
  248. /** @copydoc GUIElement::updateRenderElementsInternal */
  249. void updateRenderElementsInternal() override;
  250. /** @copydoc GUIElement::_mouseEvent() */
  251. bool _mouseEvent(const GUIMouseEvent& ev) override;
  252. private:
  253. /** Information about a currently selected keyframe. */
  254. struct SelectedKeyframe
  255. {
  256. SelectedKeyframe(KeyframeRef keyframeRef, TangentMode tangentMode)
  257. :keyframeRef(keyframeRef), tangentMode(tangentMode)
  258. { }
  259. KeyframeRef keyframeRef;
  260. TangentMode tangentMode;
  261. };
  262. Vector<CurveDrawInfo> mCurves;
  263. Vector<SelectedKeyframe> mSelectedKeyframes;
  264. float mYRange = 20.0f;
  265. float mYOffset = 0.0f;
  266. CurveDrawOptions mDrawOptions;
  267. GUIGraphTicks mTickHandler;
  268. };
  269. /** @} */
  270. }