8 #include "sequencecurvetrackview_guiactions.h" 
    9 #include "sequenceguiutils.h" 
   12 #include <imguiutils.h> 
   20         assert(action!= 
nullptr);
 
   24             ImGui::OpenPopup(
"Curve Point Actions");
 
   25             action->mOpened = 
true;
 
   28         if(ImGui::BeginPopup(
"Curve Point Actions"))
 
   30             int curveIndex = action->mCurveIndex;
 
   32             float value = action->mValue * (action->mMaximum[curveIndex] - action->mMinimum[curveIndex]) +
 
   33                           action->mMinimum[curveIndex];
 
   34             if(ImGui::InputFloat(
"value", &value))
 
   40                     action->mControlPointIndex,
 
   56             const auto *segment = 
static_cast<const SequenceTrackSegmentDuration*
>(curve_controller.getSegment(action->mTrackID, action->mSegmentID));
 
   57             assert(segment != 
nullptr);
 
   59             double time = action->mTime * segment->mDuration + segment->mStartTime;
 
   60             double min_time = segment->mStartTime;
 
   61             double max_time = segment->mStartTime + segment->mDuration;
 
   65             bool edit_time = 
false;
 
   70             edit_time = ImGui::InputInt3(
"Time (mm:ss:ms)", &time_array[0]);
 
   71             time_array[0] = math::clamp<int>(time_array[0], 0, 99999);
 
   72             time_array[1] = math::clamp<int>(time_array[1], 0, 59);
 
   73             time_array[2] = math::clamp<int>(time_array[2], 0, 99);
 
   78                 new_time = 
math::clamp(new_time, min_time, max_time);
 
   80                 float perc = (new_time - segment->mStartTime) / segment->mDuration;
 
   85                     action->mControlPointIndex,
 
   99                     action->mControlPointIndex,
 
  100                     action->mCurveIndex);
 
  104                 mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  107                 ImGui::CloseCurrentPopup();
 
  114                 mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  115                 ImGui::CloseCurrentPopup();
 
  122             mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  131         assert(action!= 
nullptr);
 
  135             ImGui::OpenPopup(
"Segment Value Actions");
 
  136             action->mOpened = 
true;
 
  139         if(ImGui::BeginPopup(
"Segment Value Actions"))
 
  141             int curveIndex = action->mCurveIndex;
 
  143             if(action->mTakeSnapshot)
 
  145                 action->mTakeSnapshot = 
false;
 
  150                 action->mValue[curveIndex] * (action->mMaximum[curveIndex] - action->mMinimum[curveIndex]) +
 
  151                 action->mMinimum[curveIndex];
 
  152             if(ImGui::InputFloat(
"value", &value))
 
  154                 float translated_value = (value - action->mMinimum[curveIndex]) /
 
  155                                          (action->mMaximum[curveIndex] - action->mMinimum[curveIndex]);
 
  170                 mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  172                 ImGui::CloseCurrentPopup();
 
  179             mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  188             const ImVec2& trackTopLeft,
 
  189             const float previousSegmentX,
 
  190             const float segmentWidth,
 
  191             const float segmentX,
 
  192             ImDrawList* drawList)
 
  197         bool needs_drawing = ImGui::IsRectVisible({trackTopLeft.x + previousSegmentX, trackTopLeft.y}, {
 
  198             trackTopLeft.x + previousSegmentX + segmentWidth, trackTopLeft.y + track_height});
 
  205                 const long point_num = (int) (points_per_pixel * segmentWidth);
 
  206                 std::vector<std::vector<ImVec2>> curves;
 
  207                 for(
int v = 0; v < segment.mCurves.size(); v++)
 
  209                     std::vector<ImVec2> curve;
 
  212                         auto start_x = math::max<float>(trackTopLeft.x, 0);
 
  218                             for(; i <= point_num; i++)
 
  220                                 float p = (float) i / (
float) point_num;
 
  221                                 float x = trackTopLeft.x + previousSegmentX + segmentWidth * p;
 
  224                                     float value = 1.0f - segment.mCurves[v]->evaluate(p);
 
  229                                             trackTopLeft.y + value * track_height
 
  231                                     curve.emplace_back(point);
 
  242                     curves.emplace_back(std::move(curve));
 
  244                 mCurveCache.emplace(segment.mID, std::move(curves));
 
  248         int selected_curve = -1;
 
  254                && ImGui::IsMouseHoveringRect(
 
  255                 {trackTopLeft.x + segmentX - segmentWidth, trackTopLeft.y}, 
 
  256                 {trackTopLeft.x + segmentX, trackTopLeft.y + track_height}))  
 
  259                 ImVec2 mouse_pos = ImGui::GetMousePos();
 
  261                     ((mouse_pos.x - (trackTopLeft.x + segmentX - segmentWidth)) / 
mState.
mStepSize) / segment.mDuration;
 
  262                 float y_in_segment = 1.0f - ((mouse_pos.y - trackTopLeft.y) / track_height);
 
  264                 for(
int i = 0; i < segment.mCurves.size(); i++)
 
  267                     float y_in_curve = segment.mCurves[i]->evaluate(x_in_segment);
 
  270                     const float maxDist = 0.1f;
 
  271                     if(std::abs(y_in_curve - y_in_segment) < maxDist)
 
  273                         mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::HoveringCurve>(
 
  278                         if(ImGui::IsMouseClicked(1))
 
  280                             mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::InsertingCurvePoint>(
 
  289                 if(selected_curve == -1)
 
  291                     mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  296                         segment, x_in_segment,
 
  305                     if(action->mSegmentID == segment.mID)
 
  307                         mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  315             for(
int i = 0; i < segment.mCurves.size(); i++)
 
  319                     float thickness = selected_curve == i ? 3.0f : 1.0f;
 
  321                     drawList->AddPolyline
 
  339             const ImVec2& trackTopLeft,
 
  340             float previousSegmentX,
 
  343             ImDrawList* drawList,
 
  350         bool draw_selection_background = 
false;
 
  354             draw_selection_background = action->
mSegmentID == segment.
mID;
 
  358             draw_selection_background = action->
mSegmentID == segment.
mID;
 
  362             draw_selection_background = action->
mSegmentID == segment.
mID;
 
  366             draw_selection_background = action->
mSegmentID == segment.
mID;
 
  370             draw_selection_background = action->
mSegmentID == segment.
mID;
 
  377         drawList->AddRectFilled(
 
  378                 { trackTopLeft.x + segmentX - segmentWidth, trackTopLeft.y }, 
 
  380                 ImGui::ColorConvertFloat4ToU32(curve_segment.mColor)); 
 
  382         if(draw_selection_background)
 
  384             drawList->AddRectFilled(
 
  385                 {trackTopLeft.x + segmentX - segmentWidth, trackTopLeft.y}, 
 
  386                 {trackTopLeft.x + segmentX, trackTopLeft.y + track_height}, 
 
  387                 ImGui::ColorConvertFloat4ToU32(ImVec4(1, 1, 1, 0.25f))); 
 
  401                     drawList->AddRectFilled
 
  403                             {trackTopLeft.x + segmentX - segmentWidth, trackTopLeft.y}, 
 
  404                             {trackTopLeft.x + segmentX, trackTopLeft.y + track_height},  
 
  405                             ImGui::ColorConvertFloat4ToU32(red) 
 
  423         drawControlPoints<T>(
 
  442                 sequencecurveenums::ESegmentValueTypes::BEGIN,
 
  453             sequencecurveenums::ESegmentValueTypes::END,
 
  463         T min = curve_track.mMinimum;
 
  464         T max = curve_track.mMaximum;
 
  467         ImGui::PushID(track.
mID.c_str());
 
  469         float drag_float_x = ImGui::GetCursorPosX() + (40.0f * 
mState.
mScale);
 
  470         ImGui::SetCursorPos({ImGui::GetCursorPosX() + offset, ImGui::GetCursorPosY() + offset});
 
  473         ImGui::PushID(
"min");
 
  474         ImGui::SetCursorPosX(drag_float_x);
 
  475         if(inputFloat<T>(min, 3))
 
  477             mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::ChangeMinMaxCurve<T>>(track.
mID, min, max);
 
  480         ImGui::PopItemWidth();
 
  481         ImGui::SetCursorPosX(ImGui::GetCursorPosX() + offset);
 
  484         ImGui::PushID(
"max");
 
  485         ImGui::SetCursorPosX(drag_float_x);
 
  486         if(inputFloat<T>(max, 3))
 
  488             mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::ChangeMinMaxCurve<T>>(track.
mID, min, max);
 
  491         ImGui::PopItemWidth();
 
  500             const ImVec2& trackTopLeft,
 
  501             const float segmentX,
 
  502             const float segmentWidth,
 
  504             ImDrawList* drawList)
 
  534         for(
int v = 0; v < segment.mCurves.size(); v++)
 
  537             ImVec2 segment_value_pos =
 
  541                                                               (
float) segment.mCurves[v]->mPoints[0].mPos.mValue :
 
  542                                                               (
float) segment.mCurves[v]->mPoints[
 
  543                                                                   segment.mCurves[v]->mPoints.size() - 1].mPos.mValue) /
 
  547             bool hovered = 
false;
 
  556                    ImGui::IsMouseHoveringRect(
 
  563                     mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::HoveringSegmentValue>(
 
  569                     if(ImGui::IsMouseDown(0))
 
  571                         mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::DraggingSegmentValue>(
 
  576                             get_value_map[RTTI_OF(T)](segment, v, segmentType));
 
  577                     } 
else if(ImGui::IsMouseDown(1))
 
  582                         mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::EditingSegmentCurveValue<T>>(
 
  587                             (segmentType == sequencecurveenums::ESegmentValueTypes::BEGIN)
 
  588                             ? curve_segment.getStartValue() : curve_segment.getEndValue(),
 
  589                             curve_track.mMinimum,
 
  590                             curve_track.mMaximum);
 
  606                         if(action->mType == segmentType &&
 
  607                            action->mSegmentID == segment.mID &&
 
  608                            action->mCurveIndex == v)
 
  610                             mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  627                     if(action->mSegmentID == segment.mID)
 
  629                         if(action->mType == segmentType && action->mCurveIndex == v)
 
  641                             float value = get_value_map[RTTI_OF(T)](segment, v, segmentType) + drag_amount;
 
  643                             action->mNewValue = value;
 
  662             const ImVec2& trackTopLeft,
 
  663             const float segmentX,
 
  664             const float segmentWidth,
 
  665             ImDrawList* drawList)
 
  672         if(track.
mSegments[0]->mID == segment.mID)
 
  674             for(
int v = 0; v < segment.mCurves.size(); v++)
 
  676                 const auto &curve_point = segment.mCurves[v]->mPoints[0];
 
  677                 std::ostringstream string_stream;
 
  678                 string_stream << segment.mID << 
"_point_" << 0 << 
"_curve_" << v;
 
  680                 ImVec2 circle_point =
 
  681                     {(trackTopLeft.x + segmentX - segmentWidth) + segmentWidth * curve_point.mPos.mTime,
 
  682                      trackTopLeft.y + track_height * (1.0f - (
float) curve_point.mPos.mValue)};
 
  689                         segment, string_stream,
 
  690                         segmentWidth, curve_point, circle_point,
 
  693                         sequencecurveenums::ETanPointTypes::IN,
 
  698                         segment, string_stream,
 
  699                         segmentWidth, curve_point, circle_point,
 
  702                         sequencecurveenums::ETanPointTypes::OUT,
 
  710         for(
int v = 0; v < segment.mCurves.size(); v++)
 
  712             for(
int i = 1; i < segment.mCurves[v]->mPoints.size() - 1; i++)
 
  715                 const auto &curve_point = segment.mCurves[v]->mPoints[i];
 
  716                 std::ostringstream string_stream;
 
  717                 string_stream << segment.mID << 
"_point_" << i << 
"_curve_" << v;
 
  718                 std::string point_id = string_stream.str();
 
  721                 ImVec2 circle_point =
 
  722                     {(trackTopLeft.x + segmentX - segmentWidth) + segmentWidth * curve_point.mPos.mTime,
 
  723                      trackTopLeft.y + track_height * (1.0f - (
float) curve_point.mPos.mValue)};
 
  726                 bool hovered = 
false;
 
  733                        && ImGui::IsMouseHoveringRect({circle_point.x - offset, circle_point.y - offset},
 
  734                                                      {circle_point.x + offset, circle_point.y + offset}))
 
  743                     mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::HoveringControlPoint>(
 
  752                         segment, curve_point.mPos.mTime,
 
  753                         curve_point.mPos.mTime * segment.mDuration + segment.mStartTime,
 
  757                     if(ImGui::IsMouseDown(0))
 
  759                         mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::DraggingControlPoint>(
 
  764                             curve_point.mPos.mTime,
 
  765                             curve_point.mPos.mValue);
 
  768                     else if(ImGui::IsMouseClicked(1))
 
  770                         mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::CurvePointActionPopup<T>>(
 
  775                             curve_point.mPos.mValue,
 
  776                             curve_point.mPos.mTime,
 
  786                         if(action->mControlPointIndex == i && track.
mID == action->mTrackID &&
 
  787                            segment.mID == action->mSegmentID && v == action->mCurveIndex)
 
  789                             mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  801                         if(action->mSegmentID == segment.mID)
 
  803                             if(action->mControlPointIndex == i && action->mCurveIndex == v)
 
  812                                     segment, curve_point.mPos.mTime,
 
  813                                     curve_point.mPos.mTime * segment.mDuration + segment.mStartTime,
 
  816                                 action->mNewValue += value_adjust;
 
  817                                 action->mNewTime += time_adjust;
 
  824                 drawList->AddCircleFilled
 
  835                         segment, string_stream,
 
  836                         segmentWidth, curve_point, circle_point,
 
  839                         sequencecurveenums::ETanPointTypes::IN,
 
  844                         segment, string_stream,
 
  845                         segmentWidth, curve_point, circle_point,
 
  848                         sequencecurveenums::ETanPointTypes::OUT,
 
  854         for(
int v = 0; v < segment.mCurves.size(); v++)
 
  858             const int control_point_index = segment.mCurves[v]->mPoints.size() - 1;
 
  859             const auto &curve_point = segment.mCurves[v]->mPoints[control_point_index];
 
  861             std::ostringstream string_stream;
 
  862             string_stream << segment.mID << 
"_point_" << control_point_index << 
"_curve_" << v;
 
  863             std::string point_id = string_stream.str();
 
  865             ImVec2 circle_point =
 
  866                 {(trackTopLeft.x + segmentX - segmentWidth) + segmentWidth * curve_point.mPos.mTime,
 
  867                  trackTopLeft.y + track_height * (1.0f - (
float) curve_point.mPos.mValue)};
 
  873                     segment, string_stream,
 
  874                     segmentWidth, curve_point, circle_point, control_point_index,
 
  876                     sequencecurveenums::ETanPointTypes::IN,
 
  881                     segment, string_stream,
 
  882                     segmentWidth, curve_point, circle_point, control_point_index,
 
  884                     sequencecurveenums::ETanPointTypes::OUT,
 
  890         ImGui::SetCursorPosY(ImGui::GetCursorPosY() - track_height);
 
  898             std::ostringstream& stringStream,
 
  899             const float segmentWidth,
 
  901             const ImVec2& circlePoint,
 
  902             const int controlPointIndex,
 
  903             const int curveIndex,
 
  905             ImDrawList* drawList)
 
  912             std::ostringstream tan_stream;
 
  913             tan_stream << stringStream.str() << ((type == sequencecurveenums::ETanPointTypes::IN) ? 
"inTan" : 
"outTan");
 
  921             ImVec2 offset = {tan_complex.
mTime * tan_constant_size,
 
  922                              static_cast<float>(tan_complex.
mValue) * -1.0f * tan_constant_size};
 
  923             ImVec2 tan_point = {circlePoint.x + offset.x, circlePoint.y + offset.y};
 
  926             bool tan_point_hovered = 
false;
 
  932                 if((
mState.
mAction->template isAction<sequenceguiactions::None>() ||
 
  933                     mState.
mAction->template isAction<sequenceguiactions::HoveringCurve>() ||
 
  934                     mState.
mAction->template isAction<sequenceguiactions::HoveringSegment>())
 
  935                    && ImGui::IsMouseHoveringRect
 
  937                            {tan_point.x - tan_bounds, tan_point.y - tan_bounds},
 
  938                            {tan_point.x + tan_bounds, tan_point.y + tan_bounds})
 
  941                     mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::HoveringTanPoint>(track.
mID, tan_stream.str());
 
  942                     tan_point_hovered = 
true;
 
  948                     if(action->mTanPointID == tan_stream.str())
 
  950                         if(ImGui::IsMouseHoveringRect(
 
  951                             {tan_point.x - tan_bounds, tan_point.y - tan_bounds},
 
  952                             {tan_point.x + tan_bounds, tan_point.y + tan_bounds}))
 
  955                             tan_point_hovered = 
true;
 
  958                             if(ImGui::IsMouseDown(0))
 
  960                                 mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::DraggingTanPoint>(
 
  966                             } 
else if(ImGui::IsMouseDown(1)) 
 
  968                                 mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::EditingTanPointPopup>(
 
  974                                     (
float) tan_complex.mValue,
 
  980                             mState.
mAction = sequenceguiactions::createAction<sequenceguiactions::None>();
 
  990                     if(action->mSegmentID == segment.
mID &&
 
  991                        action->mControlPointIndex == controlPointIndex &&
 
  992                        action->mType == type &&
 
  993                        action->mCurveIndex == curveIndex)
 
  995                         tan_point_hovered = 
true;
 
 1004                         if(type == sequencecurveenums::ETanPointTypes::IN)
 
 1007                                 curve_segment.
mCurves[curveIndex]->mPoints[controlPointIndex].mInTan.mTime + delta_time;
 
 1008                             new_value = curve_segment.mCurves[curveIndex]->mPoints[controlPointIndex].mInTan.mValue +
 
 1012                             new_time = curve_segment.
mCurves[curveIndex]->mPoints[controlPointIndex].mOutTan.mTime +
 
 1014                             new_value = curve_segment.mCurves[curveIndex]->mPoints[controlPointIndex].mOutTan.mValue +
 
 1018                         action->mNewTime = new_time;
 
 1019                         action->mNewValue = new_value;
 
 1036     template<
typename T>
 
 1037     bool SequenceCurveTrackView::pasteClipboardSegments(
const std::string &trackId, 
double time, 
utility::ErrorState &errorState)
 
 1043         std::vector<std::unique_ptr<rtti::Object>> read_objects;
 
 1046         std::vector<T *> curve_segments = curve_segment_clipboard->
deserialize<T>(read_objects, errorState);
 
 1050             nap::Logger::error(errorState.
toString());
 
 1054             assert(curve_segments.size() > 0); 
 
 1057             std::sort(curve_segments.begin(), curve_segments.end(), [](T *a, T *b)
 
 1059                 return a->mStartTime < b->mStartTime;
 
 1063             if(curve_segments.size() > 0)
 
 1065                 curve_segments[0]->mStartTime = 0.0;
 
 1067             for(
int i = 1; i < curve_segments.size(); i++)
 
 1069                 curve_segments[i]->mStartTime = curve_segments[i - 1]->mStartTime + curve_segments[i - 1]->mDuration;
 
 1073             for(
auto curve_segment: curve_segments)
 
 1076                 auto *base_controller = getEditor().getControllerWithTrackID(trackId);
 
 1079                 assert(base_controller != 
nullptr);
 
 1082                 assert(base_controller->get_type().template is_derived_from<SequenceControllerCurve>());
 
 1086                 const auto *new_segment = curve_controller->
insertSegment(trackId, time + curve_segment->mStartTime);
 
 1089                 curve_controller->changeSegmentLabel(trackId, new_segment->mID, curve_segment->mLabel);
 
 1092                 curve_controller->segmentDurationChange(trackId, new_segment->mID, curve_segment->mDuration, 
true);
 
 1095                 updateSegmentsInClipboard(trackId);
 
 1098                 for(
int c = 0; c < curve_segment->mCurves.size(); c++)
 
 1100                     for(
int i = 1; i < curve_segment->mCurves[c]->mPoints.size() - 1; i++)
 
 1102                         curve_controller->insertCurvePoint(trackId, new_segment->mID, curve_segment->mCurves[c]->mPoints[i].mPos.mTime, c);
 
 1105                     curve_controller->changeCurveType(trackId, new_segment->mID, curve_segment->mCurveTypes[c], c);
 
 1110                 for(
int c = 0; c < curve_segment->mCurves.size(); c++)
 
 1112                     for(
int i = 0; i < curve_segment->mCurves[c]->mPoints.size(); i++)
 
 1114                         curve_controller->changeCurvePoint(trackId, new_segment->mID, i, c,
 
 1115                                                            curve_segment->mCurves[c]->mPoints[i].mPos.mTime,
 
 1116                                                            curve_segment->mCurves[c]->mPoints[i].mPos.mValue);
 
 1118                         curve_controller->changeTanPoint(trackId, new_segment->mID, i, c, sequencecurveenums::IN,
 
 1119                                                          curve_segment->mCurves[c]->mPoints[i].mInTan.mTime,
 
 1120                                                          curve_segment->mCurves[c]->mPoints[i].mInTan.mValue);
 
 1125                 curve_controller->updateCurveSegments(trackId);
 
 1128                 updateSegmentsInClipboard(trackId);
 
 1136     template<
typename T>
 
 1137     void SequenceCurveTrackView::pasteClipboardSegmentInto(
const std::string& trackId, 
const std::string& segmentId)
 
 1143         assert(curve_segment_clipboard->getObjectCount() == 1);
 
 1146         std::vector<std::unique_ptr<rtti::Object>> read_objects;
 
 1147         std::vector<T *> curve_segments;
 
 1151         curve_segments = curve_segment_clipboard->deserialize<T>(read_objects, errorState);
 
 1155             T *curve_segment = curve_segments[0];
 
 1157             assert(curve_segment != 
nullptr); 
 
 1163             const auto *target_segment = curve_controller.
getSegment(trackId, segmentId);
 
 1166             assert(target_segment->get_type().template is_derived_from<T>()); 
 
 1167             const T *target_segment_upcast = 
static_cast<const T *
>(target_segment);
 
 1170             for(
size_t c = 0; c < target_segment_upcast->mCurves.size(); c++)
 
 1172                 for(
size_t p = 1; p < target_segment_upcast->mCurves[c]->mPoints.size() - 1; p++)
 
 1174                     curve_controller.deleteCurvePoint(trackId, segmentId, p, c);
 
 1179             curve_controller.segmentDurationChange(trackId, target_segment_upcast->mID, curve_segment->mDuration, 
true);
 
 1182             for(
int c = 0; c < curve_segment->mCurves.size(); c++)
 
 1184                 for(
int i = 1; i < curve_segment->mCurves[c]->mPoints.size() - 1; i++)
 
 1186                     curve_controller.insertCurvePoint(trackId, target_segment_upcast->mID, curve_segment->mCurves[c]->mPoints[i].mPos.mTime, c);
 
 1189                 curve_controller.changeCurveType(trackId, target_segment_upcast->mID, curve_segment->mCurveTypes[c], c);
 
 1194             for(
int c = 0; c < curve_segment->mCurves.size(); c++)
 
 1196                 for(
int i = 0; i < curve_segment->mCurves[c]->mPoints.size(); i++)
 
 1198                     curve_controller.changeCurvePoint(trackId, target_segment_upcast->mID, i, c,
 
 1199                                                       curve_segment->mCurves[c]->mPoints[i].mPos.mTime,
 
 1200                                                       curve_segment->mCurves[c]->mPoints[i].mPos.mValue);
 
 1202                     curve_controller.changeTanPoint(trackId, target_segment_upcast->mID, i, c, sequencecurveenums::IN,
 
 1203                                                     curve_segment->mCurves[c]->mPoints[i].mInTan.mTime,
 
 1204                                                     curve_segment->mCurves[c]->mPoints[i].mInTan.mValue);
 
 1209             curve_controller.updateCurveSegments(trackId);
 
 1212             updateSegmentsInClipboard(trackId);
 
 1215             nap::Logger::error(errorState.
toString());
 
 1220     template<
typename T>
 
 1221     void SequenceCurveTrackView::handleChangeMinMaxCurve()
 
 1224         auto *action = mState.mAction->template getDerived<sequenceguiactions::ChangeMinMaxCurve<T>>();
 
 1227         getEditor().takeSnapshot(action->get_type());
 
 1230         auto &controller = getEditor().template getController<SequenceControllerCurve>();
 
 1231         controller.template changeMinMaxCurveTrack<T>(action->mTrackID, action->mNewMin, action->mNewMax);
 
 1234         mState.mDirty = 
true;
 
 1237         mState.mAction = sequenceguiactions::createAction<sequenceguiactions::None>();