Merge branch 'master' into rational_slider
This commit is contained in:
@@ -37,8 +37,10 @@ void HandMovableView::ApplicationToolChanged(Tool::Item tool)
|
||||
{
|
||||
if (tool == Tool::kHand) {
|
||||
setDragMode(ScrollHandDrag);
|
||||
setInteractive(false);
|
||||
} else {
|
||||
setDragMode(default_drag_mode_);
|
||||
setInteractive(true);
|
||||
}
|
||||
|
||||
ToolChangedEvent(tool);
|
||||
@@ -51,6 +53,7 @@ bool HandMovableView::HandPress(QMouseEvent *event)
|
||||
dragging_hand_ = true;
|
||||
|
||||
setDragMode(ScrollHandDrag);
|
||||
setInteractive(false);
|
||||
|
||||
// Transform mouse event to act like the left button is pressed
|
||||
QMouseEvent transformed(event->type(),
|
||||
@@ -94,6 +97,7 @@ bool HandMovableView::HandRelease(QMouseEvent *event)
|
||||
|
||||
QGraphicsView::mouseReleaseEvent(&transformed);
|
||||
|
||||
setInteractive(true);
|
||||
setDragMode(pre_hand_drag_mode_);
|
||||
|
||||
dragging_hand_ = false;
|
||||
|
||||
@@ -262,7 +262,7 @@ void NodeParamView::UpdateItemTime(const int64_t ×tamp)
|
||||
|
||||
void NodeParamView::QueueKeyframePositionUpdate()
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "UpdateElementY", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, &NodeParamView::UpdateElementY, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void NodeParamView::SignalNodeOrder()
|
||||
@@ -310,8 +310,9 @@ void NodeParamView::AddNode(Node *n)
|
||||
connect(item, &NodeParamViewItem::dockLocationChanged, this, &NodeParamView::QueueKeyframePositionUpdate);
|
||||
connect(item, &NodeParamViewItem::dockLocationChanged, this, &NodeParamView::SignalNodeOrder);
|
||||
connect(item, &NodeParamViewItem::PinToggled, this, &NodeParamView::PinNode);
|
||||
connect(item, &NodeParamViewItem::ExpandedChanged, this, &NodeParamView::UpdateElementY);
|
||||
connect(item, &NodeParamViewItem::ArrayExpandedChanged, this, &NodeParamView::UpdateElementY);
|
||||
connect(item, &NodeParamViewItem::ArrayExpandedChanged, this, &NodeParamView::QueueKeyframePositionUpdate);
|
||||
connect(item, &NodeParamViewItem::ExpandedChanged, this, &NodeParamView::QueueKeyframePositionUpdate);
|
||||
connect(item, &NodeParamViewItem::Moved, this, &NodeParamView::QueueKeyframePositionUpdate);
|
||||
|
||||
// Set time target
|
||||
item->SetTimeTarget(GetTimeTarget());
|
||||
|
||||
@@ -36,8 +36,13 @@ const int NodeParamViewItemBody::kKeyControlColumn = 10;
|
||||
const int NodeParamViewItemBody::kArrayInsertColumn = kKeyControlColumn-1;
|
||||
const int NodeParamViewItemBody::kArrayRemoveColumn = kArrayInsertColumn-1;
|
||||
|
||||
// 0 is for the array collapse button, 1 is for the main label, widgets start at 2
|
||||
const int NodeParamViewItemBody::kWidgetStartColumn = 2;
|
||||
|
||||
#define super QDockWidget
|
||||
|
||||
NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) :
|
||||
QDockWidget(parent),
|
||||
super(parent),
|
||||
node_(node),
|
||||
highlighted_(false)
|
||||
{
|
||||
@@ -97,12 +102,12 @@ void NodeParamViewItem::changeEvent(QEvent *e)
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
QWidget::changeEvent(e);
|
||||
super::changeEvent(e);
|
||||
}
|
||||
|
||||
void NodeParamViewItem::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QDockWidget::paintEvent(event);
|
||||
super::paintEvent(event);
|
||||
|
||||
// Draw border if focused
|
||||
if (highlighted_) {
|
||||
@@ -113,6 +118,13 @@ void NodeParamViewItem::paintEvent(QPaintEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItem::moveEvent(QMoveEvent *event)
|
||||
{
|
||||
super::moveEvent(event);
|
||||
|
||||
emit Moved();
|
||||
}
|
||||
|
||||
void NodeParamViewItem::Retranslate()
|
||||
{
|
||||
node_->Retranslate();
|
||||
@@ -257,6 +269,10 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
|
||||
|
||||
InputUI ui_objects;
|
||||
|
||||
// Store layout and row
|
||||
ui_objects.layout = layout;
|
||||
ui_objects.row = row;
|
||||
|
||||
// Add descriptor label
|
||||
ui_objects.main_label = new QLabel();
|
||||
|
||||
@@ -299,23 +315,24 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
|
||||
|
||||
// Create a widget/input bridge for this input
|
||||
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);
|
||||
|
||||
// 0 is for the array collapse button, 1 is for the main label, widgets start at 2
|
||||
const int widget_start = 2;
|
||||
// Place widgets into layout
|
||||
PlaceWidgetsFromBridge(layout, ui_objects.widget_bridge, row);
|
||||
|
||||
// Add widgets for this parameter to the layout
|
||||
for (int i=0; i<ui_objects.widget_bridge->widgets().size(); i++) {
|
||||
QWidget* w = ui_objects.widget_bridge->widgets().at(i);
|
||||
|
||||
layout->addWidget(w, row, i+widget_start);
|
||||
layout->addWidget(w, row, i+kWidgetStartColumn);
|
||||
}
|
||||
|
||||
if (node->IsInputConnectable(input)) {
|
||||
// Create clickable label used when an input is connected
|
||||
ui_objects.connected_label = new NodeParamViewConnectedLabel(input_ref);
|
||||
connect(ui_objects.connected_label, &NodeParamViewConnectedLabel::RequestSelectNode, this, &NodeParamViewItemBody::RequestSelectNode);
|
||||
layout->addWidget(ui_objects.connected_label, row, widget_start);
|
||||
layout->addWidget(ui_objects.connected_label, row, kWidgetStartColumn);
|
||||
}
|
||||
|
||||
// Add keyframe control to this layout if parameter is keyframable
|
||||
@@ -414,6 +431,16 @@ void NodeParamViewItemBody::UpdateUIForEdgeConnection(const NodeInput& input)
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemBody::PlaceWidgetsFromBridge(QGridLayout* layout, NodeParamViewWidgetBridge *bridge, int row)
|
||||
{
|
||||
// Add widgets for this parameter to the layout
|
||||
for (int i=0; i<bridge->widgets().size(); i++) {
|
||||
QWidget* w = bridge->widgets().at(i);
|
||||
|
||||
layout->addWidget(w, row, i+kWidgetStartColumn);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemBody::ArrayCollapseBtnPressed(bool checked)
|
||||
{
|
||||
const NodeInputPair& input = array_collapse_buttons_.key(static_cast<CollapseButton*>(sender()));
|
||||
@@ -510,12 +537,19 @@ void NodeParamViewItemBody::ToggleArrayExpanded()
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemBody::SetTimebase(const rational& timebase) {
|
||||
void NodeParamViewItemBody::SetTimebase(const rational& timebase)
|
||||
{
|
||||
foreach (const InputUI& ui_obj, input_ui_map_) {
|
||||
ui_obj.widget_bridge->SetTimebase(timebase);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemBody::ReplaceWidgets(const NodeInput &input)
|
||||
{
|
||||
InputUI ui = input_ui_map_.value(input);
|
||||
PlaceWidgetsFromBridge(ui.layout, ui.widget_bridge, ui.row);
|
||||
}
|
||||
|
||||
NodeParamViewItemBody::InputUI::InputUI() :
|
||||
main_label(nullptr),
|
||||
widget_bridge(nullptr),
|
||||
|
||||
@@ -99,6 +99,8 @@ private:
|
||||
|
||||
void UpdateUIForEdgeConnection(const NodeInput &input);
|
||||
|
||||
void PlaceWidgetsFromBridge(QGridLayout *layout, NodeParamViewWidgetBridge* bridge, int row);
|
||||
|
||||
struct InputUI {
|
||||
InputUI();
|
||||
|
||||
@@ -106,6 +108,8 @@ private:
|
||||
NodeParamViewWidgetBridge* widget_bridge;
|
||||
NodeParamViewConnectedLabel* connected_label;
|
||||
NodeParamViewKeyframeControl* key_control;
|
||||
QGridLayout* layout;
|
||||
int row;
|
||||
|
||||
NodeParamViewArrayButton* array_insert_btn;
|
||||
NodeParamViewArrayButton* array_remove_btn;
|
||||
@@ -134,6 +138,8 @@ private:
|
||||
static const int kArrayInsertColumn;
|
||||
static const int kArrayRemoveColumn;
|
||||
|
||||
static const int kWidgetStartColumn;
|
||||
|
||||
private slots:
|
||||
void EdgeChanged(const NodeOutput &output, const NodeInput &input);
|
||||
|
||||
@@ -149,6 +155,8 @@ private slots:
|
||||
|
||||
void ToggleArrayExpanded();
|
||||
|
||||
void ReplaceWidgets(const NodeInput& input);
|
||||
|
||||
};
|
||||
|
||||
class NodeParamViewItem : public QDockWidget
|
||||
@@ -192,11 +200,15 @@ signals:
|
||||
|
||||
void ArrayExpandedChanged(bool e);
|
||||
|
||||
void Moved();
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent *e) override;
|
||||
|
||||
virtual void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void moveEvent(QMoveEvent *event) override;
|
||||
|
||||
private:
|
||||
NodeParamViewItemTitleBar* title_bar_;
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ NodeParamViewWidgetBridge::NodeParamViewWidgetBridge(const NodeInput &input, QOb
|
||||
|
||||
connect(input_.node(), &Node::ValueChanged, this, &NodeParamViewWidgetBridge::InputValueChanged);
|
||||
connect(input_.node(), &Node::InputPropertyChanged, this, &NodeParamViewWidgetBridge::PropertyChanged);
|
||||
connect(input_.node(), &Node::InputDataTypeChanged, this, &NodeParamViewWidgetBridge::InputDataTypeChanged);
|
||||
}
|
||||
|
||||
void NodeParamViewWidgetBridge::SetTime(const rational &time)
|
||||
@@ -212,14 +213,25 @@ void NodeParamViewWidgetBridge::SetInputValueInternal(const QVariant &value, int
|
||||
command->add_child(new NodeParamSetKeyframeValueCommand(existing_key, value));
|
||||
} else {
|
||||
// No existing key, create a new one
|
||||
NodeKeyframe* new_key = new NodeKeyframe(node_time,
|
||||
value,
|
||||
input_.node()->GetBestKeyframeTypeForTimeOnTrack(NodeKeyframeTrackReference(input_, track), node_time),
|
||||
track,
|
||||
input_.element(),
|
||||
input_.input());
|
||||
int nb_tracks = NodeValue::get_number_of_keyframe_tracks(input_.node()->GetInputDataType(input_.input()));
|
||||
for (int i=0; i<nb_tracks; i++) {
|
||||
QVariant track_value;
|
||||
|
||||
command->add_child(new NodeParamInsertKeyframeCommand(input_.node(), new_key));
|
||||
if (i == track) {
|
||||
track_value = value;
|
||||
} else {
|
||||
track_value = input_.node()->GetValueAtTime(input_.input(), node_time, input_.element());
|
||||
}
|
||||
|
||||
NodeKeyframe* new_key = new NodeKeyframe(node_time,
|
||||
track_value,
|
||||
input_.node()->GetBestKeyframeTypeForTimeOnTrack(NodeKeyframeTrackReference(input_, i), node_time),
|
||||
i,
|
||||
input_.element(),
|
||||
input_.input());
|
||||
|
||||
command->add_child(new NodeParamInsertKeyframeCommand(input_.node(), new_key));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(input_, track), value));
|
||||
@@ -767,6 +779,22 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString& input, const QStr
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewWidgetBridge::InputDataTypeChanged(const QString &input, NodeValue::Type type)
|
||||
{
|
||||
Q_UNUSED(type)
|
||||
if (input == this->input_.input()) {
|
||||
// Delete all widgets
|
||||
qDeleteAll(widgets_);
|
||||
widgets_.clear();
|
||||
|
||||
// Create new widgets
|
||||
CreateWidgets();
|
||||
|
||||
// Signal that widgets are new
|
||||
emit WidgetsRecreated(input_);
|
||||
}
|
||||
}
|
||||
|
||||
bool NodeParamViewScrollBlocker::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
Q_UNUSED(watched)
|
||||
|
||||
@@ -54,6 +54,8 @@ public:
|
||||
signals:
|
||||
void ArrayWidgetDoubleClicked();
|
||||
|
||||
void WidgetsRecreated(const NodeInput& input);
|
||||
|
||||
private:
|
||||
void CreateWidgets();
|
||||
|
||||
@@ -87,6 +89,8 @@ private slots:
|
||||
|
||||
void PropertyChanged(const QString &input, const QString& key, const QVariant& value);
|
||||
|
||||
void InputDataTypeChanged(const QString& input, NodeValue::Type type);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -298,11 +298,11 @@ void NodeView::Paste()
|
||||
|
||||
QVector<Node*> pasted_nodes = PasteNodesFromClipboard(graph_, command);
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
|
||||
if (!pasted_nodes.isEmpty()) {
|
||||
AttachNodesToCursor(pasted_nodes);
|
||||
command->add_child(new NodeViewAttachNodesToCursor(this, pasted_nodes));
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
}
|
||||
|
||||
void NodeView::Duplicate()
|
||||
@@ -321,9 +321,11 @@ void NodeView::Duplicate()
|
||||
|
||||
QVector<Node*> duplicated_nodes = Node::CopyDependencyGraph(selected, command);
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
if (!duplicated_nodes.isEmpty()) {
|
||||
command->add_child(new NodeViewAttachNodesToCursor(this, duplicated_nodes));
|
||||
}
|
||||
|
||||
AttachNodesToCursor(duplicated_nodes);
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
}
|
||||
|
||||
void NodeView::SetColorLabel(int index)
|
||||
@@ -839,4 +841,26 @@ void NodeView::ZoomFromKeyboard(double multiplier)
|
||||
ZoomIntoCursorPosition(multiplier, cursor_pos);
|
||||
}
|
||||
|
||||
NodeView::NodeViewAttachNodesToCursor::NodeViewAttachNodesToCursor(NodeView *view, const QVector<Node *> &nodes) :
|
||||
view_(view),
|
||||
nodes_(nodes)
|
||||
{
|
||||
}
|
||||
|
||||
void NodeView::NodeViewAttachNodesToCursor::redo()
|
||||
{
|
||||
view_->AttachNodesToCursor(nodes_);
|
||||
}
|
||||
|
||||
void NodeView::NodeViewAttachNodesToCursor::undo()
|
||||
{
|
||||
view_->DetachItemsFromCursor();
|
||||
}
|
||||
|
||||
Project *NodeView::NodeViewAttachNodesToCursor::GetRelevantProject() const
|
||||
{
|
||||
// Will either return a project or a nullptr which is also acceptable
|
||||
return dynamic_cast<Project*>(view_->graph_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -110,6 +110,24 @@ private:
|
||||
|
||||
void ZoomFromKeyboard(double multiplier);
|
||||
|
||||
class NodeViewAttachNodesToCursor : public UndoCommand
|
||||
{
|
||||
public:
|
||||
NodeViewAttachNodesToCursor(NodeView* view, const QVector<Node*>& nodes);
|
||||
|
||||
virtual void redo() override;
|
||||
|
||||
virtual void undo() override;
|
||||
|
||||
virtual Project * GetRelevantProject() const override;
|
||||
|
||||
private:
|
||||
NodeView* view_;
|
||||
|
||||
QVector<Node*> nodes_;
|
||||
|
||||
};
|
||||
|
||||
NodeGraph* graph_;
|
||||
|
||||
struct AttachedItem {
|
||||
|
||||
@@ -490,15 +490,19 @@ void ProjectExplorer::ContextMenuStartProxy(QAction *a)
|
||||
Sequence* sequence = Node::ValueToPtr<Sequence>(a->data());
|
||||
|
||||
// To get here, the `context_menu_items_` must be all kFootage
|
||||
foreach (Node* i, context_menu_items_) {
|
||||
Footage* f = static_cast<Footage*>(i);
|
||||
foreach (Node* item, context_menu_items_) {
|
||||
Footage* f = static_cast<Footage*>(item);
|
||||
|
||||
QVector<VideoParams> enabled_streams = f->GetEnabledVideoStreams();
|
||||
int sz = f->InputArraySize(Footage::kVideoParamsInput);
|
||||
|
||||
foreach (const VideoParams& stream, enabled_streams) {
|
||||
// Start a background task for proxying
|
||||
PreCacheTask* proxy_task = new PreCacheTask(f, stream.stream_index(), sequence);
|
||||
TaskManager::instance()->AddTask(proxy_task);
|
||||
for (int j=0; j<sz; j++) {
|
||||
VideoParams vp = f->GetVideoParams(j);
|
||||
|
||||
if (vp.enabled()) {
|
||||
// Start a background task for proxying
|
||||
PreCacheTask* proxy_task = new PreCacheTask(f, j, sequence);
|
||||
TaskManager::instance()->AddTask(proxy_task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1009,7 +1009,7 @@ void TimelineWidget::SetViewTimestamp(const int64_t &ts)
|
||||
for (int i=0;i<views_.size();i++) {
|
||||
TimelineAndTrackView* view = views_.at(i);
|
||||
|
||||
if (use_audio_time_units_ && i == Track::kAudio) {
|
||||
if (GetConnectedNode() && use_audio_time_units_ && i == Track::kAudio) {
|
||||
view->view()->SetTime(Timecode::rescale_timestamp(ts,
|
||||
timebase(),
|
||||
GetConnectedNode()->GetAudioParams().sample_rate_as_time_base()));
|
||||
@@ -1021,7 +1021,7 @@ void TimelineWidget::SetViewTimestamp(const int64_t &ts)
|
||||
|
||||
void TimelineWidget::ViewTimestampChanged(int64_t ts)
|
||||
{
|
||||
if (use_audio_time_units_ && sender() == views_.at(Track::kAudio)) {
|
||||
if (GetConnectedNode() && use_audio_time_units_ && sender() == views_.at(Track::kAudio)) {
|
||||
ts = Timecode::rescale_timestamp(ts,
|
||||
GetConnectedNode()->GetAudioParams().sample_rate_as_time_base(),
|
||||
timebase());
|
||||
@@ -1503,6 +1503,10 @@ QVector<SnapData> AttemptSnap(const QVector<double>& screen_pt,
|
||||
|
||||
bool TimelineWidget::SnapPoint(QVector<rational> start_times, rational* movement, int snap_points)
|
||||
{
|
||||
if (!GetConnectedNode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QVector<double> screen_pt;
|
||||
|
||||
foreach (const rational& s, start_times) {
|
||||
|
||||
@@ -160,6 +160,10 @@ int SeekableWidget::TimeToScreen(const rational &time) const
|
||||
|
||||
void SeekableWidget::SeekToScreenPoint(int screen)
|
||||
{
|
||||
if (timebase().isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t timestamp = qMax(static_cast<int64_t>(0), ScreenToUnitRounded(screen));
|
||||
|
||||
if (Core::instance()->snapping() && snap_service_) {
|
||||
|
||||
@@ -129,7 +129,7 @@ ViewerWidget::~ViewerWidget()
|
||||
{
|
||||
instances_.removeOne(this);
|
||||
|
||||
QList<ViewerWindow*> windows = windows_;
|
||||
auto windows = windows_;
|
||||
|
||||
foreach (ViewerWindow* window, windows) {
|
||||
delete window;
|
||||
@@ -311,6 +311,11 @@ void ViewerWidget::SetFullScreen(QScreen *screen)
|
||||
}
|
||||
}
|
||||
|
||||
if (windows_.contains(screen)) {
|
||||
delete windows_.take(screen);
|
||||
return;
|
||||
}
|
||||
|
||||
ViewerWindow* vw = new ViewerWindow(this);
|
||||
|
||||
vw->setGeometry(screen->geometry());
|
||||
@@ -326,7 +331,7 @@ void ViewerWidget::SetFullScreen(QScreen *screen)
|
||||
|
||||
vw->display_widget()->SetImage(display_widget_->last_loaded_buffer());
|
||||
|
||||
windows_.append(vw);
|
||||
windows_.insert(screen, vw);
|
||||
}
|
||||
|
||||
void ViewerWidget::ForceUpdate()
|
||||
@@ -745,7 +750,7 @@ void ViewerWidget::ContextMenuSetCustomSafeMargins()
|
||||
|
||||
void ViewerWidget::WindowAboutToClose()
|
||||
{
|
||||
windows_.removeOne(static_cast<ViewerWindow*>(sender()));
|
||||
windows_.remove(windows_.key(static_cast<ViewerWindow*>(sender())));
|
||||
}
|
||||
|
||||
void ViewerWidget::ContextMenuScopeTriggered(QAction *action)
|
||||
@@ -801,6 +806,10 @@ void ViewerWidget::RendererGeneratedFrameForQueue()
|
||||
|
||||
void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
{
|
||||
if (!GetConnectedNode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Menu menu(static_cast<QWidget*>(sender()));
|
||||
|
||||
context_menu_widget_ = dynamic_cast<ViewerDisplayWidget*>(sender());
|
||||
@@ -854,6 +863,8 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
QString::number(s->size().height())));
|
||||
|
||||
a->setData(i);
|
||||
a->setCheckable(true);
|
||||
a->setChecked(windows_.contains(QGuiApplication::screens().at(i)));
|
||||
}
|
||||
|
||||
connect(full_screen_menu, &QMenu::triggered, this, &ViewerWidget::ContextMenuSetFullScreen);
|
||||
|
||||
@@ -223,7 +223,7 @@ private:
|
||||
|
||||
AudioWaveformView* waveform_view_;
|
||||
|
||||
QList<ViewerWindow*> windows_;
|
||||
QHash<QScreen*, ViewerWindow*> windows_;
|
||||
|
||||
ViewerDisplayWidget* display_widget_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user