NAP
sequenceeventtrackview.h
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4 
5 #pragma once
6 
7 #include "sequencetrackview.h"
8 #include "sequencecontrollerevent.h"
9 #include "sequencetracksegment.h"
10 #include "sequenceeditorguiclipboard.h"
11 #include "sequenceeventtrackview_guiactions.h"
12 #include "sequenceguiutils.h"
13 
14 #include <utility>
15 #include <imguiutils.h>
16 
17 namespace nap
18 {
20 
21  // forward declares
22  class SequenceEventTrackView;
23  class SequenceGUIService;
24 
30  class NAPAPI SequenceEventTrackSegmentViewBase
31  {
32  RTTI_ENABLE()
33  public:
37  SequenceEventTrackSegmentViewBase() = default;
38 
42  virtual ~SequenceEventTrackSegmentViewBase() = default;
43 
49  virtual void handleEditPopupContent(sequenceguiactions::Action& action) = 0;
50 
60  virtual void drawEvent(const SequenceTrackSegment& segment, ImDrawList* drawList, const ImVec2& topLeft, float x, ImU32 color) = 0;
61 
69  virtual void insertSegment(SequenceControllerEvent& controller, const std::string& trackID, double time) = 0;
70 
79  virtual std::unique_ptr<sequenceguiactions::Action> createEditAction(const SequenceTrackSegmentEventBase* segment, const std::string& trackID, const std::string& segmentID) = 0;
80  };
81 
90  template<typename T>
92  {
94  public:
99  {}
100 
101 
107  void handleEditPopupContent(sequenceguiactions::Action& action) override;
108 
118  void drawEvent(const SequenceTrackSegment& segment, ImDrawList* drawList, const ImVec2& topLeft, float x, ImU32 color) override;
119 
127  void insertSegment(SequenceControllerEvent& controller, const std::string& trackID, double time) override;
128 
137  std::unique_ptr<sequenceguiactions::Action>
138  createEditAction(const SequenceTrackSegmentEventBase* segment, const std::string& trackID, const std::string& segmentID) override;
139  };
140 
144  class NAPAPI SequenceEventTrackView final : public SequenceTrackView
145  {
146  friend class SequenceGUIService;
147 
148  RTTI_ENABLE(SequenceTrackView)
149  public:
157 
158  // make this class explicitly non-copyable
160  SequenceEventTrackView& operator=(const SequenceEventTrackView&) = delete;
161 
162  protected:
167  void showInspectorContent(const SequenceTrack& track) override;
168 
174  void showTrackContent(const SequenceTrack& track, const ImVec2& trackTopLeft) override;
175 
179  void handleInsertEventSegmentPopup();
180 
184  template<typename T>
185  void handleEditEventSegmentPopup();
186 
195  bool pasteEventsFromClipboard(const std::string& trackID, double time, utility::ErrorState& errorState);
196 
204  template<typename T>
205  void pasteEvent(const std::string& trackID, const SequenceTrackSegmentEventBase& baseEvent, double time);
206 
216  void
217  drawSegmentHandler(const SequenceTrack& track, const SequenceTrackSegment& segment, const ImVec2& trackTopLeft, float segmentX, float segmentWidth, ImDrawList* drawList);
218 
222  void handleEditSegmentValuePopup();
223 
229  void updateSegmentInClipboard(const std::string& trackID, const std::string& segmentID);
230 
234  void handleAssignOutputIDToTrack();
235 
239  void handleSegmentDrag();
240 
244  void handleLoadPresetPopup();
245 
246  private:
247  // map of segment views for different event views
248  std::unordered_map<rtti::TypeInfo, std::unique_ptr<SequenceEventTrackSegmentViewBase>> mSegmentViews;
249  };
250 
251 
253  // Event Clipboards
255 
256  namespace sequenceguiclipboard
257  {
259  public Clipboard
260  {
261  RTTI_ENABLE(Clipboard)
262  public:
263  EventSegmentClipboard(const rttr::type& type, std::string sequenceName)
264  : Clipboard(type), mSequenceName(std::move(sequenceName))
265  {};
266 
267 
268  const std::string &getSequenceName() const{ return mSequenceName; }
269 
270  private:
271  std::string mSequenceName;
272  };
273  }
274 
276  // Template definitions
278 
279  template<typename T>
281  {
282  if(mState.mAction->isAction<sequenceguiactions::OpenEditEventSegmentPopup<T>>())
283  {
284  // invoke insert sequence popup
285  ImGui::OpenPopup("Edit Event");
286 
287  auto *action = mState.mAction->getDerived<sequenceguiactions::OpenEditEventSegmentPopup<T>>();
288  ImGui::SetNextWindowPos(action->mWindowPos);
289 
290  mState.mAction = sequenceguiactions::createAction<sequenceguiactions::EditingEventSegment<T>>(action->mTrackID, action->mSegmentID, action->mWindowPos, action->mValue, action->mStartTime);
291  }
292 
293  // handle insert segment popup
294  if(mState.mAction->isAction<sequenceguiactions::EditingEventSegment<T>>())
295  {
296  auto *action = mState.mAction->getDerived<sequenceguiactions::EditingEventSegment<T>>();
297 
298  if(ImGui::BeginPopup("Edit Event"))
299  {
300  // draw the registered popup content for this event
301  auto it = mSegmentViews.find(RTTI_OF(SequenceTrackSegmentEvent<T>));
302  assert(it != mSegmentViews.end()); // type not found
303  it->second->handleEditPopupContent(*action);
304 
305  // time
306  std::vector<int> time_array = convertTimeToMMSSMSArray(action->mStartTime);
307 
308  bool edit_time = false;
309 
310  ImGui::Separator();
311  ImGui::PushItemWidth(100.0f * mState.mScale);
312 
313  edit_time = ImGui::InputInt3("Time (mm:ss:ms)", &time_array[0]);
314  time_array[0] = math::clamp<int>(time_array[0], 0, 99999);
315  time_array[1] = math::clamp<int>(time_array[1], 0, 59);
316  time_array[2] = math::clamp<int>(time_array[2], 0, 99);
317 
318  ImGui::PopItemWidth();
319 
320  ImGui::Separator();
321 
322  if(edit_time)
323  {
324  auto &event_controller = getEditor().getController<SequenceControllerEvent>();
325  double new_time = convertMMSSMSArrayToTime(time_array);
326  double time = event_controller.segmentEventStartTimeChange(action->mTrackID, action->mSegmentID, new_time);
327  updateSegmentInClipboard(action->mTrackID, action->mSegmentID);
328  action->mStartTime = time;
329  mState.mDirty = true;
330  }
331  if(ImGui::ImageButton(mService.getGui().getIcon(icon::ok)))
332  {
333  auto &event_controller = getEditor().getController<SequenceControllerEvent>();
334  event_controller.editEventSegment<T>(action->mTrackID, action->mSegmentID, action->mValue);
335  updateSegmentInClipboard(action->mTrackID, action->mSegmentID);
336  mState.mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
337  ImGui::CloseCurrentPopup();
338  }
339  ImGui::SameLine();
340  if(ImGui::ImageButton(mService.getGui().getIcon(icon::cancel)))
341  {
342  ImGui::CloseCurrentPopup();
343  mState.mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
344  }
345 
346  action->mWindowPos = ImGui::GetWindowPos();
347 
348  ImGui::EndPopup();
349  } else
350  {
351  // click outside popup so cancel action
352  mState.mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
353  }
354  }
355  }
356 
357 
358  template<typename T>
359  void SequenceEventTrackView::pasteEvent(const std::string& trackID, const SequenceTrackSegmentEventBase& baseEvent, double time)
360  {
361  // obtain controller
362  auto &controller = getEditor().getController<SequenceControllerEvent>();
363 
364  // insert new segment
365  const auto *new_segment = dynamic_cast<const T *>(controller.insertEventSegment<T>(trackID,
366  baseEvent.mStartTime +
367  time));
368  assert(new_segment != nullptr); // cast failed
369 
370  // upcast de-serialized event
371  const auto *event_upcast = dynamic_cast<const T *>(&baseEvent);
372  assert(event_upcast != nullptr); // cast failed
373 
374  // copy values from deserialized event segment
375  controller.editEventSegment(trackID, new_segment->mID, event_upcast->mValue);
376  }
377 
378 
379  template<typename T>
380  void SequenceEventTrackSegmentView<T>::insertSegment(SequenceControllerEvent& controller, const std::string& trackID, double time)
381  {
382  controller.insertEventSegment<SequenceTrackSegmentEvent<T>>(trackID, time);
383  }
384 
385 
386  template<typename T>
387  std::unique_ptr<sequenceguiactions::Action> SequenceEventTrackSegmentView<T>::createEditAction(const SequenceTrackSegmentEventBase* segment, const std::string& trackID, const std::string& segmentID)
388  {
389  const auto* event = static_cast<const SequenceTrackSegmentEvent<T>*>(segment);
390  return sequenceguiactions::createAction<sequenceguiactions::OpenEditEventSegmentPopup<T>>(trackID, segmentID, ImGui::GetWindowPos(), event->mValue, segment->mStartTime);
391  }
392 }
nap::SequenceEventTrackView::pasteEvent
void pasteEvent(const std::string &trackID, const SequenceTrackSegmentEventBase &baseEvent, double time)
Definition: sequenceeventtrackview.h:359
nap::SequenceEventTrackView::handleEditEventSegmentPopup
void handleEditEventSegmentPopup()
Definition: sequenceeventtrackview.h:280
nap::SequenceEventTrackSegmentView::insertSegment
void insertSegment(SequenceControllerEvent &controller, const std::string &trackID, double time) override
Definition: sequenceeventtrackview.h:380
nap::SequenceEditorGUIState
Definition: sequenceeditorguistate.h:23
nap::convertMMSSMSArrayToTime
double NAPAPI convertMMSSMSArrayToTime(const std::vector< int > &timeArray)
ImGui::ImageButton
bool IMGUI_API ImageButton(const nap::Texture2D &texture, const ImVec2 &size, const ImVec2 &uv0=ImVec2(0, 1), const ImVec2 &uv1=ImVec2(1, 0), int frame_padding=-1, const ImVec4 &bg_col=ImVec4(0, 0, 0, 0), const ImVec4 &tint_col=ImVec4(1, 1, 1, 1))
nap::sequenceguiclipboard::EventSegmentClipboard::getSequenceName
const std::string & getSequenceName() const
Definition: sequenceeventtrackview.h:268
nap::SequenceControllerEvent::insertEventSegment
const SequenceTrackSegment * insertEventSegment(const std::string &trackID, double time)
Definition: sequencecontrollerevent.h:90
nap::utility::ErrorState
Definition: errorstate.h:19
nap::SequenceTrackSegment
Definition: sequencetracksegment.h:19
nap::icon::cancel
constexpr const char * cancel
Definition: imguiservice.h:44
nap::icon::ok
constexpr const char * ok
Definition: imguiservice.h:45
nap::SequenceGUIService
Definition: sequenceguiservice.h:59
nap::SequenceEventTrackView
Definition: sequenceeventtrackview.h:144
nap::SequenceTrack
Definition: sequencetrack.h:22
nap::SequenceTrackSegment::mStartTime
double mStartTime
Property: 'Start time' start time of segment in track.
Definition: sequencetracksegment.h:38
nap::SequenceTrackSegmentEvent
Definition: sequencetracksegmentevent.h:39
nap::SequenceEventTrackSegmentView
Definition: sequenceeventtrackview.h:91
nap::sequenceguiclipboard::Clipboard
Definition: sequenceeditorguiclipboard.h:28
nap::sequenceguiactions::Action
Definition: sequenceeditorguiactions.h:26
nap::SequenceTrackView
Definition: sequencetrackview.h:30
nap::SequenceEditorGUIView
Definition: sequenceeditorgui.h:82
nap::SequenceEventTrackSegmentView::SequenceEventTrackSegmentView
SequenceEventTrackSegmentView()
Definition: sequenceeventtrackview.h:98
nap::convertTimeToMMSSMSArray
std::vector< int > NAPAPI convertTimeToMMSSMSArray(double time)
nap::sequenceguiactions::OpenEditEventSegmentPopup
Definition: sequenceeventtrackview_guiactions.h:40
nap::sequenceguiclipboard::EventSegmentClipboard
Definition: sequenceeventtrackview.h:258
nap::SequenceTrackSegmentEventBase
Definition: sequencetracksegmentevent.h:21
nap::SequenceControllerEvent::editEventSegment
void editEventSegment(const std::string &trackID, const std::string &segmentID, const T &value)
Definition: sequencecontrollerevent.h:117
nap
Definition: templateapp.h:17
nap::SequenceControllerEvent
Definition: sequencecontrollerevent.h:21
nap::sequenceguiclipboard::EventSegmentClipboard::EventSegmentClipboard
EventSegmentClipboard(const rttr::type &type, std::string sequenceName)
Definition: sequenceeventtrackview.h:263
nap::sequenceguiactions::EditingEventSegment
Definition: sequenceeventtrackview_guiactions.h:67
nap::SequenceEventTrackSegmentViewBase
Definition: sequenceeventtracksegmentviewbase.h:18
nap::SequenceEventTrackSegmentView::createEditAction
std::unique_ptr< sequenceguiactions::Action > createEditAction(const SequenceTrackSegmentEventBase *segment, const std::string &trackID, const std::string &segmentID) override
Definition: sequenceeventtrackview.h:387