From 501564fb2228b3d6d263dbf0a9cd6603625f8ac5 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 10 May 2022 18:07:17 -0700 Subject: [PATCH] ui: replace html edit in text node with edit in viewer button --- app/node/generator/text/textv3.cpp | 1 + app/panel/param/param.cpp | 1 + app/panel/param/param.h | 2 + app/panel/viewer/viewerbase.h | 5 + app/widget/nodeparamview/nodeparamview.cpp | 10 ++ app/widget/nodeparamview/nodeparamview.h | 4 + .../nodeparamview/nodeparamviewitem.cpp | 2 + app/widget/nodeparamview/nodeparamviewitem.h | 4 + .../nodeparamview/nodeparamviewtextedit.cpp | 24 +++- .../nodeparamview/nodeparamviewtextedit.h | 9 ++ .../nodeparamviewwidgetbridge.cpp | 10 ++ .../nodeparamview/nodeparamviewwidgetbridge.h | 2 + app/widget/viewer/viewer.h | 5 + app/widget/viewer/viewerdisplay.cpp | 117 +++++++++++------- app/widget/viewer/viewerdisplay.h | 5 + app/window/mainwindow/mainwindow.cpp | 1 + 16 files changed, 148 insertions(+), 54 deletions(-) diff --git a/app/node/generator/text/textv3.cpp b/app/node/generator/text/textv3.cpp index 76f2623e6..da6f9bfe8 100644 --- a/app/node/generator/text/textv3.cpp +++ b/app/node/generator/text/textv3.cpp @@ -44,6 +44,7 @@ TextGeneratorV3::TextGeneratorV3() : ShapeNodeBase(false) { AddInput(kTextInput, NodeValue::kText, QStringLiteral("

%1

").arg(tr("Sample Text"))); + SetInputProperty(kTextInput, QStringLiteral("vieweronly"), true); SetStandardValue(kSizeInput, QVector2D(400, 300)); diff --git a/app/panel/param/param.cpp b/app/panel/param/param.cpp index 3e494174d..48fb8dfdb 100644 --- a/app/panel/param/param.cpp +++ b/app/panel/param/param.cpp @@ -30,6 +30,7 @@ ParamPanel::ParamPanel(QWidget* parent) : NodeParamView* view = new NodeParamView(); connect(view, &NodeParamView::FocusedNodeChanged, this, &ParamPanel::FocusedNodeChanged); connect(view, &NodeParamView::SelectedNodesChanged, this, &ParamPanel::SelectedNodesChanged); + connect(view, &NodeParamView::RequestViewerToStartEditingText, this, &ParamPanel::RequestViewerToStartEditingText); connect(this, &ParamPanel::visibilityChanged, view, &NodeParamView::UpdateElementY); SetTimeBasedWidget(view); diff --git a/app/panel/param/param.h b/app/panel/param/param.h index e07fed1f7..5b55075ef 100644 --- a/app/panel/param/param.h +++ b/app/panel/param/param.h @@ -67,6 +67,8 @@ signals: void SelectedNodesChanged(const QVector &nodes); + void RequestViewerToStartEditingText(); + protected: virtual void Retranslate() override; diff --git a/app/panel/viewer/viewerbase.h b/app/panel/viewer/viewerbase.h index b5319ca55..e5fe7cdff 100644 --- a/app/panel/viewer/viewerbase.h +++ b/app/panel/viewer/viewerbase.h @@ -69,6 +69,11 @@ public slots: void CacheSequenceInOut(); + void RequestStartEditingText() + { + static_cast(GetTimeBasedWidget())->RequestStartEditingText(); + } + signals: /** * @brief Signal emitted when a new frame is loaded diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index e687ada6a..99a4cd95f 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -320,6 +320,15 @@ void NodeParamView::SelectNodeFromConnectedLink(Node *node) SetSelectedNodes({p}); } +void NodeParamView::RequestEditTextInViewer() +{ + NodeParamViewItem *item = static_cast(sender()); + + focused_node_ = item; + emit FocusedNodeChanged(item->GetNode()); + emit RequestViewerToStartEditingText(); +} + void NodeParamView::SetContexts(const QVector &contexts) { // Setting contexts is expensive, so we queue it here to prevent multiple calls in a short timespan @@ -735,6 +744,7 @@ void NodeParamView::AddNode(Node *n, Node *ctx, NodeParamViewContext *context) connect(item, &NodeParamViewItem::PinToggled, this, &NodeParamView::PinNode); connect(item, &NodeParamViewItem::InputCheckedChanged, this, &NodeParamView::InputCheckBoxChanged); connect(item, &NodeParamViewItem::Clicked, this, &NodeParamView::ItemClicked); + connect(item, &NodeParamViewItem::RequestEditTextInViewer, this, &NodeParamView::RequestEditTextInViewer); item->SetContext(ctx); item->SetTimeTarget(GetTimeTarget()); diff --git a/app/widget/nodeparamview/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h index 534ae0964..ba918d373 100644 --- a/app/widget/nodeparamview/nodeparamview.h +++ b/app/widget/nodeparamview/nodeparamview.h @@ -86,6 +86,8 @@ signals: void SelectedNodesChanged(const QVector &nodes); + void RequestViewerToStartEditingText(); + protected: virtual void resizeEvent(QResizeEvent *event) override; @@ -182,6 +184,8 @@ private slots: void SelectNodeFromConnectedLink(Node *node); + void RequestEditTextInViewer(); + }; } diff --git a/app/widget/nodeparamview/nodeparamviewitem.cpp b/app/widget/nodeparamview/nodeparamviewitem.cpp index b133d7c07..3151724ce 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.cpp +++ b/app/widget/nodeparamview/nodeparamviewitem.cpp @@ -90,6 +90,7 @@ void NodeParamViewItem::RecreateBody() connect(body_, &NodeParamViewItemBody::RequestSetTime, this, &NodeParamViewItem::RequestSetTime); connect(body_, &NodeParamViewItemBody::ArrayExpandedChanged, this, &NodeParamViewItem::ArrayExpandedChanged); connect(body_, &NodeParamViewItemBody::InputCheckedChanged, this, &NodeParamViewItem::InputCheckedChanged); + connect(body_, &NodeParamViewItemBody::RequestEditTextInViewer, this, &NodeParamViewItem::RequestEditTextInViewer); body_->Retranslate(); body_->SetTime(time_); body_->SetTimebase(timebase_); @@ -237,6 +238,7 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const ui_objects.widget_bridge = new NodeParamViewWidgetBridge(NodeInput(node, input, element), this); connect(ui_objects.widget_bridge, &NodeParamViewWidgetBridge::WidgetsRecreated, this, &NodeParamViewItemBody::ReplaceWidgets); connect(ui_objects.widget_bridge, &NodeParamViewWidgetBridge::ArrayWidgetDoubleClicked, this, &NodeParamViewItemBody::ToggleArrayExpanded); + connect(ui_objects.widget_bridge, &NodeParamViewWidgetBridge::RequestEditTextInViewer, this, &NodeParamViewItemBody::RequestEditTextInViewer); // Place widgets into layout PlaceWidgetsFromBridge(layout, ui_objects.widget_bridge, row); diff --git a/app/widget/nodeparamview/nodeparamviewitem.h b/app/widget/nodeparamview/nodeparamviewitem.h index 581699d79..8ec20bb6a 100644 --- a/app/widget/nodeparamview/nodeparamviewitem.h +++ b/app/widget/nodeparamview/nodeparamviewitem.h @@ -73,6 +73,8 @@ signals: void InputCheckedChanged(const NodeInput &input, bool e); + void RequestEditTextInViewer(); + private: void CreateWidgets(QGridLayout *layout, Node* node, const QString& input, int element, int row_index); @@ -222,6 +224,8 @@ signals: void InputCheckedChanged(const NodeInput &input, bool e); + void RequestEditTextInViewer(); + protected slots: virtual void Retranslate() override; diff --git a/app/widget/nodeparamview/nodeparamviewtextedit.cpp b/app/widget/nodeparamview/nodeparamviewtextedit.cpp index 64ce8da2a..e9423f360 100644 --- a/app/widget/nodeparamview/nodeparamviewtextedit.cpp +++ b/app/widget/nodeparamview/nodeparamviewtextedit.cpp @@ -21,7 +21,6 @@ #include "nodeparamviewtextedit.h" #include -#include #include "dialog/text/text.h" #include "ui/icons/icons.h" @@ -39,11 +38,24 @@ NodeParamViewTextEdit::NodeParamViewTextEdit(QWidget *parent) : connect(line_edit_, &QPlainTextEdit::textChanged, this, &NodeParamViewTextEdit::InnerWidgetTextChanged); layout->addWidget(line_edit_); - QPushButton* edit_btn = new QPushButton(); - edit_btn->setIcon(icon::ToolEdit); - edit_btn->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); - layout->addWidget(edit_btn); - connect(edit_btn, &QPushButton::clicked, this, &NodeParamViewTextEdit::ShowTextDialog); + edit_btn_ = new QPushButton(); + edit_btn_->setIcon(icon::ToolEdit); + edit_btn_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); + layout->addWidget(edit_btn_); + connect(edit_btn_, &QPushButton::clicked, this, &NodeParamViewTextEdit::ShowTextDialog); + + edit_in_viewer_btn_ = new QPushButton(tr("Edit In Viewer")); + layout->addWidget(edit_in_viewer_btn_); + connect(edit_in_viewer_btn_, &QPushButton::clicked, this, &NodeParamViewTextEdit::RequestEditInViewer); + + SetEditInViewerOnlyMode(false); +} + +void NodeParamViewTextEdit::SetEditInViewerOnlyMode(bool on) +{ + line_edit_->setVisible(!on); + edit_btn_->setVisible(!on); + edit_in_viewer_btn_->setVisible(on); } void NodeParamViewTextEdit::ShowTextDialog() diff --git a/app/widget/nodeparamview/nodeparamviewtextedit.h b/app/widget/nodeparamview/nodeparamviewtextedit.h index a61087db8..2c2577566 100644 --- a/app/widget/nodeparamview/nodeparamviewtextedit.h +++ b/app/widget/nodeparamview/nodeparamviewtextedit.h @@ -22,6 +22,7 @@ #define NODEPARAMVIEWTEXTEDIT_H #include +#include #include #include "common/define.h" @@ -39,6 +40,8 @@ public: return line_edit_->toPlainText(); } + void SetEditInViewerOnlyMode(bool on); + public slots: void setText(const QString &s) { @@ -64,9 +67,15 @@ public slots: signals: void textEdited(const QString &); + void RequestEditInViewer(); + private: QPlainTextEdit* line_edit_; + QPushButton* edit_btn_; + + QPushButton *edit_in_viewer_btn_; + private slots: void ShowTextDialog(); diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp index f28e46559..aff1fb770 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp @@ -141,6 +141,7 @@ void NodeParamViewWidgetBridge::CreateWidgets() NodeParamViewTextEdit* line_edit = new NodeParamViewTextEdit(); widgets_.append(line_edit); connect(line_edit, &NodeParamViewTextEdit::textEdited, this, &NodeParamViewWidgetBridge::WidgetCallback); + connect(line_edit, &NodeParamViewTextEdit::RequestEditInViewer, this, &NodeParamViewWidgetBridge::RequestEditTextInViewer); break; } case NodeValue::kBoolean: @@ -781,6 +782,15 @@ void NodeParamViewWidgetBridge::SetProperty(const QString &key, const QVariant & ff->SetDirectoryMode(value.toBool()); } } + + // Parameters for text + if (data_type == NodeValue::kText) { + NodeParamViewTextEdit *tex = static_cast(widgets_.first()); + + if (key == QStringLiteral("vieweronly")) { + tex->SetEditInViewerOnlyMode(value.toBool()); + } + } } void NodeParamViewWidgetBridge::InputDataTypeChanged(const QString &input, NodeValue::Type type) diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.h b/app/widget/nodeparamview/nodeparamviewwidgetbridge.h index d7298cc2c..98a71d5d7 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.h +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.h @@ -57,6 +57,8 @@ signals: void WidgetsRecreated(const NodeInput& input); + void RequestEditTextInViewer(); + private: void CreateWidgets(); diff --git a/app/widget/viewer/viewer.h b/app/widget/viewer/viewer.h index 7397365b1..3a297fbc8 100644 --- a/app/widget/viewer/viewer.h +++ b/app/widget/viewer/viewer.h @@ -119,6 +119,11 @@ public slots: void UpdateTextureFromNode(); + void RequestStartEditingText() + { + display_widget_->RequestStartEditingText(); + } + signals: /** * @brief Wrapper for ViewerGLWidget::CursorColor() diff --git a/app/widget/viewer/viewerdisplay.cpp b/app/widget/viewer/viewerdisplay.cpp index b4b61f173..76c5c09e2 100644 --- a/app/widget/viewer/viewerdisplay.cpp +++ b/app/widget/viewer/viewerdisplay.cpp @@ -45,7 +45,6 @@ #include "node/gizmo/point.h" #include "node/gizmo/polygon.h" #include "node/gizmo/screen.h" -#include "node/gizmo/text.h" #include "node/traverser.h" #include "viewertexteditor.h" #include "window/mainwindow/mainwindow.h" @@ -353,53 +352,7 @@ void ViewerDisplayWidget::mouseDoubleClickEvent(QMouseEvent *event) foreach (NodeGizmo *g, gizmos_->GetGizmos()) { if (TextGizmo *text = dynamic_cast(g)) { if (text->GetRect().contains(ptr)) { - QTransform gizmo_transform = GenerateGizmoTransform(); - - ViewerTextEditor *text_edit = new ViewerTextEditor(gizmo_transform.m11(), this); - Html::HtmlToDoc(text_edit->document(), text->GetHtml()); - text_edit->setProperty("gizmo", reinterpret_cast(text)); - - QRectF transformed_geom = gizmo_transform.map(text->GetRect()).boundingRect(); - text_edit->setGeometry(transformed_geom.toRect()); - - ViewerTextEditorToolBar *toolbar = new ViewerTextEditorToolBar(this); - - QPoint pos = mapToGlobal(QPoint(transformed_geom.x(), transformed_geom.y() - toolbar->height())); - for (QScreen *screen : qApp->screens()) { - if (screen->geometry().contains(pos)) { - if (pos.x() + toolbar->width() > screen->geometry().right()) { - pos.setX(screen->geometry().right() - toolbar->width()); - } - break; - } - } - toolbar->move(pos); - toolbar->show(); - - text_edit->show(); - - connect(text_edit, &ViewerTextEditor::textChanged, this, &ViewerDisplayWidget::TextEditChanged); - - text_edit->ConnectToolBar(toolbar); - - QPoint text_edit_pos = text_edit->mapFrom(this, event->pos()); - - // Ensure text edit is actually focused rather than the toolbar - connect(toolbar, &ViewerTextEditorToolBar::FirstPaint, this, [this, text_edit, text_edit_pos]{ - // Grab focus back from the toolbar - this->raise(); - this->activateWindow(); - text_edit->setFocus(); - - // Start text cursor where the user clicked - text_edit->setTextCursor(text_edit->cursorForPosition(text_edit_pos)); - - // HACK: On macOS, for some reason the QDockWidget receives focus before the - // ViewerTextEditor, causing the editor to close prematurely. However this only - // happens the first time the editor receives focus and not subsequent times, so - // if we get it to only listen after the first one, this solves the problem. - text_edit->SetListenToFocusEvents(true); - }); + OpenTextGizmo(text, event); break; } } @@ -773,6 +726,62 @@ NodeGizmo *ViewerDisplayWidget::TryGizmoPress(const NodeValueRow &row, const QPo return nullptr; } +void ViewerDisplayWidget::OpenTextGizmo(TextGizmo *text, QMouseEvent *event) +{ + QTransform gizmo_transform = GenerateGizmoTransform(); + + ViewerTextEditor *text_edit = new ViewerTextEditor(gizmo_transform.m11(), this); + Html::HtmlToDoc(text_edit->document(), text->GetHtml()); + text_edit->setProperty("gizmo", reinterpret_cast(text)); + + QRectF transformed_geom = gizmo_transform.map(text->GetRect()).boundingRect(); + text_edit->setGeometry(transformed_geom.toRect()); + + ViewerTextEditorToolBar *toolbar = new ViewerTextEditorToolBar(this); + + QPoint pos = mapToGlobal(QPoint(transformed_geom.x(), transformed_geom.y() - toolbar->height())); + for (QScreen *screen : qApp->screens()) { + if (screen->geometry().contains(pos)) { + if (pos.x() + toolbar->width() > screen->geometry().right()) { + pos.setX(screen->geometry().right() - toolbar->width()); + } + break; + } + } + toolbar->move(pos); + toolbar->show(); + + text_edit->show(); + + connect(text_edit, &ViewerTextEditor::textChanged, this, &ViewerDisplayWidget::TextEditChanged); + + text_edit->ConnectToolBar(toolbar); + + QPoint text_edit_pos; + if (event) { + text_edit_pos = text_edit->mapFrom(this, event->pos()); + } + + // Ensure text edit is actually focused rather than the toolbar + connect(toolbar, &ViewerTextEditorToolBar::FirstPaint, this, [this, text_edit, text_edit_pos]{ + // Grab focus back from the toolbar + this->raise(); + this->activateWindow(); + text_edit->setFocus(); + + // Start text cursor where the user clicked + if (!text_edit_pos.isNull()) { + text_edit->setTextCursor(text_edit->cursorForPosition(text_edit_pos)); + } + + // HACK: On macOS, for some reason the QDockWidget receives focus before the + // ViewerTextEditor, causing the editor to close prematurely. However this only + // happens the first time the editor receives focus and not subsequent times, so + // if we get it to only listen after the first one, this solves the problem. + text_edit->SetListenToFocusEvents(true); + }); +} + void ViewerDisplayWidget::EmitColorAtCursor(QMouseEvent *e) { // Do this no matter what, emits signal to any pixel samplers @@ -798,6 +807,18 @@ void ViewerDisplayWidget::SetShowFPS(bool e) update(); } +void ViewerDisplayWidget::RequestStartEditingText() +{ + if (gizmos_) { + foreach (NodeGizmo *gizmo, gizmos_->GetGizmos()) { + if (TextGizmo *text = dynamic_cast(gizmo)) { + OpenTextGizmo(text); + break; + } + } + } +} + void ViewerDisplayWidget::Play(const int64_t &start_timestamp, const int &playback_speed, const rational &timebase) { playback_timebase_ = timebase; diff --git a/app/widget/viewer/viewerdisplay.h b/app/widget/viewer/viewerdisplay.h index d66d25ad7..a8c993aa1 100644 --- a/app/widget/viewer/viewerdisplay.h +++ b/app/widget/viewer/viewerdisplay.h @@ -25,6 +25,7 @@ #include #include "node/color/colormanager/colormanager.h" +#include "node/gizmo/text.h" #include "node/node.h" #include "node/output/track/tracklist.h" #include "render/color.h" @@ -169,6 +170,8 @@ public slots: void SetShowFPS(bool e); + void RequestStartEditingText(); + signals: /** * @brief Signal emitted when the user starts dragging from the viewer @@ -264,6 +267,8 @@ private: NodeGizmo *TryGizmoPress(const NodeValueRow &row, const QPointF &p); + void OpenTextGizmo(TextGizmo *text, QMouseEvent *event = nullptr); + /** * @brief Internal reference to the OpenGL texture to draw. Set in SetTexture() and used in paintGL(). */ diff --git a/app/window/mainwindow/mainwindow.cpp b/app/window/mainwindow/mainwindow.cpp index b6b3fb0e0..176575e40 100644 --- a/app/window/mainwindow/mainwindow.cpp +++ b/app/window/mainwindow/mainwindow.cpp @@ -96,6 +96,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(node_panel_, &NodePanel::NodeGroupOpened, this, &MainWindow::NodePanelGroupOpenedOrClosed); connect(node_panel_, &NodePanel::NodeGroupClosed, this, &MainWindow::NodePanelGroupOpenedOrClosed); connect(param_panel_, &ParamPanel::FocusedNodeChanged, sequence_viewer_panel_, &ViewerPanel::SetGizmos); + connect(param_panel_, &ParamPanel::RequestViewerToStartEditingText, sequence_viewer_panel_, &ViewerPanel::RequestStartEditingText); connect(param_panel_, &ParamPanel::FocusedNodeChanged, curve_panel_, &CurvePanel::SetNode); connect(param_panel_, &ParamPanel::SelectedNodesChanged, node_panel_, &NodePanel::Select);