From 3837d7c461074f3bcffeb1f15977444bd86591b0 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 8 Apr 2019 22:16:47 +1000 Subject: [PATCH] foundational node UI work --- olive.pro | 10 +- panels/effectcontrols.cpp | 328 ++++++-------------------------------- panels/effectcontrols.h | 27 +--- panels/effectspanel.cpp | 269 +++++++++++++++++++++++++++++++ panels/effectspanel.h | 41 +++++ panels/nodeeditor.cpp | 23 ++- panels/nodeeditor.h | 12 +- panels/panels.cpp | 1 + ui/nodeui.cpp | 55 +++++++ ui/nodeui.h | 21 +++ ui/nodeview.cpp | 20 ++- ui/nodeview.h | 3 + ui/nodewidget.cpp | 46 ++++++ ui/nodewidget.h | 20 +++ 14 files changed, 565 insertions(+), 311 deletions(-) create mode 100644 panels/effectspanel.cpp create mode 100644 panels/effectspanel.h create mode 100644 ui/nodeui.cpp create mode 100644 ui/nodeui.h create mode 100644 ui/nodewidget.cpp create mode 100644 ui/nodewidget.h diff --git a/olive.pro b/olive.pro index c55c3bb6c..107c4e3d8 100644 --- a/olive.pro +++ b/olive.pro @@ -188,7 +188,10 @@ SOURCES += \ panels/nodeeditor.cpp \ ui/nodeview.cpp \ nodes/medianode.cpp \ - nodes/node.cpp + nodes/node.cpp \ + ui/nodeui.cpp \ + ui/nodewidget.cpp \ + panels/effectspanel.cpp HEADERS += \ ui/mainwindow.h \ @@ -333,7 +336,10 @@ HEADERS += \ panels/nodeeditor.h \ ui/nodeview.h \ nodes/medianode.h \ - nodes/node.h + nodes/node.h \ + ui/nodeui.h \ + ui/nodewidget.h \ + panels/effectspanel.h FORMS += diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 2321572a2..da37c1ef0 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -56,7 +56,7 @@ #include "ui/menu.h" EffectControls::EffectControls(QWidget *parent) : - Panel(parent), + EffectsPanel(parent), zoom(1) { setup_ui(); @@ -81,11 +81,6 @@ EffectControls::EffectControls(QWidget *parent) : connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), verticalScrollBar, SLOT(setValue(int))); } -EffectControls::~EffectControls() -{ - Clear(true); -} - void EffectControls::set_zoom(bool in) { zoom *= (in) ? 2 : 0.5; update_keyframes(); @@ -144,55 +139,10 @@ void EffectControls::delete_selected_keyframes() { keyframeView->delete_selected_keyframes(); } -void EffectControls::copy(bool del) { - bool cleared = false; - - ComboAction* ca = nullptr; - if (del) { - ca = new ComboAction(); - } - - for (int i=0;iIsSelected()) { - Effect* e = open_effects_.at(i)->GetEffect(); - - if (e->meta->type == EFFECT_TYPE_EFFECT) { - - if (!cleared) { - olive::clipboard.Clear(); - cleared = true; - olive::clipboard.SetType(Clipboard::CLIPBOARD_TYPE_EFFECT); - } - - olive::clipboard.Append(e->copy(nullptr)); - - if (del) { - - DeleteEffect(ca, e); - - } - - } - } - } - - if (del) { - if (ca->hasActions()) { - olive::undo_stack.push(ca); - } else { - delete ca; - } - } -} - void EffectControls::scroll_to_frame(long frame) { scroll_to_frame_internal(horizontalScrollBar, frame - keyframeView->visible_in, zoom, keyframeView->width()); } -void EffectControls::cut() { - copy(true); -} - void EffectControls::show_effect_menu(int type, Track::Type subtype) { effect_menu_type = type; effect_menu_subtype = subtype; @@ -263,63 +213,6 @@ void EffectControls::show_effect_menu(int type, Track::Type subtype) { effects_menu.exec(QCursor::pos()); } -void EffectControls::Clear(bool clear_cache) { - // clear existing clips - deselect_all_effects(nullptr); - - for (int i=0;iSetEffects(open_effects_); - - vcontainer->setVisible(false); - acontainer->setVisible(false); - headers->setVisible(false); - keyframeView->setEnabled(false); - - if (clear_cache) { - selected_clips_.clear(); - } - - UpdateTitle(); -} - -bool EffectControls::IsEffectSelected(Effect *e) -{ - for (int i=0;iGetEffect() == e && open_effects_.at(i)->IsSelected()) { - return true; - } - } - return false; -} - -void EffectControls::deselect_all_effects(QWidget* sender) { - - for (int i=0;iheader_click(false, false); - } - } - - if (panel_sequence_viewer != nullptr) { - panel_sequence_viewer->viewer_widget()->update(); - } -} - -void EffectControls::open_effect(QVBoxLayout* layout, Effect* e) { - EffectUI* container = new EffectUI(e); - - connect(container, SIGNAL(CutRequested()), this, SLOT(cut())); - connect(container, SIGNAL(CopyRequested()), this, SLOT(copy())); - connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); - - open_effects_.append(container); - - layout->addWidget(container); -} - void EffectControls::UpdateTitle() { if (selected_clips_.isEmpty()) { setWindowTitle(panel_name + tr("(none)")); @@ -544,59 +437,6 @@ void EffectControls::effects_area_context_menu() { menu.exec(QCursor::pos()); } -void EffectControls::DeleteEffect(ComboAction* ca, Effect* effect_ref) { - if (effect_ref->meta->type == EFFECT_TYPE_EFFECT) { - - ca->append(new EffectDeleteCommand(effect_ref)); - - } else if (effect_ref->meta->type == EFFECT_TYPE_TRANSITION) { - - // Retrieve shared ptr for this transition - - Clip* attached_clip = effect_ref->parent_clip; - - TransitionPtr t = nullptr; - - if (attached_clip->opening_transition.get() == effect_ref) { - - t = attached_clip->opening_transition; - - } else if (attached_clip->closing_transition.get() == effect_ref) { - - t = attached_clip->closing_transition; - - } - - if (t == nullptr) { - - qWarning() << "Failed to delete transition, couldn't find clip link."; - - } else { - - ca->append(new DeleteTransitionCommand(t)); - - } - - } -} - -void EffectControls::DeleteSelectedEffects() { - ComboAction* ca = new ComboAction(); - - for (int i=0;iIsSelected()) { - DeleteEffect(ca, open_effects_.at(i)->GetEffect()); - } - } - - if (ca->hasActions()) { - olive::undo_stack.push(ca); - update_ui(true); - } else { - delete ca; - } -} - bool EffectControls::focused() { if (this->hasFocus() @@ -605,124 +445,7 @@ bool EffectControls::focused() return true; } - for (int i=0;iIsFocused()) { - return true; - } - } - - return false; -} - -void EffectControls::Reload() { - Clear(false); - Load(); -} - -void EffectControls::SetClips() -{ - Clear(true); - - Sequence* top_sequence = Timeline::GetTopSequence().get(); - - if (top_sequence == nullptr) { - selected_clips_.clear(); - } else { - // replace clip vector - selected_clips_ = top_sequence->SelectedClips(false); - - Load(); - } -} - -void EffectControls::Load() { - bool graph_editor_row_is_still_active = false; - - // load in new clips - for (int i=0;itype() == Track::kTypeVideo) { - vcontainer->setVisible(true); - layout = video_effect_layout; - } else if (c->type() == Track::kTypeAudio) { - acontainer->setVisible(true); - layout = audio_effect_layout; - } - - // Create a list of the effects we'll open - QVector effects_to_open; - - // Determine based on the current selections whether to load all effects or just the transitions - bool whole_clip_is_selected = c->IsSelected(); - - if (whole_clip_is_selected) { - for (int j=0;jeffects.size();j++) { - effects_to_open.append(c->effects.at(j).get()); - } - } - if (c->opening_transition != nullptr - && (whole_clip_is_selected || c->track()->IsTransitionSelected(c->opening_transition.get()))) { - effects_to_open.append(c->opening_transition.get()); - } - if (c->closing_transition != nullptr - && (whole_clip_is_selected || c->track()->IsTransitionSelected(c->closing_transition.get()))) { - effects_to_open.append(c->closing_transition.get()); - } - - for (int j=0;jGetEffect()->meta == effects_to_open.at(j)->meta - && !open_effects_.at(k)->IsAttachedToClip(c)) { - - open_effects_.at(k)->AddAdditionalEffect(effects_to_open.at(j)); - - already_opened = true; - - break; - } - } - - if (!already_opened) { - open_effect(layout, effects_to_open.at(j)); - } - - // Check if one of the open effects contains the row currently active in the graph editor. If not, we'll have - // to clear the graph editor later. - if (!graph_editor_row_is_still_active) { - for (int k=0;krow_count();k++) { - EffectRow* row = effects_to_open.at(j)->row(k); - if (row == panel_graph_editor->get_row()) { - graph_editor_row_is_still_active = true; - break; - } - } - } - } - } - - keyframeView->SetEffects(open_effects_); - - if (selected_clips_.size() > 0) { - keyframeView->setEnabled(true); - - headers->setVisible(true); - - QTimer::singleShot(50, this, SLOT(queue_post_update())); - } - - // If the graph editor's currently active row is not part of the current effects, clear it - if (!graph_editor_row_is_still_active) { - panel_graph_editor->set_row(nullptr); - } - - UpdateTitle(); - update_keyframes(); + return EffectsPanel::focused(); } void EffectControls::video_effect_click() { @@ -745,6 +468,53 @@ void EffectControls::resizeEvent(QResizeEvent*) { update_scrollbar(); } +void EffectControls::ClearEvent() +{ + keyframeView->SetEffects(open_effects_); + + vcontainer->setVisible(false); + acontainer->setVisible(false); + headers->setVisible(false); + keyframeView->setEnabled(false); + + UpdateTitle(); +} + +void EffectControls::LoadEvent() +{ + keyframeView->SetEffects(open_effects_); + + if (selected_clips_.size() > 0) { + keyframeView->setEnabled(true); + + headers->setVisible(true); + + QTimer::singleShot(50, this, SLOT(queue_post_update())); + } + + for (int i=0;iGetEffect(); + + if (e->meta->subtype == Track::kTypeVideo) { + vcontainer->setVisible(true); + layout = video_effect_layout; + } else if (e->meta->subtype == Track::kTypeAudio) { + acontainer->setVisible(true); + layout = audio_effect_layout; + } + + if (layout != nullptr) { + layout->addWidget(container); + } + } + + UpdateTitle(); + update_keyframes(); +} + EffectsArea::EffectsArea(QWidget* parent) : QWidget(parent) {} diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h index aefd75ffa..fabe93116 100644 --- a/panels/effectcontrols.h +++ b/panels/effectcontrols.h @@ -37,7 +37,7 @@ #include "ui/keyframeview.h" #include "ui/resizablescrollbar.h" #include "ui/keyframeview.h" -#include "ui/panel.h" +#include "effectspanel.h" #include "ui/effectui.h" class EffectsArea : public QWidget { @@ -53,21 +53,12 @@ public slots: void receive_wheel_event(QWheelEvent* e); }; -class EffectControls : public Panel +class EffectControls : public EffectsPanel { Q_OBJECT public: explicit EffectControls(QWidget *parent = nullptr); - virtual ~EffectControls() override; - - void Reload(); - void SetClips(); - void Clear(bool clear_cache = true); - - bool IsEffectSelected(Effect* e); - - void DeleteSelectedEffects(); virtual bool focused() override; void set_zoom(bool in); void delete_selected_keyframes(); @@ -83,8 +74,6 @@ public: virtual void LoadLayoutState(const QByteArray& data) override; virtual QByteArray SaveLayoutState() override; public slots: - void cut(); - void copy(bool del = false); void update_keyframes(); private slots: void menu_select(QAction* q); @@ -94,7 +83,7 @@ private slots: void video_transition_click(); void audio_transition_click(); - void deselect_all_effects(QWidget*); + void update_scrollbar(); void queue_post_update(); @@ -102,17 +91,11 @@ private slots: void effects_area_context_menu(); protected: virtual void resizeEvent(QResizeEvent *event) override; + virtual void ClearEvent() override; + virtual void LoadEvent() override; private: - QVector selected_clips_; - QVector open_effects_; - - void Load(); - - void DeleteEffect(ComboAction* ca, Effect* effect_ref); - void show_effect_menu(int type, Track::Type subtype); void load_keyframes(); - void open_effect(QVBoxLayout* hlayout, Effect *e); void UpdateTitle(); void setup_ui(); diff --git a/panels/effectspanel.cpp b/panels/effectspanel.cpp new file mode 100644 index 000000000..a901deb83 --- /dev/null +++ b/panels/effectspanel.cpp @@ -0,0 +1,269 @@ +#include "effectspanel.h" + +#include "timeline.h" +#include "global/clipboard.h" +#include "panels.h" + +EffectsPanel::EffectsPanel(QWidget *parent) : + Panel(parent) +{ + +} + +EffectsPanel::~EffectsPanel() +{ + Clear(true); +} + +void EffectsPanel::Clear(bool clear_cache) { + // clear existing clips + deselect_all_effects(nullptr); + + for (int i=0;iIsFocused()) { + return true; + } + } + + return Panel::focused(); +} + +void EffectsPanel::ClearEvent() {} + +void EffectsPanel::LoadEvent() {} + +void EffectsPanel::Reload() { + Clear(false); + Load(); +} + +void EffectsPanel::SetClips() +{ + Clear(true); + + Sequence* top_sequence = Timeline::GetTopSequence().get(); + + if (top_sequence == nullptr) { + selected_clips_.clear(); + } else { + // replace clip vector + selected_clips_ = top_sequence->SelectedClips(false); + + Load(); + } +} + +void EffectsPanel::Load() { + bool graph_editor_row_is_still_active = false; + + // load in new clips + for (int i=0;i effects_to_open; + + // Determine based on the current selections whether to load all effects or just the transitions + bool whole_clip_is_selected = c->IsSelected(); + + if (whole_clip_is_selected) { + for (int j=0;jeffects.size();j++) { + effects_to_open.append(c->effects.at(j).get()); + } + } + if (c->opening_transition != nullptr + && (whole_clip_is_selected || c->track()->IsTransitionSelected(c->opening_transition.get()))) { + effects_to_open.append(c->opening_transition.get()); + } + if (c->closing_transition != nullptr + && (whole_clip_is_selected || c->track()->IsTransitionSelected(c->closing_transition.get()))) { + effects_to_open.append(c->closing_transition.get()); + } + + for (int j=0;jGetEffect()->meta == effects_to_open.at(j)->meta + && !open_effects_.at(k)->IsAttachedToClip(c)) { + + open_effects_.at(k)->AddAdditionalEffect(effects_to_open.at(j)); + + already_opened = true; + + break; + } + } + + if (!already_opened) { + open_effect(effects_to_open.at(j)); + } + + // Check if one of the open effects contains the row currently active in the graph editor. If not, we'll have + // to clear the graph editor later. + if (!graph_editor_row_is_still_active) { + for (int k=0;krow_count();k++) { + EffectRow* row = effects_to_open.at(j)->row(k); + if (row == panel_graph_editor->get_row()) { + graph_editor_row_is_still_active = true; + break; + } + } + } + } + } + + // If the graph editor's currently active row is not part of the current effects, clear it + if (!graph_editor_row_is_still_active) { + panel_graph_editor->set_row(nullptr); + } + + LoadEvent(); +} + +bool EffectsPanel::IsEffectSelected(Effect *e) +{ + for (int i=0;iGetEffect() == e && open_effects_.at(i)->IsSelected()) { + return true; + } + } + return false; +} + +void EffectsPanel::deselect_all_effects(QWidget* sender) { + + for (int i=0;iheader_click(false, false); + } + } + + if (panel_sequence_viewer != nullptr) { + panel_sequence_viewer->viewer_widget()->update(); + } +} + +void EffectsPanel::cut() { + copy(true); +} + +void EffectsPanel::copy(bool del) { + bool cleared = false; + + ComboAction* ca = nullptr; + if (del) { + ca = new ComboAction(); + } + + for (int i=0;iIsSelected()) { + Effect* e = open_effects_.at(i)->GetEffect(); + + if (e->meta->type == EFFECT_TYPE_EFFECT) { + + if (!cleared) { + olive::clipboard.Clear(); + cleared = true; + olive::clipboard.SetType(Clipboard::CLIPBOARD_TYPE_EFFECT); + } + + olive::clipboard.Append(e->copy(nullptr)); + + if (del) { + + DeleteEffect(ca, e); + + } + + } + } + } + + if (del) { + if (ca->hasActions()) { + olive::undo_stack.push(ca); + } else { + delete ca; + } + } +} + +void EffectsPanel::DeleteEffect(ComboAction* ca, Effect* effect_ref) { + if (effect_ref->meta->type == EFFECT_TYPE_EFFECT) { + + ca->append(new EffectDeleteCommand(effect_ref)); + + } else if (effect_ref->meta->type == EFFECT_TYPE_TRANSITION) { + + // Retrieve shared ptr for this transition + + Clip* attached_clip = effect_ref->parent_clip; + + TransitionPtr t = nullptr; + + if (attached_clip->opening_transition.get() == effect_ref) { + + t = attached_clip->opening_transition; + + } else if (attached_clip->closing_transition.get() == effect_ref) { + + t = attached_clip->closing_transition; + + } + + if (t == nullptr) { + + qWarning() << "Failed to delete transition, couldn't find clip link."; + + } else { + + ca->append(new DeleteTransitionCommand(t)); + + } + + } +} + +void EffectsPanel::DeleteSelectedEffects() { + ComboAction* ca = new ComboAction(); + + for (int i=0;iIsSelected()) { + DeleteEffect(ca, open_effects_.at(i)->GetEffect()); + } + } + + if (ca->hasActions()) { + olive::undo_stack.push(ca); + update_ui(true); + } else { + delete ca; + } +} + +void EffectsPanel::open_effect(Effect* e) { + EffectUI* container = new EffectUI(e); + + connect(container, SIGNAL(CutRequested()), this, SLOT(cut())); + connect(container, SIGNAL(CopyRequested()), this, SLOT(copy())); + connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*))); + + open_effects_.append(container); +} diff --git a/panels/effectspanel.h b/panels/effectspanel.h new file mode 100644 index 000000000..cb1617b7a --- /dev/null +++ b/panels/effectspanel.h @@ -0,0 +1,41 @@ +#ifndef EFFECTSPANEL_H +#define EFFECTSPANEL_H + +#include "ui/panel.h" +#include "ui/effectui.h" +#include "timeline/clip.h" + +class EffectsPanel : public Panel +{ + Q_OBJECT +public: + explicit EffectsPanel(QWidget *parent = nullptr); + virtual ~EffectsPanel() override; + + void Reload(); + void SetClips(); + void Clear(bool clear_cache = true); + + virtual bool focused() override; + + bool IsEffectSelected(Effect* e); + void DeleteSelectedEffects(); + +public slots: + void cut(); + void copy(bool del = false); +protected: + virtual void ClearEvent(); + virtual void LoadEvent(); + + QVector selected_clips_; + QVector open_effects_; +private: + void Load(); + void open_effect(Effect *e); + void DeleteEffect(ComboAction* ca, Effect* effect_ref); +private slots: + void deselect_all_effects(QWidget*); +}; + +#endif // EFFECTSPANEL_H diff --git a/panels/nodeeditor.cpp b/panels/nodeeditor.cpp index 1eb5906d8..3ea682bea 100644 --- a/panels/nodeeditor.cpp +++ b/panels/nodeeditor.cpp @@ -3,9 +3,11 @@ #include #include #include +#include +#include NodeEditor::NodeEditor(QWidget *parent) : - Panel(parent), + EffectsPanel(parent), view_(&scene_) { resize(720, 480); @@ -18,12 +20,25 @@ NodeEditor::NodeEditor(QWidget *parent) : view_.setInteractive(true); view_.setDragMode(QGraphicsView::RubberBandDrag); - - QPushButton* push_button = new QPushButton("heck!!!"); - scene_.addWidget(push_button); + connect(&view_, SIGNAL(ScrollChanged(qreal, qreal)), this, SLOT(Scroll(qreal, qreal))); } void NodeEditor::Retranslate() { } + +void NodeEditor::LoadEvent() +{ + for (int i=0;imoveBy(x, y); + } +} diff --git a/panels/nodeeditor.h b/panels/nodeeditor.h index eaf77c586..b395fbc0b 100644 --- a/panels/nodeeditor.h +++ b/panels/nodeeditor.h @@ -3,19 +3,27 @@ #include -#include "ui/panel.h" +#include "effectspanel.h" #include "ui/nodeview.h" +#include "ui/nodeui.h" -class NodeEditor : public Panel { +class NodeEditor : public EffectsPanel { Q_OBJECT public: NodeEditor(QWidget* parent = nullptr); virtual void Retranslate() override; +protected: + virtual void LoadEvent() override; + private: QGraphicsScene scene_; NodeView view_; + QVector nodes_; + +private slots: + void Scroll(qreal x, qreal y); }; diff --git a/panels/panels.cpp b/panels/panels.cpp index 60ec67816..2145e7478 100644 --- a/panels/panels.cpp +++ b/panels/panels.cpp @@ -41,6 +41,7 @@ NodeEditor* panel_node_editor = nullptr; void update_ui(bool modified) { if (modified) { panel_effect_controls->SetClips(); + panel_node_editor->SetClips(); } panel_effect_controls->update_keyframes(); for (int i=0;i +#include +#include +#include +#include +#include +#include +#include +#include + +NodeUI::NodeUI() : + central_widget_(this) +{ + setFlag(QGraphicsItem::ItemIsMovable, true); + setFlag(QGraphicsItem::ItemIsSelectable, true); +} + +void NodeUI::AddToScene(QGraphicsScene *scene) +{ + scene->addItem(this); + + QGraphicsProxyWidget* proxy = scene->addWidget(¢ral_widget_); + proxy->setPos(pos()); + proxy->setParentItem(this); +} + +void NodeUI::Resize(const QSize &s) +{ + QRectF rectangle = rect(); + + rectangle.setSize(s); + + setRect(rectangle); +} + +void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + QPalette palette = qApp->palette(); + + if (option->state & QStyle::State_Selected) { + painter->setPen(palette.highlight().color()); + } else { + painter->setPen(palette.base().color()); + } + painter->setBrush(palette.window()); + + QRectF r = rect(); + r.setX(r.x() - 1); + r.setY(r.y() - 1); + r.setRight(r.right() + 1); + r.setBottom(r.bottom() + 1); + painter->drawRect(r); +} diff --git a/ui/nodeui.h b/ui/nodeui.h new file mode 100644 index 000000000..47e410125 --- /dev/null +++ b/ui/nodeui.h @@ -0,0 +1,21 @@ +#ifndef NODEUI_H +#define NODEUI_H + +#include +#include + +#include "ui/nodewidget.h" + +class NodeUI : public QGraphicsRectItem { +public: + NodeUI(); + void AddToScene(QGraphicsScene* scene); + void Resize(const QSize& s); +protected: + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; + +private: + NodeWidget central_widget_; +}; + +#endif // NODEUI_H diff --git a/ui/nodeview.cpp b/ui/nodeview.cpp index 16593f328..db20fb80a 100644 --- a/ui/nodeview.cpp +++ b/ui/nodeview.cpp @@ -9,20 +9,36 @@ NodeView::NodeView(QGraphicsScene *scene, QWidget *parent) : { setMouseTracking(true); setWindowTitle(tr("Node Editor")); + + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } void NodeView::mousePressEvent(QMouseEvent *event) { - QGraphicsView::mousePressEvent(event); + if (event->button() == Qt::RightButton) { + hand_moving_ = true; + drag_start_ = event->pos(); + } else { + QGraphicsView::mousePressEvent(event); + } } void NodeView::mouseMoveEvent(QMouseEvent *event) { - QGraphicsView::mouseMoveEvent(event); + if (hand_moving_) { + QPointF scene_delta = mapToScene(event->pos() - drag_start_) - mapToScene(0.0, 0.0); + emit ScrollChanged(scene_delta.x(), scene_delta.y()); + drag_start_ = event->pos(); + } else { + QGraphicsView::mouseMoveEvent(event); + } } void NodeView::mouseReleaseEvent(QMouseEvent *event) { + hand_moving_ = false; + QGraphicsView::mouseReleaseEvent(event); } void NodeView::wheelEvent(QWheelEvent *event) diff --git a/ui/nodeview.h b/ui/nodeview.h index bd751aa4c..61ef0ccdb 100644 --- a/ui/nodeview.h +++ b/ui/nodeview.h @@ -8,6 +8,9 @@ class NodeView : public QGraphicsView { public: NodeView(QGraphicsScene *scene, QWidget* parent = nullptr); +signals: + void ScrollChanged(qreal x, qreal y); + protected: virtual void mousePressEvent(QMouseEvent *event) override; virtual void mouseMoveEvent(QMouseEvent *event) override; diff --git a/ui/nodewidget.cpp b/ui/nodewidget.cpp new file mode 100644 index 000000000..6a4c3fa07 --- /dev/null +++ b/ui/nodewidget.cpp @@ -0,0 +1,46 @@ +#include "nodewidget.h" + +#include +#include +#include +#include +#include +#include + +#include "ui/nodeui.h" + +NodeWidget::NodeWidget(NodeUI *parent) : + parent_(parent) +{ + QVBoxLayout* layout = new QVBoxLayout(this); + + QLabel* title = new QLabel("Node"); + layout->addWidget(title); + + QGridLayout* grid_layout = new QGridLayout(); + + grid_layout->addWidget(new QLabel("Option 1"), 0, 0); + grid_layout->addWidget(new QLineEdit("Value 1"), 0, 1); + + grid_layout->addWidget(new QLabel("Option 2"), 1, 0); + grid_layout->addWidget(new QLineEdit("Value 2"), 1, 1); + + layout->addLayout(grid_layout); +} + +void NodeWidget::resizeEvent(QResizeEvent *event) +{ + parent_->Resize(event->size()); +} + +bool NodeWidget::event(QEvent *event) +{ + if ((event->type() == QEvent::MouseButtonPress + || event->type() == QEvent::MouseButtonRelease + || event->type() == QEvent::MouseMove + || event->type() == QEvent::MouseButtonDblClick) + && parent_->scene()->sendEvent(parent_, event)) { + return true; + } + return QWidget::event(event); +} diff --git a/ui/nodewidget.h b/ui/nodewidget.h new file mode 100644 index 000000000..16271563f --- /dev/null +++ b/ui/nodewidget.h @@ -0,0 +1,20 @@ +#ifndef NODEWIDGET_H +#define NODEWIDGET_H + +#include + +class NodeUI; + +class NodeWidget : public QWidget +{ + Q_OBJECT +public: + NodeWidget(NodeUI *parent); +protected: + virtual void resizeEvent(QResizeEvent *event) override; + virtual bool event(QEvent *event) override; +private: + NodeUI* parent_; +}; + +#endif // NODEWIDGET_H