-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Object Editor Events #153
Merged
Merged
Object Editor Events #153
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
f042b1b
idk wtf im doing
1774a9f
fix events tree parents n stuffs
RobertBColton 2735ed5
oopsie
RobertBColton ff34f35
clean up events other icon
RobertBColton 75d464f
rename key press/release icons to match events.ey event name
RobertBColton c2f898f
new ui
4d0f95d
gut roberts code
95ed18e
still fuxed
fba3d34
robert quit hidin pls
84646f0
start stacked code editor
8a3af4e
why menu no work?
5db8454
ugh
d281e40
correct indexes
461d7a1
wip
6f94ae8
Update Dialogs/EventArgumentsDialog.cpp
RobertBColton 3d6f2d5
Merge branch 'master' of https://github.com/enigma-dev/RadialGM into …
RobertBColton 844d83f
fix the done code
RobertBColton 9bc186e
ugh
36b3722
fix all that shit with identity proxy model
RobertBColton 4cf51a8
WIP
afb3951
Merge branch 'master' of https://github.com/enigma-dev/RadialGM into …
RobertBColton bb87a2a
fix code editor embedding and auto slot connections
RobertBColton daed453
done but buggy
fe98a69
done but buggy
0e8efc3
readd splitter
RobertBColton f10d3be
Merge branch 'master' of https://github.com/enigma-dev/RadialGM into …
RobertBColton 69bbd4e
return explicit invalid model index
RobertBColton 3722673
Simplify event argument dialog done
RobertBColton 42ca589
fundies wants fail safe in case arg is invalid so correct number of args
RobertBColton 0d7c65c
Update Models/EventTypesListModel.h
RobertBColton a7d0438
Update EventTypesListModel.h
RobertBColton 01fe6ac
Update Models/EventTypesListSortFilterProxyModel.cpp
RobertBColton bf78359
Merge branch 'master' of https://github.com/enigma-dev/RadialGM into …
RobertBColton 27d2691
add event args dialog to cmakelists
RobertBColton File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#include "EventArgumentsDialog.h" | ||
#include "Components/QMenuView.h" | ||
#include "MainWindow.h" | ||
#include "Models/TreeSortFilterProxyModel.h" | ||
|
||
#include <QComboBox> | ||
#include <QDialogButtonBox> | ||
#include <QGridLayout> | ||
#include <QLabel> | ||
#include <QLineEdit> | ||
#include <QMetaProperty> | ||
#include <QPushButton> | ||
#include <QSpinBox> | ||
#include <QToolButton> | ||
|
||
EventArgumentsDialog::EventArgumentsDialog(QWidget *parent, const QStringList &arguments) : QDialog(parent) { | ||
QGridLayout *layout = new QGridLayout(this); | ||
|
||
int row = 0; | ||
for (const auto &arg : arguments) { | ||
QLabel *name = new QLabel(this); | ||
name->setText(arg); | ||
|
||
QWidget *value; | ||
|
||
if (arg == "integer") { | ||
QSpinBox *integer = new QSpinBox(this); | ||
integer->setMinimum(0); | ||
value = integer; | ||
layout->addWidget(value, row, 1); | ||
} else if (arg == "string") { | ||
QLineEdit *lineEdit = new QLineEdit(this); | ||
lineEdit->setText(tr("MyCustomEvent")); | ||
value = lineEdit; | ||
layout->addWidget(value, row, 1); | ||
} else if (arg == "object") { | ||
QHBoxLayout *objLayout = new QHBoxLayout(); | ||
QToolButton *objButton = new QToolButton(this); | ||
|
||
QMenuView *objMenu = new QMenuView(this); | ||
TreeSortFilterProxyModel *treeProxy = new TreeSortFilterProxyModel(this); | ||
treeProxy->SetFilterType(TreeNode::TypeCase::kObject); | ||
treeProxy->setSourceModel(MainWindow::treeModel.get()); | ||
objMenu->setModel(treeProxy); | ||
objButton->setMenu(objMenu); | ||
objButton->setPopupMode(QToolButton::MenuButtonPopup); | ||
|
||
QLineEdit *lineEdit = new QLineEdit(this); | ||
lineEdit->setReadOnly(true); | ||
QModelIndex firstObjIdx = treeProxy | ||
->match(treeProxy->index(0, 0), TreeModel::UserRoles::TypeCaseRole, | ||
TypeCase::kObject, 1, Qt::MatchRecursive) | ||
.first(); | ||
QString firstObj = firstObjIdx.data(Qt::DisplayRole).toString(); | ||
objButton->setIcon(firstObjIdx.data(Qt::DecorationRole).value<QIcon>()); | ||
lineEdit->setText(firstObj); | ||
|
||
connect(objMenu, &QMenuView::triggered, [=](const QModelIndex &index) { | ||
lineEdit->setText(treeProxy->data(index, Qt::DisplayRole).toString()); | ||
objButton->setIcon(treeProxy->data(index, Qt::DecorationRole).value<QIcon>()); | ||
}); | ||
|
||
objLayout->addWidget(lineEdit); | ||
objLayout->addWidget(objButton); | ||
|
||
layout->addItem(objLayout, row, 1); | ||
|
||
value = lineEdit; | ||
} else { | ||
QComboBox *combo = new QComboBox(this); | ||
auto argList = MainWindow::GetEventData()->value_names_for_type(name->text().toStdString()); | ||
for (auto a : argList) { | ||
combo->addItem(QString::fromStdString(a.first)); | ||
} | ||
value = combo; | ||
layout->addWidget(value, row, 1); | ||
} | ||
|
||
widgets_.append(value); | ||
|
||
layout->addWidget(name, row, 0); | ||
row++; | ||
} | ||
|
||
QDialogButtonBox *btn = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); | ||
layout->addWidget(btn, row, 1); | ||
connect(btn, SIGNAL(accepted()), this, SLOT(accept())); | ||
connect(btn, SIGNAL(rejected()), this, SLOT(reject())); | ||
|
||
setWindowTitle(tr("Event arguments")); | ||
} | ||
|
||
const QStringList &EventArgumentsDialog::GetArguments() const { return arguments_; } | ||
|
||
void EventArgumentsDialog::done(int r) { | ||
for (const QWidget *w : widgets_) { | ||
QVariant argument = w->metaObject()->userProperty().read(w); | ||
QString argstr = ""; | ||
if (argument.isValid()) | ||
argstr = argument.toString(); | ||
arguments_.append(argstr); | ||
} | ||
|
||
QDialog::done(r); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#ifndef EVENTARGUMENTSDIALOG_H | ||
#define EVENTARGUMENTSDIALOG_H | ||
|
||
#include "event_reader/event_parser.h" | ||
|
||
#include <QDialog> | ||
|
||
class EventArgumentsDialog : public QDialog | ||
{ | ||
Q_OBJECT | ||
public: | ||
EventArgumentsDialog(QWidget* parent, const QStringList& arguments); | ||
const QStringList& GetArguments() const; | ||
void done(int r) override; | ||
|
||
private: | ||
QStringList arguments_; | ||
QVector<QWidget*> widgets_; | ||
}; | ||
|
||
#endif // EVENTARGUMENTSDIALOG_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,194 @@ | ||
#include "ObjectEditor.h" | ||
#include "Components/QMenuView.h" | ||
#include "Dialogs/EventArgumentsDialog.h" | ||
#include "MainWindow.h" | ||
#include "Models/EventTypesListModel.h" | ||
#include "Models/RepeatedMessageModel.h" | ||
#include "Models/RepeatedStringModel.h" | ||
|
||
#include "ui_ObjectEditor.h" | ||
|
||
ObjectEditor::ObjectEditor(MessageModel* model, QWidget* parent) : BaseEditor(model, parent), _ui(new Ui::ObjectEditor) { | ||
#include <QSplitter> | ||
|
||
void ObjectEditor::BindEventMenu(QToolButton *btn, bool add) { | ||
QMenuView *eventsMenu = new QMenuView(this); | ||
eventsMenu->setModel(_eventsTypesModel); | ||
eventsMenu->setToolTipsVisible(true); | ||
btn->setMenu(eventsMenu); | ||
connect(eventsMenu, &QMenuView::triggered, [=](const QModelIndex &index) { AddChangeFromMenuEvent(index, add); }); | ||
} | ||
|
||
ObjectEditor::ObjectEditor(MessageModel *model, QWidget *parent) | ||
: BaseEditor(model, parent), _ui(new Ui::ObjectEditor) { | ||
_ui->setupUi(this); | ||
|
||
_nodeMapper->addMapping(_ui->nameEdit, TreeNode::kNameFieldNumber); | ||
|
||
connect(_ui->saveButton, &QAbstractButton::pressed, this, &BaseEditor::OnSave); | ||
|
||
_eventsModel = new EventsListModel(MainWindow::GetEventData(), this); | ||
|
||
EventTypesListModel *m = new EventTypesListModel(MainWindow::GetEventData(), this); | ||
_eventsTypesModel = new EventTypesListSortFilterProxyModel(m); | ||
_eventsTypesModel->setSourceModel(m); | ||
_eventsTypesModel->sort(0); | ||
|
||
BindEventMenu(_ui->addEventButton, true); | ||
BindEventMenu(_ui->changeEventButton, false); | ||
|
||
RebindSubModels(); | ||
} | ||
|
||
ObjectEditor::~ObjectEditor() { delete _ui; } | ||
|
||
void ObjectEditor::AddChangeEventHelper(const Object::EgmEvent &event, bool add) { | ||
if (add) { | ||
AddEvent(event); | ||
} else { | ||
int existingIdx = MapRowFrom(IndexOf(event)); | ||
int selectedIdx = MapRowTo(_ui->eventsList->selectionModel()->currentIndex().row()); | ||
if (existingIdx == -1 && selectedIdx != -1) { | ||
ChangeEvent(selectedIdx, event, false); | ||
} else | ||
qDebug() << "Change event failed"; | ||
} | ||
} | ||
|
||
void ObjectEditor::AddChangeFromMenuEvent(const QModelIndex &index, bool add) { | ||
QStringList args = _eventsTypesModel->data(index, EventTypesListModel::UserRoles::EventArgumentsRole).toStringList(); | ||
EventArgumentsDialog *dialog = nullptr; | ||
if (args.size() > 0) { | ||
dialog = new EventArgumentsDialog(this, args); | ||
dialog->open(); | ||
|
||
connect(dialog, &QDialog::accepted, [=]() { | ||
if (dialog->result() == QDialog::Accepted) { | ||
Object::EgmEvent event; | ||
event.set_id( | ||
_eventsTypesModel->data(index, EventTypesListModel::UserRoles::EventBareIDRole).toString().toStdString()); | ||
for (const QString &arg : dialog->GetArguments()) { | ||
std::string *s = event.add_arguments(); | ||
s->assign(arg.toStdString()); | ||
} | ||
|
||
AddChangeEventHelper(event, add); | ||
} | ||
}); | ||
} else { | ||
Object::EgmEvent event; | ||
event.set_id( | ||
_eventsTypesModel->data(index, EventTypesListModel::UserRoles::EventBareIDRole).toString().toStdString()); | ||
AddChangeEventHelper(event, add); | ||
} | ||
} | ||
|
||
void ObjectEditor::RebindSubModels() { | ||
_objectModel = _model->GetSubModel<MessageModel *>(TreeNode::kObjectFieldNumber); | ||
_eventsModel->setSourceModel(_objectModel->GetSubModel<RepeatedMessageModel *>(Object::kEgmEventsFieldNumber)); | ||
|
||
_sortedEvents = new QSortFilterProxyModel(_eventsModel); | ||
_sortedEvents->setSourceModel(_eventsModel); | ||
_sortedEvents->sort(0); | ||
_sortedEvents->setDynamicSortFilter(true); | ||
_ui->eventsList->setModel(_sortedEvents); | ||
|
||
connect(_ui->eventsList, &QAbstractItemView::clicked, | ||
[=](const QModelIndex &index) { SetCurrentEditor(MapRowTo(index.row())); }); | ||
|
||
connect(_ui->deleteEventButton, &QToolButton::pressed, [=]() { | ||
QModelIndex selection = _ui->eventsList->selectionModel()->currentIndex(); | ||
if (selection.row() != -1) RemoveEvent(MapRowTo(selection.row())); | ||
}); | ||
|
||
for (int event = 0; event < _eventsModel->rowCount(); ++event) { | ||
BindEventEditor(event); | ||
} | ||
|
||
SetCurrentEditor(MapRowFrom(0)); | ||
CheckDisableButtons(); | ||
|
||
BaseEditor::RebindSubModels(); | ||
} | ||
|
||
void ObjectEditor::CheckDisableButtons() { | ||
bool hasEvents = _sortedEvents->rowCount() > 0; | ||
_ui->changeEventButton->setDisabled(!hasEvents); | ||
_ui->deleteEventButton->setDisabled(!hasEvents); | ||
_ui->codeEditor->setDisabled(!hasEvents); | ||
if (!hasEvents) _ui->eventLineEdit->setText(""); | ||
} | ||
|
||
void ObjectEditor::AddEvent(Object::EgmEvent event) { | ||
RepeatedMessageModel *eventsModel = _objectModel->GetSubModel<RepeatedMessageModel *>(Object::kEgmEventsFieldNumber); | ||
int idx = eventsModel->rowCount(); | ||
|
||
if (IndexOf(event) == -1) { | ||
bool insert = eventsModel->insertRow(idx); | ||
if (insert) { | ||
BindEventEditor(idx); | ||
ChangeEvent(idx, event); | ||
} | ||
} else | ||
qDebug() << "Event already exists"; | ||
} | ||
|
||
void ObjectEditor::ChangeEvent(int idx, Object::EgmEvent event, bool changeCode) { | ||
RepeatedMessageModel *eventsModel = _objectModel->GetSubModel<RepeatedMessageModel *>(Object::kEgmEventsFieldNumber); | ||
|
||
eventsModel->SetData(QString::fromStdString(event.id()), idx, Object::EgmEvent::kIdFieldNumber); | ||
|
||
if (changeCode) eventsModel->SetData(QString::fromStdString(event.code()), idx, Object::EgmEvent::kCodeFieldNumber); | ||
|
||
RepeatedStringModel *argsModel = eventsModel->GetSubModel<MessageModel *>(idx)->GetSubModel<RepeatedStringModel *>( | ||
Object::EgmEvent::kArgumentsFieldNumber); | ||
|
||
size_t argc = 0; | ||
argsModel->removeRows(0, argsModel->rowCount()); // clear old arguments | ||
if (event.arguments_size() > 0) { | ||
argsModel->insertRows(argsModel->rowCount(), event.arguments_size()); | ||
for (const auto &arg : event.arguments()) { | ||
argsModel->SetData(QString::fromStdString(arg), argc++); | ||
} | ||
} | ||
|
||
SetCurrentEditor(idx); | ||
CheckDisableButtons(); | ||
} | ||
|
||
void ObjectEditor::RemoveEvent(int idx) { | ||
RepeatedMessageModel *eventsModel = _objectModel->GetSubModel<RepeatedMessageModel *>(Object::kEgmEventsFieldNumber); | ||
eventsModel->removeRow(idx); | ||
_ui->codeEditor->RemoveCodeWidget(idx); | ||
SetCurrentEditor(MapRowFrom(0)); | ||
CheckDisableButtons(); | ||
} | ||
|
||
int ObjectEditor::IndexOf(Object::EgmEvent event) { | ||
std::vector<std::string> args(event.arguments().begin(), event.arguments().end()); | ||
Event e = MainWindow::GetEventData()->get_event(event.id(), args); | ||
for (int i = 0; i < _eventsModel->rowCount(); ++i) { | ||
if (_eventsModel->data(_eventsModel->index(i, 0)).toString() == QString::fromStdString(e.HumanName())) return i; | ||
} | ||
return -1; | ||
} | ||
|
||
void ObjectEditor::BindEventEditor(int idx) { | ||
RepeatedMessageModel *eventsModel = _objectModel->GetSubModel<RepeatedMessageModel *>(Object::kEgmEventsFieldNumber); | ||
CodeWidget *codeWidget = _ui->codeEditor->AddCodeWidget(); | ||
ModelMapper *mapper(new ModelMapper(eventsModel->GetSubModel<MessageModel *>(idx), this)); | ||
mapper->addMapping(codeWidget, Object::EgmEvent::kCodeFieldNumber); | ||
mapper->toFirst(); | ||
} | ||
|
||
void ObjectEditor::SetCurrentEditor(int idx) { | ||
if (idx < _sortedEvents->rowCount()) { | ||
_ui->codeEditor->SetCurrentIndex(idx); | ||
_ui->eventLineEdit->setText(_eventsModel->data(_eventsModel->index(idx, 0)).toString()); | ||
_ui->eventsList->selectionModel()->select(_sortedEvents->index(MapRowFrom(idx), 0), | ||
QItemSelectionModel::QItemSelectionModel::ClearAndSelect); | ||
} | ||
} | ||
|
||
int ObjectEditor::MapRowTo(int row) { return _sortedEvents->mapToSource(_sortedEvents->index(row, 0)).row(); } | ||
|
||
int ObjectEditor::MapRowFrom(int row) { return _sortedEvents->mapFromSource(_eventsModel->index(row, 0)).row(); } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are the arguments string and not QVariant or something. Why aren't we using real reflection over the event proto here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because they're strings... Arguments are "object", "integer" or "string"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what's in event data? Strings is what the shared event stuff gives you to work with? I don't know why Josh would do it that way and not give an enum or some other typed way of doing it.