add functions to select or zoom to fit keyframes of a single input
This commit is contained in:
@@ -102,6 +102,34 @@ void CurveView::DisconnectInput(NodeInput *input, int element, int track)
|
||||
connected_inputs_.removeOne(ref);
|
||||
}
|
||||
|
||||
void CurveView::SelectKeyframesOf(NodeInput *input, int element, int track)
|
||||
{
|
||||
DeselectAll();
|
||||
|
||||
for (auto it=item_map().cbegin(); it!=item_map().cend(); it++) {
|
||||
if (it.key()->parent() == input
|
||||
&& it.key()->element() == element
|
||||
&& it.key()->track() == track) {
|
||||
it.value()->setSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CurveView::ZoomToFitInput(NodeInput *input, int element, int track)
|
||||
{
|
||||
QList<NodeKeyframe*> keys;
|
||||
|
||||
for (auto it=item_map().cbegin(); it!=item_map().cend(); it++) {
|
||||
if (it.key()->parent() == input
|
||||
&& it.key()->element() == element
|
||||
&& it.key()->track() == track) {
|
||||
keys.append(it.key());
|
||||
}
|
||||
}
|
||||
|
||||
ZoomToFitInternal(keys);
|
||||
}
|
||||
|
||||
void CurveView::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
if (timebase().isNull()) {
|
||||
@@ -293,7 +321,48 @@ void CurveView::ContextMenuEvent(Menu &m)
|
||||
QAction* zoom_fit_action = m.addAction(tr("Zoom to Fit"));
|
||||
connect(zoom_fit_action, &QAction::triggered, this, &CurveView::ZoomToFit);
|
||||
|
||||
//QAction* reset_zoom_action = m.addAction(tr("Reset Zoom"));
|
||||
QAction* zoom_fit_selected_action = m.addAction(tr("Zoom to Fit Selected"));
|
||||
connect(zoom_fit_selected_action, &QAction::triggered, this, &CurveView::ZoomToFitSelected);
|
||||
|
||||
QAction* reset_zoom_action = m.addAction(tr("Reset Zoom"));
|
||||
connect(reset_zoom_action, &QAction::triggered, this, &CurveView::ResetZoom);
|
||||
}
|
||||
|
||||
void CurveView::ZoomToFitInternal(const QList<NodeKeyframe *> &keys)
|
||||
{
|
||||
if (keys.isEmpty()) {
|
||||
// Prevent scaling to DBL_MIN/DBL_MAX
|
||||
return;
|
||||
}
|
||||
|
||||
rational min_time = RATIONAL_MAX;
|
||||
rational max_time = RATIONAL_MIN;
|
||||
|
||||
double min_val = DBL_MAX;
|
||||
double max_val = DBL_MIN;
|
||||
|
||||
for (auto i=item_map().constBegin(); i!=item_map().constEnd(); i++) {
|
||||
rational transformed_time = GetAdjustedTime(i.key()->parent()->parent(),
|
||||
GetTimeTarget(),
|
||||
i.key()->time(),
|
||||
false);
|
||||
|
||||
min_time = qMin(transformed_time, min_time);
|
||||
max_time = qMax(transformed_time, max_time);
|
||||
|
||||
min_val = qMin(i.key()->value().toDouble(), min_val);
|
||||
max_val = qMax(i.key()->value().toDouble(), max_val);
|
||||
}
|
||||
|
||||
double time_range = max_time.toDouble() - min_time.toDouble();
|
||||
double new_x_scale = CalculateScaleFromDimensions(this->width(), time_range);
|
||||
double new_y_scale = CalculateScaleFromDimensions(this->height(), max_val - min_val);
|
||||
|
||||
emit ScaleChanged(new_x_scale);
|
||||
SetYScale(new_y_scale);
|
||||
|
||||
horizontalScrollBar()->setValue(TimeToScene(min_time) - CalculatePaddingFromDimensionScale(this->width()));
|
||||
verticalScrollBar()->setValue(GetItemYFromKeyframeValue(max_val) - CalculatePaddingFromDimensionScale(this->height()));
|
||||
}
|
||||
|
||||
qreal CurveView::GetItemYFromKeyframeValue(NodeKeyframe *key)
|
||||
@@ -377,39 +446,26 @@ void CurveView::BezierControlPointDestroyed()
|
||||
|
||||
void CurveView::ZoomToFit()
|
||||
{
|
||||
if (item_map().isEmpty()) {
|
||||
// Prevent scaling to DBL_MIN/DBL_MAX
|
||||
return;
|
||||
ZoomToFitInternal(item_map().keys());
|
||||
}
|
||||
|
||||
void CurveView::ZoomToFitSelected()
|
||||
{
|
||||
QList<NodeKeyframe*> selected_keys;
|
||||
|
||||
for (auto it=item_map().cbegin(); it!=item_map().cend(); it++) {
|
||||
if (it.value()->isSelected()) {
|
||||
selected_keys.append(it.key());
|
||||
}
|
||||
}
|
||||
|
||||
rational min_time = RATIONAL_MAX;
|
||||
rational max_time = RATIONAL_MIN;
|
||||
ZoomToFitInternal(selected_keys);
|
||||
}
|
||||
|
||||
double min_val = DBL_MAX;
|
||||
double max_val = DBL_MIN;
|
||||
|
||||
for (auto i=item_map().constBegin(); i!=item_map().constEnd(); i++) {
|
||||
rational transformed_time = GetAdjustedTime(i.key()->parent()->parent(),
|
||||
GetTimeTarget(),
|
||||
i.key()->time(),
|
||||
false);
|
||||
|
||||
min_time = qMin(transformed_time, min_time);
|
||||
max_time = qMax(transformed_time, max_time);
|
||||
|
||||
min_val = qMin(i.key()->value().toDouble(), min_val);
|
||||
max_val = qMax(i.key()->value().toDouble(), max_val);
|
||||
}
|
||||
|
||||
double time_range = max_time.toDouble() - min_time.toDouble();
|
||||
double new_x_scale = CalculateScaleFromDimensions(this->width(), time_range);
|
||||
double new_y_scale = CalculateScaleFromDimensions(this->height(), max_val - min_val);
|
||||
|
||||
emit ScaleChanged(new_x_scale);
|
||||
SetYScale(new_y_scale);
|
||||
|
||||
horizontalScrollBar()->setValue(TimeToScene(min_time) - CalculatePaddingFromDimensionScale(this->width()));
|
||||
verticalScrollBar()->setValue(GetItemYFromKeyframeValue(max_val) - CalculatePaddingFromDimensionScale(this->height()));
|
||||
void CurveView::ResetZoom()
|
||||
{
|
||||
SetScale(1.0);
|
||||
SetYScale(1.0);
|
||||
}
|
||||
|
||||
void CurveView::AddKeyframe(NodeKeyframe* key)
|
||||
|
||||
@@ -42,11 +42,19 @@ public:
|
||||
|
||||
void DisconnectInput(NodeInput* input, int element, int track);
|
||||
|
||||
void SelectKeyframesOf(NodeInput* input, int element, int track);
|
||||
|
||||
void ZoomToFitInput(NodeInput* input, int element, int track);
|
||||
|
||||
public slots:
|
||||
void AddKeyframe(NodeKeyframe* key);
|
||||
|
||||
void ZoomToFit();
|
||||
|
||||
void ZoomToFitSelected();
|
||||
|
||||
void ResetZoom();
|
||||
|
||||
protected:
|
||||
virtual void drawBackground(QPainter* painter, const QRectF& rect) override;
|
||||
|
||||
@@ -61,6 +69,8 @@ protected:
|
||||
virtual void ContextMenuEvent(Menu &m) override;
|
||||
|
||||
private:
|
||||
void ZoomToFitInternal(const QList<NodeKeyframe *> &keys);
|
||||
|
||||
qreal GetItemYFromKeyframeValue(NodeKeyframe* key);
|
||||
qreal GetItemYFromKeyframeValue(double value);
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ CurveWidget::CurveWidget(QWidget *parent) :
|
||||
connect(tree_view_, &NodeTreeView::NodeEnableChanged, this, &CurveWidget::NodeEnabledChanged);
|
||||
connect(tree_view_, &NodeTreeView::InputEnableChanged, this, &CurveWidget::InputEnabledChanged);
|
||||
connect(tree_view_, &NodeTreeView::InputSelectionChanged, this, &CurveWidget::InputSelectionChanged);
|
||||
connect(tree_view_, &NodeTreeView::InputDoubleClicked, this, &CurveWidget::InputDoubleClicked);
|
||||
splitter->addWidget(tree_view_);
|
||||
|
||||
QWidget* workarea = new QWidget();
|
||||
@@ -359,9 +360,16 @@ void CurveWidget::RemoveKeyframe(NodeKeyframe *key)
|
||||
|
||||
void CurveWidget::InputSelectionChanged(NodeInput *input, int element, int track)
|
||||
{
|
||||
Q_UNUSED(track)
|
||||
|
||||
key_control_->SetInput(input, element);
|
||||
|
||||
if (input) {
|
||||
view_->SelectKeyframesOf(input, element, track);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveWidget::InputDoubleClicked(NodeInput *input, int element, int track)
|
||||
{
|
||||
view_->ZoomToFitInput(input, element, track);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -104,6 +104,8 @@ private slots:
|
||||
|
||||
void InputSelectionChanged(NodeInput* input, int element, int track);
|
||||
|
||||
void InputDoubleClicked(NodeInput* input, int element, int track);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -82,11 +82,43 @@ void NodeTreeView::changeEvent(QEvent *e)
|
||||
}
|
||||
}
|
||||
|
||||
void NodeTreeView::mouseDoubleClickEvent(QMouseEvent *e)
|
||||
{
|
||||
QTreeWidget::mouseDoubleClickEvent(e);
|
||||
|
||||
NodeInput::KeyframeTrackReference ref = GetSelectedInput();
|
||||
|
||||
if (ref.input) {
|
||||
emit InputDoubleClicked(ref.input, ref.element, ref.track);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeTreeView::Retranslate()
|
||||
{
|
||||
setHeaderLabel(tr("Nodes"));
|
||||
}
|
||||
|
||||
NodeInput::KeyframeTrackReference NodeTreeView::GetSelectedInput()
|
||||
{
|
||||
QList<QTreeWidgetItem*> sel = selectedItems();
|
||||
|
||||
NodeInput* selected_input = nullptr;
|
||||
int selected_element = -1;
|
||||
int selected_track = -1;
|
||||
|
||||
if (!sel.isEmpty()) {
|
||||
QTreeWidgetItem* item = sel.first();
|
||||
|
||||
if (item->data(0, kItemType).toInt() == kItemTypeInput) {
|
||||
selected_input = reinterpret_cast<NodeInput*>(item->data(0, kItemPointer).value<quintptr>());
|
||||
selected_element = item->data(0, kItemElement).toInt();
|
||||
selected_track = item->data(0, kItemTrack).toInt();
|
||||
}
|
||||
}
|
||||
|
||||
return {selected_input, selected_element, selected_track};
|
||||
}
|
||||
|
||||
QTreeWidgetItem* NodeTreeView::CreateItem(QTreeWidgetItem *parent, NodeInput *input, int element, int track)
|
||||
{
|
||||
QTreeWidgetItem* input_item = new QTreeWidgetItem(parent);
|
||||
@@ -166,23 +198,9 @@ void NodeTreeView::ItemCheckStateChanged(QTreeWidgetItem *item, int column)
|
||||
|
||||
void NodeTreeView::SelectionChanged()
|
||||
{
|
||||
QList<QTreeWidgetItem*> sel = selectedItems();
|
||||
NodeInput::KeyframeTrackReference ref = GetSelectedInput();
|
||||
|
||||
NodeInput* selected_input = nullptr;
|
||||
int selected_element = -1;
|
||||
int selected_track = -1;
|
||||
|
||||
if (!sel.isEmpty()) {
|
||||
QTreeWidgetItem* item = sel.first();
|
||||
|
||||
if (item->data(0, kItemType).toInt() == kItemTypeInput) {
|
||||
selected_input = reinterpret_cast<NodeInput*>(item->data(0, kItemPointer).value<quintptr>());
|
||||
selected_element = item->data(0, kItemElement).toInt();
|
||||
selected_track = item->data(0, kItemTrack).toInt();
|
||||
}
|
||||
}
|
||||
|
||||
emit InputSelectionChanged(selected_input, selected_element, selected_track);
|
||||
emit InputSelectionChanged(ref.input, ref.element, ref.track);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,12 +37,18 @@ signals:
|
||||
|
||||
void InputSelectionChanged(NodeInput* input, int element, int track);
|
||||
|
||||
void InputDoubleClicked(NodeInput* input, int element, int track);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent* e) override;
|
||||
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent* e) override;
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
|
||||
NodeInput::KeyframeTrackReference GetSelectedInput();
|
||||
|
||||
QTreeWidgetItem *CreateItem(QTreeWidgetItem* parent, NodeInput* input, int element, int track);
|
||||
|
||||
enum ItemType {
|
||||
|
||||
Reference in New Issue
Block a user