Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions qtfred/src/mission/dialogs/WaypointEditorDialogModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,10 @@ void WaypointEditorDialogModel::selectWaypointPathByIndex(int idx) {
initializeData();
}

int WaypointEditorDialogModel::getSelectedPathIndex() const {
return _selectedWaypointPaths.empty() ? -1 : _selectedWaypointPaths.front();
}

void WaypointEditorDialogModel::selectNextPath() {
if (Waypoint_lists.empty())
return;
Expand Down
3 changes: 2 additions & 1 deletion qtfred/src/mission/dialogs/WaypointEditorDialogModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class WaypointEditorDialogModel : public AbstractDialogModel {

void selectNextPath();
void selectPreviousPath();
void selectWaypointPathByIndex(int idx);
int getSelectedPathIndex() const;

signals:
void waypointPathMarkingChanged();
Expand All @@ -58,7 +60,6 @@ private slots:
void initializeData();
void showErrorDialogNoCancel(const SCP_string& message);
bool validateName(const SCP_string& name);
void selectWaypointPathByIndex(int idx);

SCP_vector<int> _selectedWaypointPaths; // indices into Waypoint_lists
SCP_string _currentName;
Expand Down
20 changes: 20 additions & 0 deletions qtfred/src/ui/dialogs/JumpNodeEditorDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#include "ui_JumpNodeEditorDialog.h"

#include <globalincs/globals.h>
#include <jumpnode/jumpnode.h>
#include <mission/util.h>
#include <ui/util/menu.h>

namespace fso::fred::dialogs {

Expand Down Expand Up @@ -32,6 +34,24 @@ JumpNodeEditorDialog::JumpNodeEditorDialog(FredView* parent, EditorViewport* vie
updateUi();
});

// "Select Jump Node" menu: jump the editor to any jump node in the mission.
Editor* editor = viewport->editor;
util::installSelectMenu(
this,
[]() {
std::vector<util::SelectMenuEntry> entries;
for (const auto& jn : Jump_nodes) {
entries.push_back({QString::fromUtf8(jn.GetName()), jn.GetSCPObjectNumber()});
}
return entries;
},
[this, editor]() { return _model->hasMultipleSelection() ? -1 : editor->currentObject; },
[editor](int objnum) {
editor->unmark_all();
editor->selectObject(objnum);
},
tr("&Select Jump Node"));

// Resize the dialog to the minimum size
resize(QDialog::sizeHint());
}
Expand Down
24 changes: 24 additions & 0 deletions qtfred/src/ui/dialogs/PropEditorDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
#include "ui_PropEditorDialog.h"

#include <globalincs/globals.h>
#include <globalincs/linklist.h>
#include <object/object.h>
#include <prop/prop.h>
#include <ui/util/SignalBlockers.h>
#include <ui/util/menu.h>
#include <ui/widgets/FlagList.h>

#include <QMetaObject>
Expand Down Expand Up @@ -40,6 +44,26 @@ PropEditorDialog::PropEditorDialog(FredView* parent, EditorViewport* viewport)
QMetaObject::invokeMethod(this, [this]() { _viewport->editor->missionChanged(); }, Qt::QueuedConnection);
});

// "Select Prop" menu: jump the editor to any prop in the mission.
Editor* editor = viewport->editor;
util::installSelectMenu(
this,
[]() {
std::vector<util::SelectMenuEntry> entries;
for (auto* ptr = GET_FIRST(&obj_used_list); ptr != END_OF_LIST(&obj_used_list); ptr = GET_NEXT(ptr)) {
if (ptr->type == OBJ_PROP && Props[ptr->instance].has_value()) {
entries.push_back({QString::fromUtf8(Props[ptr->instance]->prop_name), OBJ_INDEX(ptr)});
}
}
return entries;
},
[this, editor]() { return _model->hasMultipleSelection() ? -1 : editor->currentObject; },
[editor](int objnum) {
editor->unmark_all();
editor->selectObject(objnum);
},
tr("&Select Prop"));

resize(QDialog::sizeHint());
}

Expand Down
21 changes: 21 additions & 0 deletions qtfred/src/ui/dialogs/ShipEditor/ShipEditorDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <globalincs/linklist.h>
#include <ship/ship.h>
#include <ui/util/SignalBlockers.h>
#include <ui/util/menu.h>

#include <QCloseEvent>
#include <ui/dialogs/General/CheckBoxListDialog.h>
Expand Down Expand Up @@ -53,6 +54,26 @@ ShipEditorDialog::ShipEditorDialog(FredView* parent, EditorViewport* viewport)

// ui->cargoCombo->installEventFilter(this);

// "Select Ship" menu: jump the editor to any ship (or player) in the mission.
Editor* editor = viewport->editor;
util::installSelectMenu(
this,
[]() {
std::vector<util::SelectMenuEntry> entries;
for (auto* ptr = GET_FIRST(&obj_used_list); ptr != END_OF_LIST(&obj_used_list); ptr = GET_NEXT(ptr)) {
if (ptr->type == OBJ_SHIP || ptr->type == OBJ_START) {
entries.push_back({QString::fromUtf8(Ships[ptr->instance].ship_name), OBJ_INDEX(ptr)});
}
}
return entries;
},
[this, editor]() { return _model->getIfMultipleShips() ? -1 : editor->currentObject; },
[editor](int objnum) {
editor->unmark_all();
editor->selectObject(objnum);
},
tr("&Select Ship"));

updateUi(true);

// Resize the dialog to the minimum size
Expand Down
18 changes: 18 additions & 0 deletions qtfred/src/ui/dialogs/WaypointEditorDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include <globalincs/globals.h>
#include <mission/util.h>
#include <object/waypoint.h>
#include <ui/util/menu.h>

namespace fso::fred::dialogs {

Expand Down Expand Up @@ -34,6 +36,22 @@ WaypointEditorDialog::WaypointEditorDialog(FredView* parent, EditorViewport* vie
updateUi();
});

// "Select Waypoint Path" menu: jump the editor to any path in the mission.
auto* model = _model.get();
util::installSelectMenu(
this,
[]() {
std::vector<util::SelectMenuEntry> entries;
entries.reserve(Waypoint_lists.size());
for (int i = 0; i < static_cast<int>(Waypoint_lists.size()); i++) {
entries.push_back({QString::fromUtf8(Waypoint_lists[i].get_name()), i});
}
return entries;
},
[model]() { return model->hasMultipleSelection() ? -1 : model->getSelectedPathIndex(); },
[model](int idx) { model->selectWaypointPathByIndex(idx); },
tr("&Select Waypoint Path"));

// Resize the dialog to the minimum size
resize(QDialog::sizeHint());
}
Expand Down
19 changes: 19 additions & 0 deletions qtfred/src/ui/dialogs/WingEditorDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
#include "ui_WingEditorDialog.h"

#include <globalincs/globals.h>
#include <ship/ship.h>
#include <ui/util/SignalBlockers.h>
#include <ui/util/ImageRenderer.h>
#include <ui/util/menu.h>
#include <QMessageBox>

namespace fso::fred::dialogs {
Expand Down Expand Up @@ -43,6 +45,23 @@ WingEditorDialog::WingEditorDialog(FredView* parent, EditorViewport* viewport)
connect(ui->departureTree, &sexp_tree_view::helpChanged, this, [this](const QString& help) { ui->helpText->setPlainText(help); });
connect(ui->departureTree, &sexp_tree_view::miniHelpChanged, this, [this](const QString& help) { ui->HelpTitle->setText(help); });

// "Select Wing" menu: jump the editor to any wing in the mission.
Editor* editor = viewport->editor;
util::installSelectMenu(
this,
[]() {
std::vector<util::SelectMenuEntry> entries;
for (int i = 0; i < MAX_WINGS; i++) {
if (Wings[i].wave_count) {
entries.push_back({QString::fromUtf8(Wings[i].name), i});
}
}
return entries;
},
[editor]() { return editor->cur_wing; },
[editor](int wing) { editor->mark_wing(wing); },
tr("&Select Wing"));

refreshAllDynamicCombos();
updateUi();

Expand Down
53 changes: 53 additions & 0 deletions qtfred/src/ui/util/menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@

#include "menu.h"

#include <QAction>
#include <QFont>
#include <QLayout>
#include <QMenuBar>
#include <QWidget>

#include <utility>

namespace fso {
namespace fred {
Expand All @@ -28,6 +35,52 @@ int propagate_disabled_status(QMenu* top) {
return count;
}

void installSelectMenu(QWidget* dialog,
std::function<std::vector<SelectMenuEntry>()> gather,
std::function<int()> currentId,
std::function<void(int)> onChosen,
const QString& menuTitle)
{
auto* layout = dialog->layout();
if (layout == nullptr) {
return; // needs a top-level layout to host a menu bar
}

// Reuse an existing menu bar if one is already installed, otherwise add a
// slim one above the dialog's content.
auto* menuBar = qobject_cast<QMenuBar*>(layout->menuBar());
if (menuBar == nullptr) {
menuBar = new QMenuBar(dialog);
layout->setMenuBar(menuBar);
}

QMenu* menu = menuBar->addMenu(menuTitle);

// Rebuild the list from the live scene every time the menu opens.
QObject::connect(menu, &QMenu::aboutToShow, menu,
[menu, gather = std::move(gather), currentId = std::move(currentId), onChosen = std::move(onChosen)]() {
menu->clear();
const int current = currentId ? currentId() : -1;
QAction* currentAct = nullptr;
for (const auto& entry : gather()) {
QAction* act = menu->addAction(entry.name);
if (entry.id == current) {
// Highlight the current object with a bold font
QFont font = act->font();
font.setBold(true);
act->setFont(font);
currentAct = act;
}
const int id = entry.id;
QObject::connect(act, &QAction::triggered, menu, [onChosen, id]() { onChosen(id); });
}
// Open with the current item pre-highlighted.
if (currentAct != nullptr) {
menu->setActiveAction(currentAct);
}
});
}

}
}
}
20 changes: 20 additions & 0 deletions qtfred/src/ui/util/menu.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
#pragma once

#include <QMenu>
#include <QString>

#include <functional>
#include <vector>

class QWidget;

namespace fso {
namespace fred {
namespace util {

int propagate_disabled_status(QMenu* top);

struct SelectMenuEntry {
QString name;
int id;
};

// Adds a "Select" menu to an object-editor dialog's menu bar, creating a slim
// menu bar via the dialog's top-level layout if one isn't already present and
// reusing an existing bar otherwise.
void installSelectMenu(QWidget* dialog,
std::function<std::vector<SelectMenuEntry>()> gather,
std::function<int()> currentId,
std::function<void(int)> onChosen,
const QString& menuTitle);

}
}
}
Loading