implemented vertical "zooming" in the TimelineWidget and CurveView

This comes in the form of changing the vertical scale in the CurveView and
adjusting all track heights in the Timeline.
This commit is contained in:
itsmattkc
2019-12-31 00:23:28 +11:00
parent 441555e9f2
commit 2b24fae26f
22 changed files with 220 additions and 41 deletions
+10
View File
@@ -328,11 +328,21 @@ bool TrackOutput::IsTrack() const
return true;
}
int TrackOutput::GetTrackHeightIncrement()
{
return qApp->fontMetrics().height() / 2;
}
int TrackOutput::GetDefaultTrackHeight()
{
return qApp->fontMetrics().height() * 3;
}
int TrackOutput::GetTrackHeightMinimum()
{
return qApp->fontMetrics().height() * 3 / 2;
}
QString TrackOutput::GetDefaultTrackName(TrackType type, int index)
{
// Starts tracks at 1 rather than 0
+4
View File
@@ -120,8 +120,12 @@ public:
virtual bool IsTrack() const override;
static int GetTrackHeightIncrement();
static int GetDefaultTrackHeight();
static int GetTrackHeightMinimum();
static QString GetDefaultTrackName(TrackType type, int index);
bool IsMuted() const;
+10
View File
@@ -41,6 +41,16 @@ void CurvePanel::ZoomOut()
widget_->SetScale(widget_->GetScale() * 0.5);
}
void CurvePanel::IncreaseTrackHeight()
{
widget_->SetVerticalScale(widget_->GetVerticalScale() * 2);
}
void CurvePanel::DecreaseTrackHeight()
{
widget_->SetVerticalScale(widget_->GetVerticalScale() * 0.5);
}
void CurvePanel::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
+4
View File
@@ -21,6 +21,10 @@ public slots:
virtual void ZoomOut() override;
virtual void IncreaseTrackHeight() override;
virtual void DecreaseTrackHeight() override;
signals:
void TimeChanged(const int64_t& timestamp);
+10
View File
@@ -119,6 +119,16 @@ void TimelinePanel::DeleteSelected()
timeline_widget_->DeleteSelected();
}
void TimelinePanel::IncreaseTrackHeight()
{
timeline_widget_->IncreaseTrackHeight();
}
void TimelinePanel::DecreaseTrackHeight()
{
timeline_widget_->DecreaseTrackHeight();
}
void TimelinePanel::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
+4
View File
@@ -64,6 +64,10 @@ public:
virtual void DeleteSelected() override;
virtual void IncreaseTrackHeight() override;
virtual void DecreaseTrackHeight() override;
public slots:
void SetTimebase(const rational& timebase);
+39 -10
View File
@@ -8,7 +8,7 @@
CurveView::CurveView(QWidget *parent) :
KeyframeViewBase(parent)
{
setAlignment(Qt::AlignLeft | Qt::AlignBottom);
setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
setDragMode(RubberBandDrag);
setViewportUpdateMode(FullViewportUpdate);
SetYAxisEnabled(true);
@@ -181,6 +181,7 @@ void CurveView::drawBackground(QPainter *painter, const QRectF &rect)
void CurveView::KeyframeAboutToBeRemoved(NodeKeyframe *key)
{
disconnect(key, &NodeKeyframe::ValueChanged, this, &CurveView::KeyframeValueChanged);
disconnect(key, &NodeKeyframe::TypeChanged, this, &CurveView::KeyframeTypeChanged);
}
void CurveView::ScaleChangedEvent(double scale)
@@ -192,6 +193,15 @@ void CurveView::ScaleChangedEvent(double scale)
}
}
void CurveView::VerticalScaleChangedEvent(double scale)
{
QMap<NodeKeyframe*, KeyframeViewItem*>::const_iterator iterator;
for (iterator=item_map().begin();iterator!=item_map().end();iterator++) {
SetItemYFromKeyframeValue(iterator.value()->key().get(), iterator.value());
}
}
QList<NodeKeyframe *> CurveView::GetKeyframesSortedByTime()
{
QList<NodeKeyframe *> sorted;
@@ -234,6 +244,19 @@ QPointF CurveView::ScalePoint(const QPointF &point)
return QPointF(point.x() * scale_, - point.y() * y_scale_);
}
void CurveView::CreateBezierControlPoints(KeyframeViewItem* item)
{
BezierControlPointItem* bezier_in_pt = new BezierControlPointItem(item->key(), NodeKeyframe::kInHandle, item);
bezier_in_pt->SetXScale(scale_);
bezier_control_points_.append(bezier_in_pt);
connect(bezier_in_pt, &QObject::destroyed, this, &CurveView::BezierControlPointDestroyed, Qt::DirectConnection);
BezierControlPointItem* bezier_out_pt = new BezierControlPointItem(item->key(), NodeKeyframe::kOutHandle, item);
bezier_out_pt->SetXScale(scale_);
bezier_control_points_.append(bezier_out_pt);
connect(bezier_out_pt, &QObject::destroyed, this, &CurveView::BezierControlPointDestroyed, Qt::DirectConnection);
}
void CurveView::KeyframeValueChanged()
{
NodeKeyframe* key = static_cast<NodeKeyframe*>(sender());
@@ -242,6 +265,17 @@ void CurveView::KeyframeValueChanged()
SetItemYFromKeyframeValue(key, item);
}
void CurveView::KeyframeTypeChanged()
{
NodeKeyframe* key = static_cast<NodeKeyframe*>(sender());
KeyframeViewItem* item = item_map().value(key);
if (item->isSelected()) {
item->setSelected(false);
item->setSelected(true);
}
}
void CurveView::SelectionChanged()
{
// Clear current bezier handles
@@ -255,15 +289,9 @@ void CurveView::SelectionChanged()
foreach (QGraphicsItem* item, selected) {
KeyframeViewItem* this_item = static_cast<KeyframeViewItem*>(item);
BezierControlPointItem* bezier_in_pt = new BezierControlPointItem(this_item->key(), NodeKeyframe::kInHandle, item);
bezier_in_pt->SetXScale(scale_);
bezier_control_points_.append(bezier_in_pt);
connect(bezier_in_pt, &QObject::destroyed, this, &CurveView::BezierControlPointDestroyed, Qt::DirectConnection);
BezierControlPointItem* bezier_out_pt = new BezierControlPointItem(this_item->key(), NodeKeyframe::kOutHandle, item);
bezier_out_pt->SetXScale(scale_);
bezier_control_points_.append(bezier_out_pt);
connect(bezier_out_pt, &QObject::destroyed, this, &CurveView::BezierControlPointDestroyed, Qt::DirectConnection);
if (this_item->key()->type() == NodeKeyframe::kBezier) {
CreateBezierControlPoints(this_item);
}
}
}
@@ -279,4 +307,5 @@ void CurveView::AddKeyframe(NodeKeyframePtr key)
SetItemYFromKeyframeValue(key.get(), item);
connect(key.get(), &NodeKeyframe::ValueChanged, this, &CurveView::KeyframeValueChanged);
connect(key.get(), &NodeKeyframe::TypeChanged, this, &CurveView::KeyframeTypeChanged);
}
+6
View File
@@ -25,6 +25,8 @@ protected:
virtual void ScaleChangedEvent(double scale) override;
virtual void VerticalScaleChangedEvent(double scale) override;
private:
QList<NodeKeyframe*> GetKeyframesSortedByTime();
@@ -36,6 +38,8 @@ private:
void AdjustLines();
void CreateBezierControlPoints(KeyframeViewItem *item);
int text_padding_;
int minimum_grid_space_;
@@ -47,6 +51,8 @@ private:
private slots:
void KeyframeValueChanged();
void KeyframeTypeChanged();
void SelectionChanged();
void BezierControlPointDestroyed();
+10
View File
@@ -148,6 +148,16 @@ void CurveWidget::SetScale(const double &scale)
view_->SetScale(scale);
}
const double &CurveWidget::GetVerticalScale()
{
return view_->GetYScale();
}
void CurveWidget::SetVerticalScale(const double &vscale)
{
view_->SetYScale(vscale);
}
void CurveWidget::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
+3
View File
@@ -28,6 +28,9 @@ public:
const double& GetScale();
void SetScale(const double& scale);
const double& GetVerticalScale();
void SetVerticalScale(const double& vscale);
signals:
void TimeChanged(const int64_t& timestamp);
+15 -1
View File
@@ -33,10 +33,20 @@ void KeyframeViewBase::Clear()
item_map_.clear();
}
const double &KeyframeViewBase::GetYScale() const
{
return y_scale_;
}
void KeyframeViewBase::SetYScale(const double &y_scale)
{
y_scale_ = y_scale;
viewport()->update();
if (y_axis_enabled_) {
VerticalScaleChangedEvent(y_scale_);
viewport()->update();
}
}
void KeyframeViewBase::RemoveKeyframe(NodeKeyframePtr key)
@@ -188,6 +198,10 @@ void KeyframeViewBase::ScaleChangedEvent(double scale)
}
}
void KeyframeViewBase::VerticalScaleChangedEvent(double scale)
{
}
const QMap<NodeKeyframe *, KeyframeViewItem *> &KeyframeViewBase::item_map() const
{
return item_map_;
@@ -15,6 +15,7 @@ public:
virtual void Clear();
const double& GetYScale() const;
void SetYScale(const double& y_scale);
public slots:
@@ -29,6 +30,8 @@ protected:
virtual void ScaleChangedEvent(double scale) override;
virtual void VerticalScaleChangedEvent(double scale);
const QMap<NodeKeyframe*, KeyframeViewItem*>& item_map() const;
virtual void KeyframeAboutToBeRemoved(NodeKeyframe* key);
+12 -12
View File
@@ -32,9 +32,9 @@ NodeView::NodeView(QWidget *parent) :
setDragMode(RubberBandDrag);
setContextMenuPolicy(Qt::CustomContextMenu);
connect(&scene_, SIGNAL(changed(const QList<QRectF>&)), this, SLOT(ItemsChanged()));
connect(&scene_, SIGNAL(selectionChanged()), this, SLOT(SceneSelectionChangedSlot()));
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ShowContextMenu(const QPoint &)));
connect(&scene_, &QGraphicsScene::changed, this, &NodeView::ItemsChanged);
connect(&scene_, &QGraphicsScene::selectionChanged, this, &NodeView::SceneSelectionChangedSlot);
connect(this, &NodeView::customContextMenuRequested, this, &NodeView::ShowContextMenu);
}
NodeView::~NodeView()
@@ -50,10 +50,10 @@ void NodeView::SetGraph(NodeGraph *graph)
}
if (graph_ != nullptr) {
disconnect(graph_, SIGNAL(NodeAdded(Node*)), this, SLOT(AddNode(Node*)));
disconnect(graph_, SIGNAL(NodeRemoved(Node*)), this, SLOT(RemoveNode(Node*)));
disconnect(graph_, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(AddEdge(NodeEdgePtr)));
disconnect(graph_, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(RemoveEdge(NodeEdgePtr)));
disconnect(graph_, &NodeGraph::NodeAdded, this, &NodeView::AddNode);
disconnect(graph_, &NodeGraph::NodeRemoved, this, &NodeView::RemoveNode);
disconnect(graph_, &NodeGraph::EdgeAdded, this, &NodeView::AddEdge);
disconnect(graph_, &NodeGraph::EdgeRemoved, this, &NodeView::RemoveEdge);
}
// Clear the scene of all UI objects
@@ -64,10 +64,10 @@ void NodeView::SetGraph(NodeGraph *graph)
// If the graph is valid, add UI objects for each of its Nodes
if (graph_ != nullptr) {
connect(graph_, SIGNAL(NodeAdded(Node*)), this, SLOT(AddNode(Node*)));
connect(graph_, SIGNAL(NodeRemoved(Node*)), this, SLOT(RemoveNode(Node*)));
connect(graph_, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(AddEdge(NodeEdgePtr)));
connect(graph_, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(RemoveEdge(NodeEdgePtr)));
connect(graph_, &NodeGraph::NodeAdded, this, &NodeView::AddNode);
connect(graph_, &NodeGraph::NodeRemoved, this, &NodeView::RemoveNode);
connect(graph_, &NodeGraph::EdgeAdded, this, &NodeView::AddEdge);
connect(graph_, &NodeGraph::EdgeRemoved, this, &NodeView::RemoveEdge);
QList<Node*> graph_nodes = graph_->nodes();
@@ -233,7 +233,7 @@ void NodeView::ShowContextMenu(const QPoint &pos)
Menu* add_menu = NodeFactory::CreateMenu();
add_menu->setTitle(tr("Add"));
connect(add_menu, SIGNAL(triggered(QAction*)), this, SLOT(CreateNodeSlot(QAction*)));
connect(add_menu, &Menu::triggered, this, &NodeView::CreateNodeSlot);
m->addMenu(add_menu);
m->exec(mapToGlobal(pos));
+4
View File
@@ -108,6 +108,10 @@ public:
virtual void DeleteSelected(){}
virtual void IncreaseTrackHeight(){}
virtual void DecreaseTrackHeight(){}
protected:
/**
* @brief Set panel's title
@@ -473,6 +473,34 @@ void TimelineWidget::DeleteSelected()
Core::instance()->undo_stack()->pushIfHasChildren(command);
}
void TimelineWidget::IncreaseTrackHeight()
{
if (!timeline_node_) {
return;
}
QVector<TrackOutput*> all_tracks = timeline_node_->Tracks();
// Increase the height of each track by one "unit"
foreach (TrackOutput* t, all_tracks) {
t->SetTrackHeight(t->GetTrackHeight() + t->GetTrackHeightIncrement());
}
}
void TimelineWidget::DecreaseTrackHeight()
{
if (!timeline_node_) {
return;
}
QVector<TrackOutput*> all_tracks = timeline_node_->Tracks();
// Decrease the height of each track by one "unit"
foreach (TrackOutput* t, all_tracks) {
t->SetTrackHeight(qMax(t->GetTrackHeight() - t->GetTrackHeightIncrement(), t->GetTrackHeightMinimum()));
}
}
QList<TimelineViewBlockItem *> TimelineWidget::GetSelectedBlocks()
{
QList<TimelineViewBlockItem *> list;
@@ -54,6 +54,10 @@ public:
void DeleteSelected();
void IncreaseTrackHeight();
void DecreaseTrackHeight();
QList<TimelineViewBlockItem*> GetSelectedBlocks();
public slots:
@@ -61,8 +61,14 @@ void TrackViewSplitter::SetTrackHeight(int index, int h)
{
QList<int> element_sizes = sizes();
if (alignment_ == Qt::AlignBottom) {
index = count() - index - 1;
}
int old_ele_sz = element_sizes.at(index);
qDebug() << "Old ele sz" << old_ele_sz << "vs h" << h;
int diff = h - old_ele_sz;
// Set new size on element
@@ -45,6 +45,7 @@ TimelineView::TimelineView(const TrackType &type, Qt::Alignment vertical_alignme
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
setBackgroundRole(QPalette::Window);
setContextMenuPolicy(Qt::CustomContextMenu);
SetLimitYAxis(true);
}
void TimelineView::SelectAll()
@@ -10,7 +10,8 @@ TimelineViewBase::TimelineViewBase(QWidget *parent) :
QGraphicsView(parent),
playhead_(0),
playhead_scene_left_(-1),
playhead_scene_right_(-1)
playhead_scene_right_(-1),
limit_y_axis_(false)
{
setScene(&scene_);
@@ -111,28 +112,33 @@ void TimelineViewBase::UpdateSceneRect()
{
QRectF bounding_rect = scene_.itemsBoundingRect();
// Ensure the scene height is always AT LEAST the height of the view
// The scrollbar appears to have a 1px margin on the top and bottom, hence the -2
int minimum_height = height() - horizontalScrollBar()->height() - 2;
if (limit_y_axis_) {
// Ensure the scene height is always AT LEAST the height of the view
// The scrollbar appears to have a 1px margin on the top and bottom, hence the -2
int minimum_height = height() - horizontalScrollBar()->height() - 2;
if (alignment() & Qt::AlignBottom) {
// Ensure the scene left and bottom are always 0
bounding_rect.setBottomLeft(QPointF(0, 0));
if (alignment() & Qt::AlignBottom) {
// Ensure the scene left and bottom are always 0
bounding_rect.setBottomLeft(QPointF(0, 0));
if (bounding_rect.top() > minimum_height) {
bounding_rect.setTop(-minimum_height);
if (bounding_rect.top() > minimum_height) {
bounding_rect.setTop(-minimum_height);
}
} else {
// Ensure the scene left and top are always 0
bounding_rect.setTopLeft(QPointF(0, 0));
if (bounding_rect.height() < minimum_height) {
bounding_rect.setHeight(minimum_height);
}
}
} else {
// Ensure the scene left and top are always 0
bounding_rect.setTopLeft(QPointF(0, 0));
if (bounding_rect.height() < minimum_height) {
bounding_rect.setHeight(minimum_height);
}
// We'll still limit the X to 0 since that behavior is desired by all TimelineViewBase derivatives
bounding_rect.setLeft(0);
}
// Ensure the scene is always the full length of the timeline with a gap at the end to work with
end_item_->SetEndPadding(width()/4);
end_item_->SetEndPadding(width()/2);
// If the scene is already this rect, do nothing
if (scene_.sceneRect() == bounding_rect) {
@@ -153,3 +159,9 @@ void TimelineViewBase::ScaleChangedEvent(double scale)
{
Q_UNUSED(scale)
}
void TimelineViewBase::SetLimitYAxis(bool e)
{
limit_y_axis_ = true;
UpdateSceneRect();
}
@@ -34,6 +34,8 @@ protected:
virtual void ScaleChangedEvent(double scale);
void SetLimitYAxis(bool e);
rational GetPlayheadTime();
bool PlayheadPress(QMouseEvent* event);
@@ -54,6 +56,8 @@ private:
QGraphicsScene scene_;
bool limit_y_axis_;
private slots:
/**
* @brief Slot called whenever the view resizes or the scene contents change to enforce minimum scene sizes
+12 -2
View File
@@ -92,8 +92,8 @@ MainMenu::MainMenu(QMainWindow *parent) :
view_menu_ = new Menu(this, this, SLOT(ViewMenuAboutToShow()));
view_zoom_in_item_ = view_menu_->AddItem("zoomin", this, SLOT(ZoomInTriggered()), "=");
view_zoom_out_item_ = view_menu_->AddItem("zoomout", this, SLOT(ZoomOutTriggered()), "-");
view_increase_track_height_item_ = view_menu_->AddItem("vzoomin", nullptr, nullptr, "Ctrl+=");
view_decrease_track_height_item_ = view_menu_->AddItem("vzoomout", nullptr, nullptr, "Ctrl+-");
view_increase_track_height_item_ = view_menu_->AddItem("vzoomin", this, SLOT(IncreaseTrackHeightTriggered()), "Ctrl+=");
view_decrease_track_height_item_ = view_menu_->AddItem("vzoomout", this, SLOT(DecreaseTrackHeightTriggered()), "Ctrl+-");
view_show_all_item_ = view_menu_->AddItem("showall", nullptr, nullptr, "\\");
view_show_all_item_->setCheckable(true);
view_menu_->addSeparator();
@@ -416,6 +416,16 @@ void MainMenu::ZoomOutTriggered()
PanelManager::instance()->CurrentlyFocused()->ZoomOut();
}
void MainMenu::IncreaseTrackHeightTriggered()
{
PanelManager::instance()->CurrentlyFocused()->IncreaseTrackHeight();
}
void MainMenu::DecreaseTrackHeightTriggered()
{
PanelManager::instance()->CurrentlyFocused()->DecreaseTrackHeight();
}
void MainMenu::GoToStartTriggered()
{
PanelManager::instance()->CurrentlyFocused()->GoToStart();
+3
View File
@@ -104,6 +104,9 @@ private slots:
*/
void ZoomOutTriggered();
void IncreaseTrackHeightTriggered();
void DecreaseTrackHeightTriggered();
void GoToStartTriggered();
void PrevFrameTriggered();