merged world editor qt to default
|
@ -19,14 +19,15 @@
|
||||||
|
|
||||||
#include "nel/ligo/zone_bank.h"
|
#include "nel/ligo/zone_bank.h"
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
#include "nel/misc/debug.h"
|
#include "nel/misc/debug.h"
|
||||||
#include "nel/misc/file.h"
|
#include "nel/misc/file.h"
|
||||||
#include "nel/misc/i_xml.h"
|
#include "nel/misc/i_xml.h"
|
||||||
#include "nel/misc/o_xml.h"
|
#include "nel/misc/o_xml.h"
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#endif // NL_OS_WINDOWS
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace NLMISC;
|
using namespace NLMISC;
|
||||||
|
@ -496,8 +497,9 @@ void CZoneBank::reset ()
|
||||||
_Selection.clear ();
|
_Selection.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
bool CZoneBank::initFromPath(const string &sPathName, std::string &error)
|
bool CZoneBank::initFromPath(const std::string &sPathName, std::string &error)
|
||||||
{
|
{
|
||||||
char sDirBackup[512];
|
char sDirBackup[512];
|
||||||
GetCurrentDirectory (512, sDirBackup);
|
GetCurrentDirectory (512, sDirBackup);
|
||||||
|
@ -520,6 +522,7 @@ bool CZoneBank::initFromPath(const string &sPathName, std::string &error)
|
||||||
SetCurrentDirectory (sDirBackup);
|
SetCurrentDirectory (sDirBackup);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif // NL_OS_WINDOWS
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
bool CZoneBank::addElement (const std::string &elementName, std::string &error)
|
bool CZoneBank::addElement (const std::string &elementName, std::string &error)
|
||||||
|
@ -695,5 +698,3 @@ void CZoneBank::getSelection (std::vector<CZoneBankElement*> &SelectedElements)
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
} // namespace NLLIGO
|
} // namespace NLLIGO
|
||||||
|
|
||||||
#endif // NL_OS_WINDOWS
|
|
||||||
|
|
BIN
code/nel/tools/3d/object_viewer_qt/src/3rdparty/qtpropertybrowser/images/resetproperty.png
vendored
Normal file
After Width: | Height: | Size: 169 B |
|
@ -101,6 +101,13 @@
|
||||||
#include <QtGui/QToolButton>
|
#include <QtGui/QToolButton>
|
||||||
#include <QtGui/QColorDialog>
|
#include <QtGui/QColorDialog>
|
||||||
#include <QtGui/QFontDialog>
|
#include <QtGui/QFontDialog>
|
||||||
|
#include <QtGui/QDialog>
|
||||||
|
#include <QtGui/QPlainTextEdit>
|
||||||
|
#include <QtGui/QTextEdit>
|
||||||
|
#include <QCompleter>
|
||||||
|
#include <QColumnView>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QtGui/QDialogButtonBox>
|
||||||
#include <QtGui/QSpacerItem>
|
#include <QtGui/QSpacerItem>
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
|
|
||||||
|
@ -652,6 +659,7 @@ class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate<QtBoolEdit>
|
||||||
public:
|
public:
|
||||||
void slotPropertyChanged(QtProperty *property, bool value);
|
void slotPropertyChanged(QtProperty *property, bool value);
|
||||||
void slotSetValue(bool value);
|
void slotSetValue(bool value);
|
||||||
|
void slotResetProperty();
|
||||||
};
|
};
|
||||||
|
|
||||||
void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value)
|
void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value)
|
||||||
|
@ -662,6 +670,7 @@ void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool va
|
||||||
QListIterator<QtBoolEdit *> itEditor(m_createdEditors[property]);
|
QListIterator<QtBoolEdit *> itEditor(m_createdEditors[property]);
|
||||||
while (itEditor.hasNext()) {
|
while (itEditor.hasNext()) {
|
||||||
QtBoolEdit *editor = itEditor.next();
|
QtBoolEdit *editor = itEditor.next();
|
||||||
|
editor->setStateResetButton(property->isModified());
|
||||||
editor->blockCheckBoxSignals(true);
|
editor->blockCheckBoxSignals(true);
|
||||||
editor->setChecked(value);
|
editor->setChecked(value);
|
||||||
editor->blockCheckBoxSignals(false);
|
editor->blockCheckBoxSignals(false);
|
||||||
|
@ -684,6 +693,22 @@ void QtCheckBoxFactoryPrivate::slotSetValue(bool value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtCheckBoxFactoryPrivate::slotResetProperty()
|
||||||
|
{
|
||||||
|
QObject *object = q_ptr->sender();
|
||||||
|
|
||||||
|
const QMap<QtBoolEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
|
||||||
|
for (QMap<QtBoolEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
|
||||||
|
if (itEditor.key() == object) {
|
||||||
|
QtProperty *property = itEditor.value();
|
||||||
|
QtBoolPropertyManager *manager = q_ptr->propertyManager(property);
|
||||||
|
if (!manager)
|
||||||
|
return;
|
||||||
|
manager->emitResetProperty(property);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class QtCheckBoxFactory
|
\class QtCheckBoxFactory
|
||||||
|
|
||||||
|
@ -733,8 +758,10 @@ QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtPrope
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
{
|
{
|
||||||
QtBoolEdit *editor = d_ptr->createEditor(property, parent);
|
QtBoolEdit *editor = d_ptr->createEditor(property, parent);
|
||||||
|
editor->setStateResetButton(property->isModified());
|
||||||
editor->setChecked(manager->value(property));
|
editor->setChecked(manager->value(property));
|
||||||
|
|
||||||
|
connect(editor, SIGNAL(resetProperty()), this, SLOT(slotResetProperty()));
|
||||||
connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool)));
|
connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool)));
|
||||||
connect(editor, SIGNAL(destroyed(QObject *)),
|
connect(editor, SIGNAL(destroyed(QObject *)),
|
||||||
this, SLOT(slotEditorDestroyed(QObject *)));
|
this, SLOT(slotEditorDestroyed(QObject *)));
|
||||||
|
@ -1853,9 +1880,87 @@ void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager *manag
|
||||||
this, SLOT(slotPropertyChanged(QtProperty *, const QChar &)));
|
this, SLOT(slotPropertyChanged(QtProperty *, const QChar &)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class QtEnumEditWidget : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QtEnumEditWidget(QWidget *parent);
|
||||||
|
|
||||||
|
bool blockComboBoxSignals(bool block);
|
||||||
|
void addItems(const QStringList &texts);
|
||||||
|
void clearComboBox();
|
||||||
|
void setItemIcon(int index, const QIcon &icon);
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void setValue(int value);
|
||||||
|
void setStateResetButton(bool enabled);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void valueChanged(int value);
|
||||||
|
void resetProperty();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QComboBox *m_comboBox;
|
||||||
|
QToolButton *m_defaultButton;
|
||||||
|
};
|
||||||
|
|
||||||
|
QtEnumEditWidget::QtEnumEditWidget(QWidget *parent) :
|
||||||
|
QWidget(parent),
|
||||||
|
m_comboBox(new QComboBox),
|
||||||
|
m_defaultButton(new QToolButton)
|
||||||
|
{
|
||||||
|
m_comboBox->view()->setTextElideMode(Qt::ElideRight);
|
||||||
|
|
||||||
|
QHBoxLayout *lt = new QHBoxLayout(this);
|
||||||
|
lt->setContentsMargins(0, 0, 0, 0);
|
||||||
|
lt->setSpacing(0);
|
||||||
|
lt->addWidget(m_comboBox);
|
||||||
|
|
||||||
|
m_defaultButton->setIcon(QIcon(":/trolltech/qtpropertybrowser/images/resetproperty.png"));
|
||||||
|
m_defaultButton->setMaximumWidth(16);
|
||||||
|
|
||||||
|
connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(valueChanged(int)));
|
||||||
|
connect(m_defaultButton, SIGNAL(clicked()), this, SIGNAL(resetProperty()));
|
||||||
|
lt->addWidget(m_defaultButton);
|
||||||
|
m_defaultButton->setEnabled(false);
|
||||||
|
setFocusProxy(m_comboBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtEnumEditWidget::setValue(int value)
|
||||||
|
{
|
||||||
|
if (m_comboBox->currentIndex() != value)
|
||||||
|
m_comboBox->setCurrentIndex(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtEnumEditWidget::setStateResetButton(bool enabled)
|
||||||
|
{
|
||||||
|
m_defaultButton->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtEnumEditWidget::blockComboBoxSignals(bool block)
|
||||||
|
{
|
||||||
|
return m_comboBox->blockSignals(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtEnumEditWidget::addItems(const QStringList &texts)
|
||||||
|
{
|
||||||
|
m_comboBox->addItems(texts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtEnumEditWidget::clearComboBox()
|
||||||
|
{
|
||||||
|
m_comboBox->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtEnumEditWidget::setItemIcon(int index, const QIcon &icon)
|
||||||
|
{
|
||||||
|
m_comboBox->setItemIcon(index, icon);
|
||||||
|
}
|
||||||
|
|
||||||
// QtEnumEditorFactory
|
// QtEnumEditorFactory
|
||||||
|
|
||||||
class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate<QComboBox>
|
class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate<QtEnumEditWidget>
|
||||||
{
|
{
|
||||||
QtEnumEditorFactory *q_ptr;
|
QtEnumEditorFactory *q_ptr;
|
||||||
Q_DECLARE_PUBLIC(QtEnumEditorFactory)
|
Q_DECLARE_PUBLIC(QtEnumEditorFactory)
|
||||||
|
@ -1865,19 +1970,36 @@ public:
|
||||||
void slotEnumNamesChanged(QtProperty *property, const QStringList &);
|
void slotEnumNamesChanged(QtProperty *property, const QStringList &);
|
||||||
void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &);
|
void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &);
|
||||||
void slotSetValue(int value);
|
void slotSetValue(int value);
|
||||||
|
void slotResetProperty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void QtEnumEditorFactoryPrivate::slotResetProperty()
|
||||||
|
{
|
||||||
|
QObject *object = q_ptr->sender();
|
||||||
|
const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
|
||||||
|
for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
|
||||||
|
if (itEditor.key() == object) {
|
||||||
|
QtProperty *property = itEditor.value();
|
||||||
|
QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
|
||||||
|
if (!manager)
|
||||||
|
return;
|
||||||
|
manager->emitResetProperty(property);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
|
void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
|
||||||
{
|
{
|
||||||
if (!m_createdEditors.contains(property))
|
if (!m_createdEditors.contains(property))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
|
QListIterator<QtEnumEditWidget *> itEditor(m_createdEditors[property]);
|
||||||
while (itEditor.hasNext()) {
|
while (itEditor.hasNext()) {
|
||||||
QComboBox *editor = itEditor.next();
|
QtEnumEditWidget *editor = itEditor.next();
|
||||||
editor->blockSignals(true);
|
editor->setStateResetButton(property->isModified());
|
||||||
editor->setCurrentIndex(value);
|
editor->blockComboBoxSignals(true);
|
||||||
editor->blockSignals(false);
|
editor->setValue(value);
|
||||||
|
editor->blockComboBoxSignals(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1893,17 +2015,17 @@ void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property,
|
||||||
|
|
||||||
QMap<int, QIcon> enumIcons = manager->enumIcons(property);
|
QMap<int, QIcon> enumIcons = manager->enumIcons(property);
|
||||||
|
|
||||||
QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
|
QListIterator<QtEnumEditWidget *> itEditor(m_createdEditors[property]);
|
||||||
while (itEditor.hasNext()) {
|
while (itEditor.hasNext()) {
|
||||||
QComboBox *editor = itEditor.next();
|
QtEnumEditWidget *editor = itEditor.next();
|
||||||
editor->blockSignals(true);
|
editor->blockComboBoxSignals(true);
|
||||||
editor->clear();
|
editor->clearComboBox();
|
||||||
editor->addItems(enumNames);
|
editor->addItems(enumNames);
|
||||||
const int nameCount = enumNames.count();
|
const int nameCount = enumNames.count();
|
||||||
for (int i = 0; i < nameCount; i++)
|
for (int i = 0; i < nameCount; i++)
|
||||||
editor->setItemIcon(i, enumIcons.value(i));
|
editor->setItemIcon(i, enumIcons.value(i));
|
||||||
editor->setCurrentIndex(manager->value(property));
|
editor->setValue(manager->value(property));
|
||||||
editor->blockSignals(false);
|
editor->blockComboBoxSignals(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1918,23 +2040,23 @@ void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const QStringList enumNames = manager->enumNames(property);
|
const QStringList enumNames = manager->enumNames(property);
|
||||||
QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
|
QListIterator<QtEnumEditWidget *> itEditor(m_createdEditors[property]);
|
||||||
while (itEditor.hasNext()) {
|
while (itEditor.hasNext()) {
|
||||||
QComboBox *editor = itEditor.next();
|
QtEnumEditWidget *editor = itEditor.next();
|
||||||
editor->blockSignals(true);
|
editor->blockComboBoxSignals(true);
|
||||||
const int nameCount = enumNames.count();
|
const int nameCount = enumNames.count();
|
||||||
for (int i = 0; i < nameCount; i++)
|
for (int i = 0; i < nameCount; i++)
|
||||||
editor->setItemIcon(i, enumIcons.value(i));
|
editor->setItemIcon(i, enumIcons.value(i));
|
||||||
editor->setCurrentIndex(manager->value(property));
|
editor->setValue(manager->value(property));
|
||||||
editor->blockSignals(false);
|
editor->blockComboBoxSignals(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtEnumEditorFactoryPrivate::slotSetValue(int value)
|
void QtEnumEditorFactoryPrivate::slotSetValue(int value)
|
||||||
{
|
{
|
||||||
QObject *object = q_ptr->sender();
|
QObject *object = q_ptr->sender();
|
||||||
const QMap<QComboBox *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
|
const QMap<QtEnumEditWidget *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
|
||||||
for (QMap<QComboBox *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
|
for (QMap<QtEnumEditWidget *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
|
||||||
if (itEditor.key() == object) {
|
if (itEditor.key() == object) {
|
||||||
QtProperty *property = itEditor.value();
|
QtProperty *property = itEditor.value();
|
||||||
QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
|
QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
|
||||||
|
@ -1995,18 +2117,19 @@ void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager)
|
||||||
QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property,
|
QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property,
|
||||||
QWidget *parent)
|
QWidget *parent)
|
||||||
{
|
{
|
||||||
QComboBox *editor = d_ptr->createEditor(property, parent);
|
QtEnumEditWidget *editor = d_ptr->createEditor(property, parent);
|
||||||
editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||||
editor->view()->setTextElideMode(Qt::ElideRight);
|
|
||||||
QStringList enumNames = manager->enumNames(property);
|
QStringList enumNames = manager->enumNames(property);
|
||||||
editor->addItems(enumNames);
|
editor->addItems(enumNames);
|
||||||
QMap<int, QIcon> enumIcons = manager->enumIcons(property);
|
QMap<int, QIcon> enumIcons = manager->enumIcons(property);
|
||||||
const int enumNamesCount = enumNames.count();
|
const int enumNamesCount = enumNames.count();
|
||||||
for (int i = 0; i < enumNamesCount; i++)
|
for (int i = 0; i < enumNamesCount; i++)
|
||||||
editor->setItemIcon(i, enumIcons.value(i));
|
editor->setItemIcon(i, enumIcons.value(i));
|
||||||
editor->setCurrentIndex(manager->value(property));
|
editor->setValue(manager->value(property));
|
||||||
|
editor->setStateResetButton(property->isModified());
|
||||||
|
|
||||||
connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int)));
|
connect(editor, SIGNAL(resetProperty()), this, SLOT(slotResetProperty()));
|
||||||
|
connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
|
||||||
connect(editor, SIGNAL(destroyed(QObject *)),
|
connect(editor, SIGNAL(destroyed(QObject *)),
|
||||||
this, SLOT(slotEditorDestroyed(QObject *)));
|
this, SLOT(slotEditorDestroyed(QObject *)));
|
||||||
return editor;
|
return editor;
|
||||||
|
@ -2601,6 +2724,267 @@ void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manag
|
||||||
disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont)));
|
disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class QtTextEditWidget : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QtTextEditWidget(QWidget *parent);
|
||||||
|
|
||||||
|
bool eventFilter(QObject *obj, QEvent *ev);
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void setValue(const QString &value);
|
||||||
|
void setStateResetButton(bool enabled);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void buttonClicked();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void valueChanged(const QString &value);
|
||||||
|
void resetProperty();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLineEdit *m_lineEdit;
|
||||||
|
QToolButton *m_defaultButton;
|
||||||
|
QToolButton *m_button;
|
||||||
|
};
|
||||||
|
|
||||||
|
QtTextEditWidget::QtTextEditWidget(QWidget *parent) :
|
||||||
|
QWidget(parent),
|
||||||
|
m_lineEdit(new QLineEdit),
|
||||||
|
m_defaultButton(new QToolButton),
|
||||||
|
m_button(new QToolButton)
|
||||||
|
{
|
||||||
|
QHBoxLayout *lt = new QHBoxLayout(this);
|
||||||
|
lt->setContentsMargins(0, 0, 0, 0);
|
||||||
|
lt->setSpacing(0);
|
||||||
|
lt->addWidget(m_lineEdit);
|
||||||
|
m_lineEdit->setReadOnly(true);
|
||||||
|
|
||||||
|
m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
|
||||||
|
m_button->setFixedWidth(20);
|
||||||
|
m_button->setText(tr("..."));
|
||||||
|
m_button->installEventFilter(this);
|
||||||
|
|
||||||
|
setFocusProxy(m_button);
|
||||||
|
setFocusPolicy(m_button->focusPolicy());
|
||||||
|
|
||||||
|
m_defaultButton->setIcon(QIcon(":/trolltech/qtpropertybrowser/images/resetproperty.png"));
|
||||||
|
m_defaultButton->setMaximumWidth(16);
|
||||||
|
|
||||||
|
connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
|
||||||
|
connect(m_defaultButton, SIGNAL(clicked()), this, SIGNAL(resetProperty()));
|
||||||
|
lt->addWidget(m_button);
|
||||||
|
lt->addWidget(m_defaultButton);
|
||||||
|
m_defaultButton->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtTextEditWidget::setValue(const QString &value)
|
||||||
|
{
|
||||||
|
if (m_lineEdit->text() != value)
|
||||||
|
m_lineEdit->setText(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtTextEditWidget::setStateResetButton(bool enabled)
|
||||||
|
{
|
||||||
|
m_defaultButton->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtTextEditWidget::buttonClicked()
|
||||||
|
{
|
||||||
|
QGridLayout *gridLayout;
|
||||||
|
QPlainTextEdit *plainTextEdit;
|
||||||
|
QDialogButtonBox *buttonBox;
|
||||||
|
QDialog *dialog;
|
||||||
|
|
||||||
|
dialog = new QDialog(this);
|
||||||
|
dialog->resize(400, 300);
|
||||||
|
gridLayout = new QGridLayout(dialog);
|
||||||
|
plainTextEdit = new QPlainTextEdit(dialog);
|
||||||
|
|
||||||
|
gridLayout->addWidget(plainTextEdit, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
buttonBox = new QDialogButtonBox(dialog);
|
||||||
|
buttonBox->setOrientation(Qt::Horizontal);
|
||||||
|
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
|
||||||
|
|
||||||
|
gridLayout->addWidget(buttonBox, 1, 0, 1, 1);
|
||||||
|
|
||||||
|
QObject::connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
|
||||||
|
QObject::connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
|
||||||
|
|
||||||
|
plainTextEdit->textCursor().insertText(m_lineEdit->text());
|
||||||
|
|
||||||
|
dialog->setModal(true);
|
||||||
|
dialog->show();
|
||||||
|
int result = dialog->exec();
|
||||||
|
|
||||||
|
if (result == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
QString newText = plainTextEdit->document()->toPlainText();
|
||||||
|
|
||||||
|
setValue(newText);
|
||||||
|
if (plainTextEdit->document()->isModified())
|
||||||
|
Q_EMIT valueChanged(newText);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtTextEditWidget::eventFilter(QObject *obj, QEvent *ev)
|
||||||
|
{
|
||||||
|
if (obj == m_button) {
|
||||||
|
switch (ev->type()) {
|
||||||
|
case QEvent::KeyPress:
|
||||||
|
case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
|
||||||
|
switch (static_cast<const QKeyEvent*>(ev)->key()) {
|
||||||
|
case Qt::Key_Escape:
|
||||||
|
case Qt::Key_Enter:
|
||||||
|
case Qt::Key_Return:
|
||||||
|
ev->ignore();
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QWidget::eventFilter(obj, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
// QtLineEditFactory
|
||||||
|
|
||||||
|
class QtTextEditorFactoryPrivate : public EditorFactoryPrivate<QtTextEditWidget>
|
||||||
|
{
|
||||||
|
QtTextEditorFactory *q_ptr;
|
||||||
|
Q_DECLARE_PUBLIC(QtTextEditorFactory)
|
||||||
|
public:
|
||||||
|
|
||||||
|
void slotPropertyChanged(QtProperty *property, const QString &value);
|
||||||
|
void slotSetValue(const QString &value);
|
||||||
|
void slotResetProperty();
|
||||||
|
};
|
||||||
|
|
||||||
|
void QtTextEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
|
||||||
|
const QString &value)
|
||||||
|
{
|
||||||
|
const PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
|
||||||
|
if (it == m_createdEditors.end())
|
||||||
|
return;
|
||||||
|
QListIterator<QtTextEditWidget *> itEditor(it.value());
|
||||||
|
|
||||||
|
while (itEditor.hasNext())
|
||||||
|
{
|
||||||
|
QtTextEditWidget *editor = itEditor.next();
|
||||||
|
editor->setValue(value);
|
||||||
|
editor->setStateResetButton(property->isModified());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtTextEditorFactoryPrivate::slotSetValue(const QString &value)
|
||||||
|
{
|
||||||
|
QObject *object = q_ptr->sender();
|
||||||
|
const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
|
||||||
|
for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
|
||||||
|
if (itEditor.key() == object) {
|
||||||
|
QtProperty *property = itEditor.value();
|
||||||
|
QtTextPropertyManager *manager = q_ptr->propertyManager(property);
|
||||||
|
if (!manager)
|
||||||
|
return;
|
||||||
|
manager->setValue(property, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtTextEditorFactoryPrivate::slotResetProperty()
|
||||||
|
{
|
||||||
|
QObject *object = q_ptr->sender();
|
||||||
|
const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
|
||||||
|
for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
|
||||||
|
if (itEditor.key() == object) {
|
||||||
|
QtProperty *property = itEditor.value();
|
||||||
|
QtTextPropertyManager *manager = q_ptr->propertyManager(property);
|
||||||
|
if (!manager)
|
||||||
|
return;
|
||||||
|
manager->emitResetProperty(property);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QtTextEditFactory
|
||||||
|
|
||||||
|
\brief The QtTextEditFactory class provides QTextEdit widgets for
|
||||||
|
properties created by QtStringPropertyManager objects.
|
||||||
|
|
||||||
|
\sa QtAbstractEditorFactory, QtStringPropertyManager
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a factory with the given \a parent.
|
||||||
|
*/
|
||||||
|
QtTextEditorFactory::QtTextEditorFactory(QObject *parent)
|
||||||
|
: QtAbstractEditorFactory<QtTextPropertyManager>(parent)
|
||||||
|
{
|
||||||
|
d_ptr = new QtTextEditorFactoryPrivate();
|
||||||
|
d_ptr->q_ptr = this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Destroys this factory, and all the widgets it has created.
|
||||||
|
*/
|
||||||
|
QtTextEditorFactory::~QtTextEditorFactory()
|
||||||
|
{
|
||||||
|
qDeleteAll(d_ptr->m_editorToProperty.keys());
|
||||||
|
delete d_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
|
||||||
|
Reimplemented from the QtAbstractEditorFactory class.
|
||||||
|
*/
|
||||||
|
void QtTextEditorFactory::connectPropertyManager(QtTextPropertyManager *manager)
|
||||||
|
{
|
||||||
|
connect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)),
|
||||||
|
this, SLOT(slotPropertyChanged(QtProperty *, const QString &)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
|
||||||
|
Reimplemented from the QtAbstractEditorFactory class.
|
||||||
|
*/
|
||||||
|
QWidget *QtTextEditorFactory::createEditor(QtTextPropertyManager *manager,
|
||||||
|
QtProperty *property, QWidget *parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
QtTextEditWidget *editor = d_ptr->createEditor(property, parent);
|
||||||
|
|
||||||
|
editor->setValue(manager->value(property));
|
||||||
|
editor->setStateResetButton(property->isModified());
|
||||||
|
|
||||||
|
connect(editor, SIGNAL(resetProperty()), this, SLOT(slotResetProperty()));
|
||||||
|
connect(editor, SIGNAL(valueChanged(QString)), this, SLOT(slotSetValue(QString)));
|
||||||
|
connect(editor, SIGNAL(destroyed(QObject *)), this, SLOT(slotEditorDestroyed(QObject *)));
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
|
||||||
|
Reimplemented from the QtAbstractEditorFactory class.
|
||||||
|
*/
|
||||||
|
void QtTextEditorFactory::disconnectPropertyManager(QtTextPropertyManager *manager)
|
||||||
|
{
|
||||||
|
disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)),
|
||||||
|
this, SLOT(slotPropertyChanged(QtProperty *, const QString &)));
|
||||||
|
}
|
||||||
|
|
||||||
#if QT_VERSION >= 0x040400
|
#if QT_VERSION >= 0x040400
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -186,6 +186,7 @@ private:
|
||||||
Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool))
|
Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool))
|
||||||
Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool))
|
Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool))
|
||||||
Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
|
Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void slotResetProperty())
|
||||||
};
|
};
|
||||||
|
|
||||||
class QtDoubleSpinBoxFactoryPrivate;
|
class QtDoubleSpinBoxFactoryPrivate;
|
||||||
|
@ -373,6 +374,7 @@ private:
|
||||||
const QMap<int, QIcon> &))
|
const QMap<int, QIcon> &))
|
||||||
Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
|
Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
|
||||||
Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
|
Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void slotResetProperty())
|
||||||
};
|
};
|
||||||
|
|
||||||
class QtCursorEditorFactoryPrivate;
|
class QtCursorEditorFactoryPrivate;
|
||||||
|
@ -441,6 +443,29 @@ private:
|
||||||
Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &))
|
Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QtTextEditorFactoryPrivate;
|
||||||
|
|
||||||
|
class QT_QTPROPERTYBROWSER_EXPORT QtTextEditorFactory : public QtAbstractEditorFactory<QtTextPropertyManager>
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QtTextEditorFactory(QObject *parent = 0);
|
||||||
|
~QtTextEditorFactory();
|
||||||
|
protected:
|
||||||
|
void connectPropertyManager(QtTextPropertyManager *manager);
|
||||||
|
QWidget *createEditor(QtTextPropertyManager *manager, QtProperty *property,
|
||||||
|
QWidget *parent);
|
||||||
|
void disconnectPropertyManager(QtTextPropertyManager *manager);
|
||||||
|
private:
|
||||||
|
QtTextEditorFactoryPrivate *d_ptr;
|
||||||
|
Q_DECLARE_PRIVATE(QtTextEditorFactory)
|
||||||
|
Q_DISABLE_COPY(QtTextEditorFactory)
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &))
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &))
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
|
||||||
|
Q_PRIVATE_SLOT(d_func(), void slotResetProperty())
|
||||||
|
};
|
||||||
|
|
||||||
#if QT_VERSION >= 0x040400
|
#if QT_VERSION >= 0x040400
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -808,6 +808,11 @@ QtProperty *QtAbstractPropertyManager::addProperty(const QString &name)
|
||||||
return property;
|
return property;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtAbstractPropertyManager::emitResetProperty(QtProperty *property)
|
||||||
|
{
|
||||||
|
emit resetProperty(property);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Creates a property.
|
Creates a property.
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,7 @@ public:
|
||||||
void clear() const;
|
void clear() const;
|
||||||
|
|
||||||
QtProperty *addProperty(const QString &name = QString());
|
QtProperty *addProperty(const QString &name = QString());
|
||||||
|
void emitResetProperty(QtProperty *property);
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
||||||
void propertyInserted(QtProperty *property,
|
void propertyInserted(QtProperty *property,
|
||||||
|
@ -177,6 +178,7 @@ Q_SIGNALS:
|
||||||
void propertyChanged(QtProperty *property);
|
void propertyChanged(QtProperty *property);
|
||||||
void propertyRemoved(QtProperty *property, QtProperty *parent);
|
void propertyRemoved(QtProperty *property, QtProperty *parent);
|
||||||
void propertyDestroyed(QtProperty *property);
|
void propertyDestroyed(QtProperty *property);
|
||||||
|
void resetProperty(QtProperty *property);
|
||||||
protected:
|
protected:
|
||||||
virtual bool hasValue(const QtProperty *property) const;
|
virtual bool hasValue(const QtProperty *property) const;
|
||||||
virtual QIcon valueIcon(const QtProperty *property) const;
|
virtual QIcon valueIcon(const QtProperty *property) const;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
<file>images/cursor-vsplit.png</file>
|
<file>images/cursor-vsplit.png</file>
|
||||||
<file>images/cursor-wait.png</file>
|
<file>images/cursor-wait.png</file>
|
||||||
<file>images/cursor-whatsthis.png</file>
|
<file>images/cursor-whatsthis.png</file>
|
||||||
|
<file>images/resetproperty.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,7 @@
|
||||||
#include <QtGui/QHBoxLayout>
|
#include <QtGui/QHBoxLayout>
|
||||||
#include <QtGui/QMouseEvent>
|
#include <QtGui/QMouseEvent>
|
||||||
#include <QtGui/QCheckBox>
|
#include <QtGui/QCheckBox>
|
||||||
|
#include <QtGui/QToolButton>
|
||||||
#include <QtGui/QLineEdit>
|
#include <QtGui/QLineEdit>
|
||||||
#include <QtGui/QMenu>
|
#include <QtGui/QMenu>
|
||||||
|
|
||||||
|
@ -260,16 +261,25 @@ QString QtPropertyBrowserUtils::fontValueText(const QFont &f)
|
||||||
QtBoolEdit::QtBoolEdit(QWidget *parent) :
|
QtBoolEdit::QtBoolEdit(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
m_checkBox(new QCheckBox(this)),
|
m_checkBox(new QCheckBox(this)),
|
||||||
|
m_defaultButton(new QToolButton(this)),
|
||||||
m_textVisible(true)
|
m_textVisible(true)
|
||||||
{
|
{
|
||||||
|
m_defaultButton->setIcon(QIcon(":/trolltech/qtpropertybrowser/images/resetproperty.png"));
|
||||||
|
m_defaultButton->setMaximumWidth(16);
|
||||||
|
m_defaultButton->setEnabled(false);
|
||||||
|
|
||||||
QHBoxLayout *lt = new QHBoxLayout;
|
QHBoxLayout *lt = new QHBoxLayout;
|
||||||
if (QApplication::layoutDirection() == Qt::LeftToRight)
|
if (QApplication::layoutDirection() == Qt::LeftToRight)
|
||||||
lt->setContentsMargins(4, 0, 0, 0);
|
lt->setContentsMargins(4, 0, 0, 0);
|
||||||
else
|
else
|
||||||
lt->setContentsMargins(0, 0, 4, 0);
|
lt->setContentsMargins(0, 0, 4, 0);
|
||||||
lt->addWidget(m_checkBox);
|
lt->addWidget(m_checkBox);
|
||||||
|
lt->addWidget(m_defaultButton);
|
||||||
setLayout(lt);
|
setLayout(lt);
|
||||||
|
|
||||||
connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
|
connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
|
||||||
|
connect(m_defaultButton, SIGNAL(clicked()), this, SIGNAL(resetProperty()));
|
||||||
|
|
||||||
setFocusProxy(m_checkBox);
|
setFocusProxy(m_checkBox);
|
||||||
m_checkBox->setText(QString());
|
m_checkBox->setText(QString());
|
||||||
}
|
}
|
||||||
|
@ -293,6 +303,11 @@ void QtBoolEdit::setCheckState(Qt::CheckState state)
|
||||||
m_checkBox->setCheckState(state);
|
m_checkBox->setCheckState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtBoolEdit::setStateResetButton(bool enabled)
|
||||||
|
{
|
||||||
|
m_defaultButton->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
bool QtBoolEdit::isChecked() const
|
bool QtBoolEdit::isChecked() const
|
||||||
{
|
{
|
||||||
return m_checkBox->isChecked();
|
return m_checkBox->isChecked();
|
||||||
|
|
|
@ -110,6 +110,7 @@ QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QMouseEvent;
|
class QMouseEvent;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
|
class QToolButton;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
|
|
||||||
class QtCursorDatabase
|
class QtCursorDatabase
|
||||||
|
@ -154,6 +155,7 @@ public:
|
||||||
|
|
||||||
Qt::CheckState checkState() const;
|
Qt::CheckState checkState() const;
|
||||||
void setCheckState(Qt::CheckState state);
|
void setCheckState(Qt::CheckState state);
|
||||||
|
void setStateResetButton(bool enabled);
|
||||||
|
|
||||||
bool isChecked() const;
|
bool isChecked() const;
|
||||||
void setChecked(bool c);
|
void setChecked(bool c);
|
||||||
|
@ -162,12 +164,14 @@ public:
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void toggled(bool);
|
void toggled(bool);
|
||||||
|
void resetProperty();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent * event);
|
void mousePressEvent(QMouseEvent * event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QCheckBox *m_checkBox;
|
QCheckBox *m_checkBox;
|
||||||
|
QToolButton *m_defaultButton;
|
||||||
bool m_textVisible;
|
bool m_textVisible;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@
|
||||||
#include <QtGui/QApplication>
|
#include <QtGui/QApplication>
|
||||||
#include <QtGui/QPainter>
|
#include <QtGui/QPainter>
|
||||||
#include <QtGui/QLabel>
|
#include <QtGui/QLabel>
|
||||||
|
#include <QStringRef>
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
@ -6457,6 +6458,20 @@ void QtCursorPropertyManager::uninitializeProperty(QtProperty *property)
|
||||||
d_ptr->m_values.remove(property);
|
d_ptr->m_values.remove(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QtTextPropertyManager::valueText(const QtProperty *property) const
|
||||||
|
{
|
||||||
|
QString text = QtStringPropertyManager::valueText(property);
|
||||||
|
for (int i = 0; i < text.size(); i++)
|
||||||
|
{
|
||||||
|
if (text.at(i) == '\n')
|
||||||
|
{
|
||||||
|
QStringRef ret(&text, 0, i);
|
||||||
|
return ret.toString() + " ...";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
#if QT_VERSION >= 0x040400
|
#if QT_VERSION >= 0x040400
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -160,8 +160,10 @@ public:
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setValue(QtProperty *property, bool val);
|
void setValue(QtProperty *property, bool val);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void valueChanged(QtProperty *property, bool val);
|
void valueChanged(QtProperty *property, bool val);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString valueText(const QtProperty *property) const;
|
QString valueText(const QtProperty *property) const;
|
||||||
QIcon valueIcon(const QtProperty *property) const;
|
QIcon valueIcon(const QtProperty *property) const;
|
||||||
|
@ -789,6 +791,16 @@ private:
|
||||||
Q_DISABLE_COPY(QtCursorPropertyManager)
|
Q_DISABLE_COPY(QtCursorPropertyManager)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QT_QTPROPERTYBROWSER_EXPORT QtTextPropertyManager : public QtStringPropertyManager
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QtTextPropertyManager(QObject *parent = 0):QtStringPropertyManager(parent) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QString valueText(const QtProperty *property) const;
|
||||||
|
};
|
||||||
|
|
||||||
#if QT_VERSION >= 0x040400
|
#if QT_VERSION >= 0x040400
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,6 +7,7 @@ ADD_SUBDIRECTORY(disp_sheet_id)
|
||||||
ADD_SUBDIRECTORY(object_viewer)
|
ADD_SUBDIRECTORY(object_viewer)
|
||||||
ADD_SUBDIRECTORY(georges_editor)
|
ADD_SUBDIRECTORY(georges_editor)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(world_editor)
|
||||||
IF(WITH_GUI)
|
IF(WITH_GUI)
|
||||||
ADD_SUBDIRECTORY(gui_editor)
|
ADD_SUBDIRECTORY(gui_editor)
|
||||||
ENDIF(WITH_GUI)
|
ENDIF(WITH_GUI)
|
||||||
|
@ -15,6 +16,7 @@ ADD_SUBDIRECTORY(translation_manager)
|
||||||
ADD_SUBDIRECTORY(bnp_manager)
|
ADD_SUBDIRECTORY(bnp_manager)
|
||||||
# Note: Temporarily disabled until development continues.
|
# Note: Temporarily disabled until development continues.
|
||||||
#ADD_SUBDIRECTORY(zone_painter)
|
#ADD_SUBDIRECTORY(zone_painter)
|
||||||
|
|
||||||
# Ryzom Specific Plugins
|
# Ryzom Specific Plugins
|
||||||
IF(WITH_RYZOM AND WITH_RYZOM_TOOLS)
|
IF(WITH_RYZOM AND WITH_RYZOM_TOOLS)
|
||||||
ADD_SUBDIRECTORY(mission_compiler)
|
ADD_SUBDIRECTORY(mission_compiler)
|
||||||
|
|
|
@ -11,9 +11,19 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.
|
||||||
|
|
||||||
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h
|
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_HDR landscape_editor_plugin.h
|
||||||
landscape_editor_window.h
|
landscape_editor_window.h
|
||||||
|
landscape_scene_base.h
|
||||||
|
landscape_scene.h
|
||||||
|
list_zones_model.h
|
||||||
|
list_zones_widget.h
|
||||||
|
landscape_view.h
|
||||||
|
project_settings_dialog.h
|
||||||
|
snapshot_dialog.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS landscape_editor_window.ui
|
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_UIS landscape_editor_window.ui
|
||||||
|
list_zones_widget.ui
|
||||||
|
project_settings_dialog.ui
|
||||||
|
shapshot_dialog.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc)
|
SET(OVQT_PLUGIN_LANDSCAPE_EDITOR_RCS landscape_editor.qrc)
|
||||||
|
@ -31,13 +41,13 @@ SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC}
|
||||||
SOURCE_GROUP("Landscape Editor Plugin" FILES ${SRC})
|
SOURCE_GROUP("Landscape Editor Plugin" FILES ${SRC})
|
||||||
SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC})
|
SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC})
|
||||||
|
|
||||||
ADD_LIBRARY(ovqt_plugin_landscape_editor MODULE ${SRC}
|
ADD_LIBRARY(ovqt_plugin_landscape_editor SHARED ${SRC}
|
||||||
${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC}
|
${OVQT_PLUGIN_LANDSCAPE_EDITOR_MOC_SRC}
|
||||||
${OVQT_EXT_SYS_SRC}
|
${OVQT_EXT_SYS_SRC}
|
||||||
${OVQT_PLUGIN_LANDSCAPE_EDITOR_UI_HDRS}
|
${OVQT_PLUGIN_LANDSCAPE_EDITOR_UI_HDRS}
|
||||||
${OVQT_PLUGIN_LANDSCAPE_EDITOR_RC_SRCS})
|
${OVQT_PLUGIN_LANDSCAPE_EDITOR_RC_SRCS})
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(ovqt_plugin_landscape_editor ovqt_plugin_core nelmisc nel3d ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY})
|
TARGET_LINK_LIBRARIES(ovqt_plugin_landscape_editor ovqt_plugin_core nelmisc nel3d nelgeorges nelligo ${QT_LIBRARIES} ${QT_QTOPENGL_LIBRARY})
|
||||||
|
|
||||||
NL_DEFAULT_PROPS(ovqt_plugin_landscape_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: Landscape Editor")
|
NL_DEFAULT_PROPS(ovqt_plugin_landscape_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: Landscape Editor")
|
||||||
NL_ADD_RUNTIME_FLAGS(ovqt_plugin_landscape_editor)
|
NL_ADD_RUNTIME_FLAGS(ovqt_plugin_landscape_editor)
|
||||||
|
@ -47,4 +57,3 @@ ADD_DEFINITIONS(-DLANDSCAPE_EDITOR_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -D
|
||||||
|
|
||||||
INSTALL(TARGETS ovqt_plugin_landscape_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} ARCHIVE DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
|
INSTALL(TARGETS ovqt_plugin_landscape_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} ARCHIVE DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
|
||||||
#INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_landscape_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)
|
#INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_landscape_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,540 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "builder_zone.h"
|
||||||
|
#include "list_zones_widget.h"
|
||||||
|
#include "landscape_actions.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <QtGui/QMessageBox>
|
||||||
|
#include <QtGui/QProgressDialog>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
int LandCounter = 0;
|
||||||
|
|
||||||
|
ZoneBuilder::ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget, QUndoStack *undoStack)
|
||||||
|
: m_currentZoneRegion(-1),
|
||||||
|
m_pixmapDatabase(0),
|
||||||
|
m_listZonesWidget(listZonesWidget),
|
||||||
|
m_landscapeScene(landscapeScene),
|
||||||
|
m_undoStack(undoStack)
|
||||||
|
{
|
||||||
|
nlassert(m_landscapeScene);
|
||||||
|
m_pixmapDatabase = new PixmapDatabase();
|
||||||
|
m_lastPathName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneBuilder::~ZoneBuilder()
|
||||||
|
{
|
||||||
|
delete m_pixmapDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneBuilder::init(const QString &pathName, bool displayProgress)
|
||||||
|
{
|
||||||
|
if (pathName.isEmpty())
|
||||||
|
return false;
|
||||||
|
if (pathName != m_lastPathName)
|
||||||
|
{
|
||||||
|
m_lastPathName = pathName;
|
||||||
|
QString zoneBankPath = pathName;
|
||||||
|
zoneBankPath += "/zoneligos/";
|
||||||
|
|
||||||
|
// Init the ZoneBank
|
||||||
|
m_zoneBank.reset();
|
||||||
|
if (!initZoneBank (zoneBankPath))
|
||||||
|
{
|
||||||
|
m_zoneBank.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Construct the DataBase from the ZoneBank
|
||||||
|
QString zoneBitmapPath = pathName;
|
||||||
|
zoneBitmapPath += "/zonebitmaps/";
|
||||||
|
m_pixmapDatabase->reset();
|
||||||
|
if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank, displayProgress))
|
||||||
|
{
|
||||||
|
m_zoneBank.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::actionLigoTile(const LigoData &data, const ZonePosition &zonePos)
|
||||||
|
{
|
||||||
|
if (m_undoStack == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
checkBeginMacro();
|
||||||
|
// nlinfo(QString("%1 %2 %3 (%4 %5)").arg(data.zoneName.c_str()).arg(zonePos.x).arg(zonePos.y).arg(data.posX).arg(data.posY).toStdString().c_str());
|
||||||
|
m_zonePositionList.push_back(zonePos);
|
||||||
|
m_undoStack->push(new LigoTileCommand(data, zonePos, this, m_landscapeScene));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::actionLigoMove(uint index, sint32 deltaX, sint32 deltaY)
|
||||||
|
{
|
||||||
|
if (m_undoStack == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
checkBeginMacro();
|
||||||
|
//m_undoStack->push(new LigoMoveCommand(index, deltaX, deltaY, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY)
|
||||||
|
{
|
||||||
|
if (m_undoStack == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
checkBeginMacro();
|
||||||
|
// nlinfo(QString("minX=%1 maxX=%2 minY=%3 maxY=%4").arg(newMinX).arg(newMaxX).arg(newMinY).arg(newMaxY).toStdString().c_str());
|
||||||
|
m_undoStack->push(new LigoResizeCommand(index, newMinX, newMaxX, newMinY, newMaxY, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::addZone(sint32 posX, sint32 posY)
|
||||||
|
{
|
||||||
|
// Read-only mode
|
||||||
|
if ((m_listZonesWidget == 0) || (m_undoStack == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_landscapeMap.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check zone name
|
||||||
|
std::string zoneName = m_listZonesWidget->currentZoneName().toStdString();
|
||||||
|
if (zoneName.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion;
|
||||||
|
builderZoneRegion->init(this);
|
||||||
|
|
||||||
|
uint8 rot = uint8(m_listZonesWidget->currentRot());
|
||||||
|
uint8 flip = uint8(m_listZonesWidget->currentFlip());
|
||||||
|
|
||||||
|
NLLIGO::CZoneBankElement *zoneBankElement = getZoneBank().getElementByZoneName(zoneName);
|
||||||
|
|
||||||
|
m_titleAction = QString("Add zone %1,%2").arg(posX).arg(posY);
|
||||||
|
m_createdAction = false;
|
||||||
|
m_zonePositionList.clear();
|
||||||
|
if (m_listZonesWidget->isForce())
|
||||||
|
{
|
||||||
|
builderZoneRegion->addForce(posX, posY, rot, flip, zoneBankElement);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_listZonesWidget->isNotPropogate())
|
||||||
|
builderZoneRegion->addNotPropagate(posX, posY, rot, flip, zoneBankElement);
|
||||||
|
else
|
||||||
|
builderZoneRegion->add(posX, posY, rot, flip, zoneBankElement);
|
||||||
|
}
|
||||||
|
checkEndMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::addTransition(const sint32 posX, const sint32 posY)
|
||||||
|
{
|
||||||
|
// Read-only mode
|
||||||
|
if ((m_listZonesWidget == 0) || (m_undoStack == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_landscapeMap.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_titleAction = QString("Transition zone %1,%2").arg(posX).arg(posY);
|
||||||
|
m_createdAction = false;
|
||||||
|
m_zonePositionList.clear();
|
||||||
|
|
||||||
|
nlinfo(QString("trans %1,%2").arg(posX).arg(posY).toStdString().c_str());
|
||||||
|
|
||||||
|
sint32 x = (sint32)floor(float(posX) / m_landscapeScene->cellSize());
|
||||||
|
sint32 y = (sint32)floor(float(posY) / m_landscapeScene->cellSize());
|
||||||
|
sint32 k;
|
||||||
|
|
||||||
|
// Detect if we are in a transition square to switch
|
||||||
|
BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion;
|
||||||
|
builderZoneRegion->init(this);
|
||||||
|
const NLLIGO::CZoneRegion &zoneRegion = currentZoneRegion()->ligoZoneRegion();
|
||||||
|
bool bCutEdgeTouched = false;
|
||||||
|
for (uint8 transPos = 0; transPos < 4; ++transPos)
|
||||||
|
{
|
||||||
|
uint ce = zoneRegion.getCutEdge(x, y, transPos);
|
||||||
|
|
||||||
|
if ((ce > 0) && (ce < 3))
|
||||||
|
for (k = 0; k < 2; ++k)
|
||||||
|
{
|
||||||
|
float xTrans, yTrans;
|
||||||
|
|
||||||
|
if ((transPos == 0) || (transPos == 1))
|
||||||
|
{
|
||||||
|
if (ce == 1)
|
||||||
|
xTrans = m_landscapeScene->cellSize() / 3.0f;
|
||||||
|
else
|
||||||
|
xTrans = 2.0f * m_landscapeScene->cellSize() / 3.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (transPos == 2)
|
||||||
|
xTrans = 0;
|
||||||
|
else
|
||||||
|
xTrans = m_landscapeScene->cellSize();
|
||||||
|
}
|
||||||
|
xTrans += x * m_landscapeScene->cellSize();
|
||||||
|
|
||||||
|
if ((transPos == 2) || (transPos == 3))
|
||||||
|
{
|
||||||
|
if (ce == 1)
|
||||||
|
yTrans = m_landscapeScene->cellSize() / 3.0f;
|
||||||
|
else
|
||||||
|
yTrans = 2.0f * m_landscapeScene->cellSize() / 3.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (transPos == 1)
|
||||||
|
yTrans = 0;
|
||||||
|
else
|
||||||
|
yTrans = m_landscapeScene->cellSize();
|
||||||
|
}
|
||||||
|
yTrans += y * m_landscapeScene->cellSize();
|
||||||
|
|
||||||
|
if ((posX >= (xTrans - m_landscapeScene->cellSize() / 12.0f)) &&
|
||||||
|
(posX <= (xTrans + m_landscapeScene->cellSize() / 12.0f)) &&
|
||||||
|
(posY >= (yTrans - m_landscapeScene->cellSize() / 12.0f)) &&
|
||||||
|
(posY <= (yTrans + m_landscapeScene->cellSize() / 12.0f)))
|
||||||
|
{
|
||||||
|
builderZoneRegion->invertCutEdge (x, y, transPos);
|
||||||
|
bCutEdgeTouched = true;
|
||||||
|
}
|
||||||
|
ce = 3 - ce;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not clicked to change the cutEdge so the user want to change the transition
|
||||||
|
if (!bCutEdgeTouched)
|
||||||
|
{
|
||||||
|
builderZoneRegion->cycleTransition (x, y);
|
||||||
|
}
|
||||||
|
checkEndMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::delZone(const sint32 posX, const sint32 posY)
|
||||||
|
{
|
||||||
|
if ((m_listZonesWidget == 0) || (m_undoStack == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_landscapeMap.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_titleAction = QString("Del zone %1,%2").arg(posX).arg(posY);
|
||||||
|
m_createdAction = false;
|
||||||
|
|
||||||
|
BuilderZoneRegion *builderZoneRegion = m_landscapeMap.value(m_currentZoneRegion).builderZoneRegion;
|
||||||
|
|
||||||
|
builderZoneRegion->init(this);
|
||||||
|
builderZoneRegion->del(posX, posY);
|
||||||
|
checkEndMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZoneBuilder::createZoneRegion()
|
||||||
|
{
|
||||||
|
LandscapeItem landItem;
|
||||||
|
landItem.zoneRegionObject = new ZoneRegionObject();
|
||||||
|
landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter);
|
||||||
|
landItem.builderZoneRegion->init(this);
|
||||||
|
landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
|
||||||
|
|
||||||
|
m_landscapeMap.insert(LandCounter, landItem);
|
||||||
|
if (m_currentZoneRegion == -1)
|
||||||
|
setCurrentZoneRegion(LandCounter);
|
||||||
|
|
||||||
|
calcMask();
|
||||||
|
return LandCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZoneBuilder::createZoneRegion(const QString &fileName)
|
||||||
|
{
|
||||||
|
LandscapeItem landItem;
|
||||||
|
landItem.zoneRegionObject = new ZoneRegionObject();
|
||||||
|
landItem.zoneRegionObject->load(fileName.toStdString());
|
||||||
|
|
||||||
|
if (checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion()))
|
||||||
|
{
|
||||||
|
delete landItem.zoneRegionObject;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter);
|
||||||
|
landItem.builderZoneRegion->init(this);
|
||||||
|
|
||||||
|
m_landscapeScene->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion());
|
||||||
|
landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
|
||||||
|
m_landscapeMap.insert(LandCounter, landItem);
|
||||||
|
|
||||||
|
if (m_currentZoneRegion == -1)
|
||||||
|
setCurrentZoneRegion(LandCounter);
|
||||||
|
|
||||||
|
calcMask();
|
||||||
|
return LandCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::deleteZoneRegion(int id)
|
||||||
|
{
|
||||||
|
if (m_landscapeMap.contains(id))
|
||||||
|
{
|
||||||
|
if (m_landscapeMap.value(id).rectItem != 0)
|
||||||
|
delete m_landscapeMap.value(id).rectItem;
|
||||||
|
m_landscapeScene->delZoneRegion(m_landscapeMap.value(id).zoneRegionObject->ligoZoneRegion());
|
||||||
|
delete m_landscapeMap.value(id).zoneRegionObject;
|
||||||
|
delete m_landscapeMap.value(id).builderZoneRegion;
|
||||||
|
m_landscapeMap.remove(id);
|
||||||
|
calcMask();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nlwarning("Landscape (id %i) not found", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::setCurrentZoneRegion(int id)
|
||||||
|
{
|
||||||
|
if (m_landscapeMap.contains(id))
|
||||||
|
{
|
||||||
|
if (currentIdZoneRegion() != -1)
|
||||||
|
{
|
||||||
|
NLLIGO::CZoneRegion &ligoRegion = m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject->ligoZoneRegion();
|
||||||
|
m_landscapeMap[m_currentZoneRegion].rectItem = m_landscapeScene->createLayerBlackout(ligoRegion);
|
||||||
|
}
|
||||||
|
delete m_landscapeMap.value(id).rectItem;
|
||||||
|
m_landscapeMap[id].rectItem = 0;
|
||||||
|
m_currentZoneRegion = id;
|
||||||
|
calcMask();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nlwarning("Landscape (id %i) not found", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZoneBuilder::currentIdZoneRegion() const
|
||||||
|
{
|
||||||
|
return m_currentZoneRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneRegionObject *ZoneBuilder::currentZoneRegion() const
|
||||||
|
{
|
||||||
|
ZoneRegionObject *result = 0;
|
||||||
|
if (m_landscapeMap.contains(m_currentZoneRegion))
|
||||||
|
result = m_landscapeMap.value(m_currentZoneRegion).zoneRegionObject;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZoneBuilder::countZoneRegion() const
|
||||||
|
{
|
||||||
|
return m_landscapeMap.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneRegionObject *ZoneBuilder::zoneRegion(int id) const
|
||||||
|
{
|
||||||
|
ZoneRegionObject *result = 0;
|
||||||
|
if (m_landscapeMap.contains(id))
|
||||||
|
result = m_landscapeMap.value(id).zoneRegionObject;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneBuilder::ligoData(LigoData &data, const ZonePosition &zonePos)
|
||||||
|
{
|
||||||
|
if (m_landscapeMap.contains(zonePos.region))
|
||||||
|
{
|
||||||
|
m_landscapeMap.value(zonePos.region).zoneRegionObject->ligoData(data, zonePos.x, zonePos.y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::setLigoData(LigoData &data, const ZonePosition &zonePos)
|
||||||
|
{
|
||||||
|
if (m_landscapeMap.contains(zonePos.region))
|
||||||
|
m_landscapeMap.value(zonePos.region).zoneRegionObject->setLigoData(data, zonePos.x, zonePos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneBuilder::initZoneBank (const QString &pathName)
|
||||||
|
{
|
||||||
|
QDir *dir = new QDir(pathName);
|
||||||
|
QStringList filters;
|
||||||
|
filters << "*.ligozone";
|
||||||
|
|
||||||
|
// Find all ligozone files in dir
|
||||||
|
QStringList listFiles = dir->entryList(filters, QDir::Files);
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
Q_FOREACH(QString file, listFiles)
|
||||||
|
{
|
||||||
|
//nlinfo(file.toStdString().c_str());
|
||||||
|
if (!m_zoneBank.addElement((pathName + file).toStdString(), error))
|
||||||
|
QMessageBox::critical(0, QObject::tr("Landscape editor"), QString(error.c_str()), QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
delete dir;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PixmapDatabase *ZoneBuilder::pixmapDatabase() const
|
||||||
|
{
|
||||||
|
return m_pixmapDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ZoneBuilder::dataPath() const
|
||||||
|
{
|
||||||
|
return m_lastPathName;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneBuilder::getZoneMask(sint32 x, sint32 y)
|
||||||
|
{
|
||||||
|
if ((x < m_minX) || (x > m_maxX) ||
|
||||||
|
(y < m_minY) || (y > m_maxY))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return m_zoneMask[(x - m_minX) + (y - m_minY) * (1 + m_maxX - m_minX)];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::calcMask()
|
||||||
|
{
|
||||||
|
sint32 x, y;
|
||||||
|
|
||||||
|
m_minY = m_minX = 1000000;
|
||||||
|
m_maxY = m_maxX = -1000000;
|
||||||
|
|
||||||
|
if (m_landscapeMap.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMapIterator<int, LandscapeItem> i(m_landscapeMap);
|
||||||
|
while (i.hasNext())
|
||||||
|
{
|
||||||
|
i.next();
|
||||||
|
const NLLIGO::CZoneRegion ®ion = i.value().zoneRegionObject->ligoZoneRegion();
|
||||||
|
|
||||||
|
if (m_minX > region.getMinX())
|
||||||
|
m_minX = region.getMinX();
|
||||||
|
if (m_minY > region.getMinY())
|
||||||
|
m_minY = region.getMinY();
|
||||||
|
if (m_maxX < region.getMaxX())
|
||||||
|
m_maxX = region.getMaxX();
|
||||||
|
if (m_maxY < region.getMaxY())
|
||||||
|
m_maxY = region.getMaxY();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_zoneMask.resize ((1 + m_maxX - m_minX) * (1 + m_maxY - m_minY));
|
||||||
|
sint32 stride = (1 + m_maxX - m_minX);
|
||||||
|
for (y = m_minY; y <= m_maxY; ++y)
|
||||||
|
for (x = m_minX; x <= m_maxX; ++x)
|
||||||
|
{
|
||||||
|
m_zoneMask[x - m_minX + (y - m_minY) * stride] = true;
|
||||||
|
|
||||||
|
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
it.next();
|
||||||
|
if (int(it.key()) != m_currentZoneRegion)
|
||||||
|
{
|
||||||
|
const NLLIGO::CZoneRegion ®ion = it.value().zoneRegionObject->ligoZoneRegion();
|
||||||
|
|
||||||
|
const std::string &rSZone = region.getName (x, y);
|
||||||
|
if ((rSZone != STRING_OUT_OF_BOUND) && (rSZone != STRING_UNUSED))
|
||||||
|
{
|
||||||
|
m_zoneMask[x - m_minX + (y - m_minY) * stride] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneBuilder::getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y)
|
||||||
|
{
|
||||||
|
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
it.next();
|
||||||
|
const NLLIGO::CZoneRegion ®ion = it.value().zoneRegionObject->ligoZoneRegion();
|
||||||
|
if ((x < region.getMinX()) || (x > region.getMaxX()) ||
|
||||||
|
(y < region.getMinY()) || (y > region.getMaxY()))
|
||||||
|
continue;
|
||||||
|
if (region.getName(x, y) != STRING_UNUSED)
|
||||||
|
{
|
||||||
|
builderZoneRegionFrom = it.value().builderZoneRegion;
|
||||||
|
zonePos = ZonePosition(x, y, it.key());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The zone is not present in other region so it is an empty or oob zone of the current region
|
||||||
|
const NLLIGO::CZoneRegion ®ion = zoneRegion(builderZoneRegionFrom->getRegionId())->ligoZoneRegion();
|
||||||
|
if ((x < region.getMinX()) || (x > region.getMaxX()) ||
|
||||||
|
(y < region.getMinY()) || (y > region.getMaxY()))
|
||||||
|
return false; // Out Of Bound
|
||||||
|
|
||||||
|
zonePos = ZonePosition(x, y, builderZoneRegionFrom->getRegionId());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::checkBeginMacro()
|
||||||
|
{
|
||||||
|
if (!m_createdAction)
|
||||||
|
{
|
||||||
|
m_createdAction = true;
|
||||||
|
m_undoStack->beginMacro(m_titleAction);
|
||||||
|
m_undoScanRegionCommand = new UndoScanRegionCommand(true, this, m_landscapeScene);
|
||||||
|
m_undoStack->push(m_undoScanRegionCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilder::checkEndMacro()
|
||||||
|
{
|
||||||
|
if (m_createdAction)
|
||||||
|
{
|
||||||
|
UndoScanRegionCommand *redoScanRegionCommand = new UndoScanRegionCommand(false, this, m_landscapeScene);
|
||||||
|
|
||||||
|
// Sets list positions in which need apply changes
|
||||||
|
m_undoScanRegionCommand->setScanList(m_zonePositionList);
|
||||||
|
redoScanRegionCommand->setScanList(m_zonePositionList);
|
||||||
|
|
||||||
|
// Adds command in the stack
|
||||||
|
m_undoStack->push(redoScanRegionCommand);
|
||||||
|
m_undoStack->endMacro();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneBuilder::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion)
|
||||||
|
{
|
||||||
|
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
it.next();
|
||||||
|
const NLLIGO::CZoneRegion &zoneRegion = it.value().zoneRegionObject->ligoZoneRegion();
|
||||||
|
for (sint32 y = zoneRegion.getMinY(); y <= zoneRegion.getMaxY(); ++y)
|
||||||
|
for (sint32 x = zoneRegion.getMinX(); x <= zoneRegion.getMaxX(); ++x)
|
||||||
|
{
|
||||||
|
const std::string &refZoneName = zoneRegion.getName(x, y);
|
||||||
|
if (refZoneName != STRING_UNUSED)
|
||||||
|
{
|
||||||
|
const std::string &zoneName = newZoneRegion.getName(x, y);
|
||||||
|
if ((zoneName != STRING_UNUSED) && (zoneName != STRING_OUT_OF_BOUND))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,174 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef BUILDER_ZONE_H
|
||||||
|
#define BUILDER_ZONE_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "builder_zone_base.h"
|
||||||
|
#include "builder_zone_region.h"
|
||||||
|
#include "zone_region_editor.h"
|
||||||
|
#include "pixmap_database.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/zone_bank.h>
|
||||||
|
#include <nel/ligo/zone_region.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtGui/QPixmap>
|
||||||
|
#include <QtGui/QUndoStack>
|
||||||
|
#include <QtGui/QGraphicsRectItem>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
class ListZonesWidget;
|
||||||
|
class LandscapeScene;
|
||||||
|
class UndoScanRegionCommand;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class ZoneBuilder
|
||||||
|
@brief ZoneBuilder contains all the shared data between the tools and the engine.
|
||||||
|
@details ZoneBank contains the macro zones that is composed of several zones plus a mask.
|
||||||
|
PixmapDatabase contains the graphics for the zones
|
||||||
|
*/
|
||||||
|
class ZoneBuilder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZoneBuilder(LandscapeScene *landscapeScene, ListZonesWidget *listZonesWidget = 0, QUndoStack *undoStack = 0);
|
||||||
|
~ZoneBuilder();
|
||||||
|
|
||||||
|
/// Inits zoneBank and init zone pixmap database
|
||||||
|
bool init(const QString &pathName, bool displayProgress = false);
|
||||||
|
|
||||||
|
void calcMask();
|
||||||
|
|
||||||
|
/// @return false if in point (x, y) placed zone brick, else true
|
||||||
|
bool getZoneMask (sint32 x, sint32 y);
|
||||||
|
|
||||||
|
bool getZoneAmongRegions(ZonePosition &zonePos, BuilderZoneRegion *builderZoneRegionFrom, sint32 x, sint32 y);
|
||||||
|
|
||||||
|
/// Ligo Actions
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/// Adds the LigoTileCommand in undo stack
|
||||||
|
void actionLigoTile(const LigoData &data, const ZonePosition &zonePos);
|
||||||
|
|
||||||
|
void actionLigoMove(uint index, sint32 deltaX, sint32 deltaY);
|
||||||
|
|
||||||
|
/// Adds the LigoResizeCommand in undo stack
|
||||||
|
void actionLigoResize(uint index, sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY);
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// Zone Bricks
|
||||||
|
/// @{
|
||||||
|
void addZone(const sint32 posX, const sint32 posY);
|
||||||
|
void addTransition(const sint32 posX, const sint32 posY);
|
||||||
|
void delZone(const sint32 posX, const sint32 posY);
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// Zone Region
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/// Creates empty zone region and adds in the workspace
|
||||||
|
/// @return id zone region
|
||||||
|
int createZoneRegion();
|
||||||
|
|
||||||
|
/// Loads zone region from file @fileName and adds in the workspace.
|
||||||
|
/// @return id zone region
|
||||||
|
int createZoneRegion(const QString &fileName);
|
||||||
|
|
||||||
|
/// Unloads zone region from the workspace
|
||||||
|
void deleteZoneRegion(int id);
|
||||||
|
|
||||||
|
/// Sets the current zone region with @id
|
||||||
|
void setCurrentZoneRegion(int id);
|
||||||
|
|
||||||
|
/// @return id the current zone region, if workspace is empty then returns (-1)
|
||||||
|
int currentIdZoneRegion() const;
|
||||||
|
|
||||||
|
ZoneRegionObject *currentZoneRegion() const;
|
||||||
|
int countZoneRegion() const;
|
||||||
|
ZoneRegionObject *zoneRegion(int id) const;
|
||||||
|
bool ligoData(LigoData &data, const ZonePosition &zonePos);
|
||||||
|
void setLigoData(LigoData &data, const ZonePosition &zonePos);
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
NLLIGO::CZoneBank &getZoneBank()
|
||||||
|
{
|
||||||
|
return m_zoneBank;
|
||||||
|
}
|
||||||
|
|
||||||
|
PixmapDatabase *pixmapDatabase() const;
|
||||||
|
|
||||||
|
QString dataPath() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// Scans ./zoneligos dir and add all *.ligozone files to zoneBank
|
||||||
|
bool initZoneBank (const QString &path);
|
||||||
|
|
||||||
|
/// Checks enabled beginMacro mode for undo stack, if false, then enables mode
|
||||||
|
void checkBeginMacro();
|
||||||
|
|
||||||
|
/// Checks enabled on beginMacro mode for undo stack, if true, then adds UndoScanRegionCommand
|
||||||
|
/// in undo stack and disables beginMacro mode
|
||||||
|
void checkEndMacro();
|
||||||
|
|
||||||
|
/// Checks intersects between them zone regions
|
||||||
|
/// @return true if newZoneRegion intersects with loaded zone regions, else return false
|
||||||
|
bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion);
|
||||||
|
|
||||||
|
struct LandscapeItem
|
||||||
|
{
|
||||||
|
BuilderZoneRegion *builderZoneRegion;
|
||||||
|
ZoneRegionObject *zoneRegionObject;
|
||||||
|
QGraphicsRectItem *rectItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
sint32 m_minX, m_maxX, m_minY, m_maxY;
|
||||||
|
std::vector<bool> m_zoneMask;
|
||||||
|
|
||||||
|
QString m_lastPathName;
|
||||||
|
|
||||||
|
int m_currentZoneRegion;
|
||||||
|
//std::vector<LandscapeItem> m_landscapeItems;
|
||||||
|
QMap<int, LandscapeItem> m_landscapeMap;
|
||||||
|
|
||||||
|
bool m_createdAction;
|
||||||
|
QString m_titleAction;
|
||||||
|
QList<ZonePosition> m_zonePositionList;
|
||||||
|
UndoScanRegionCommand *m_undoScanRegionCommand;
|
||||||
|
|
||||||
|
PixmapDatabase *m_pixmapDatabase;
|
||||||
|
NLLIGO::CZoneBank m_zoneBank;
|
||||||
|
ListZonesWidget *m_listZonesWidget;
|
||||||
|
LandscapeScene *m_landscapeScene;
|
||||||
|
QUndoStack *m_undoStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // BUILDER_ZONE_H
|
|
@ -0,0 +1,206 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "builder_zone_base.h"
|
||||||
|
#include "landscape_scene_base.h"
|
||||||
|
#include "zone_region_editor.h"
|
||||||
|
#include "pixmap_database.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <QtGui/QMessageBox>
|
||||||
|
#include <QtGui/QProgressDialog>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
int NewLandId = 0;
|
||||||
|
|
||||||
|
ZoneBuilderBase::ZoneBuilderBase(LandscapeSceneBase *landscapeScene)
|
||||||
|
: m_pixmapDatabase(0),
|
||||||
|
m_landscapeSceneBase(landscapeScene)
|
||||||
|
{
|
||||||
|
nlassert(m_landscapeSceneBase);
|
||||||
|
m_pixmapDatabase = new PixmapDatabase();
|
||||||
|
m_lastPathName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneBuilderBase::~ZoneBuilderBase()
|
||||||
|
{
|
||||||
|
delete m_pixmapDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneBuilderBase::init(const QString &pathName, bool displayProgress)
|
||||||
|
{
|
||||||
|
if (pathName.isEmpty())
|
||||||
|
return false;
|
||||||
|
if (pathName != m_lastPathName)
|
||||||
|
{
|
||||||
|
m_lastPathName = pathName;
|
||||||
|
QString zoneBankPath = pathName;
|
||||||
|
zoneBankPath += "/zoneligos/";
|
||||||
|
|
||||||
|
// Init the ZoneBank
|
||||||
|
m_zoneBank.reset();
|
||||||
|
if (!initZoneBank (zoneBankPath))
|
||||||
|
{
|
||||||
|
m_zoneBank.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Construct the DataBase from the ZoneBank
|
||||||
|
QString zoneBitmapPath = pathName;
|
||||||
|
zoneBitmapPath += "/zonebitmaps/";
|
||||||
|
m_pixmapDatabase->reset();
|
||||||
|
if (!m_pixmapDatabase->loadPixmaps(zoneBitmapPath, m_zoneBank, displayProgress))
|
||||||
|
{
|
||||||
|
m_zoneBank.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZoneBuilderBase::loadZoneRegion(const QString &fileName, int defaultId)
|
||||||
|
{
|
||||||
|
LandscapeItem landItem;
|
||||||
|
landItem.zoneRegionObject = new ZoneRegionObject();
|
||||||
|
landItem.zoneRegionObject->load(fileName.toStdString());
|
||||||
|
|
||||||
|
if (!checkOverlaps(landItem.zoneRegionObject->ligoZoneRegion()))
|
||||||
|
{
|
||||||
|
delete landItem.zoneRegionObject;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int id = defaultId;
|
||||||
|
if (id == -1)
|
||||||
|
id = NewLandId++;
|
||||||
|
// landItem.builderZoneRegion = new BuilderZoneRegion(LandCounter);
|
||||||
|
// landItem.builderZoneRegion->init(this);
|
||||||
|
|
||||||
|
m_landscapeSceneBase->addZoneRegion(landItem.zoneRegionObject->ligoZoneRegion());
|
||||||
|
// landItem.rectItem = m_landscapeScene->createLayerBlackout(landItem.zoneRegionObject->ligoZoneRegion());
|
||||||
|
m_landscapeMap.insert(id, landItem);
|
||||||
|
|
||||||
|
calcMask();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilderBase::deleteZoneRegion(int id)
|
||||||
|
{
|
||||||
|
if (m_landscapeMap.contains(id))
|
||||||
|
{
|
||||||
|
m_landscapeSceneBase->delZoneRegion(m_landscapeMap.value(id).zoneRegionObject->ligoZoneRegion());
|
||||||
|
delete m_landscapeMap.value(id).zoneRegionObject;
|
||||||
|
// delete m_landscapeMap.value(id).builderZoneRegion;
|
||||||
|
m_landscapeMap.remove(id);
|
||||||
|
calcMask();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nlwarning("Landscape (id %i) not found", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ZoneBuilderBase::countZoneRegion() const
|
||||||
|
{
|
||||||
|
return m_landscapeMap.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneRegionObject *ZoneBuilderBase::zoneRegion(int id) const
|
||||||
|
{
|
||||||
|
return m_landscapeMap.value(id).zoneRegionObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneBuilderBase::initZoneBank (const QString &pathName)
|
||||||
|
{
|
||||||
|
QDir *dir = new QDir(pathName);
|
||||||
|
QStringList filters;
|
||||||
|
filters << "*.ligozone";
|
||||||
|
|
||||||
|
// Find all ligozone files in dir
|
||||||
|
QStringList listFiles = dir->entryList(filters, QDir::Files);
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
Q_FOREACH(QString file, listFiles)
|
||||||
|
{
|
||||||
|
//nlinfo(file.toStdString().c_str());
|
||||||
|
if (!m_zoneBank.addElement((pathName + file).toStdString(), error))
|
||||||
|
QMessageBox::critical(0, QObject::tr("Landscape editor"), QString(error.c_str()), QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
delete dir;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PixmapDatabase *ZoneBuilderBase::pixmapDatabase() const
|
||||||
|
{
|
||||||
|
return m_pixmapDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ZoneBuilderBase::dataPath() const
|
||||||
|
{
|
||||||
|
return m_lastPathName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneBuilderBase::calcMask()
|
||||||
|
{
|
||||||
|
m_minY = m_minX = 1000000;
|
||||||
|
m_maxY = m_maxX = -1000000;
|
||||||
|
|
||||||
|
if (m_landscapeMap.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMapIterator<int, LandscapeItem> i(m_landscapeMap);
|
||||||
|
while (i.hasNext())
|
||||||
|
{
|
||||||
|
i.next();
|
||||||
|
const NLLIGO::CZoneRegion ®ion = i.value().zoneRegionObject->ligoZoneRegion();
|
||||||
|
|
||||||
|
if (m_minX > region.getMinX())
|
||||||
|
m_minX = region.getMinX();
|
||||||
|
if (m_minY > region.getMinY())
|
||||||
|
m_minY = region.getMinY();
|
||||||
|
if (m_maxX < region.getMaxX())
|
||||||
|
m_maxX = region.getMaxX();
|
||||||
|
if (m_maxY < region.getMaxY())
|
||||||
|
m_maxY = region.getMaxY();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneBuilderBase::checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion)
|
||||||
|
{
|
||||||
|
QMapIterator<int, LandscapeItem> it(m_landscapeMap);
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
it.next();
|
||||||
|
const NLLIGO::CZoneRegion &zoneRegion = it.value().zoneRegionObject->ligoZoneRegion();
|
||||||
|
for (sint32 y = zoneRegion.getMinY(); y <= zoneRegion.getMaxY(); ++y)
|
||||||
|
for (sint32 x = zoneRegion.getMinX(); x <= zoneRegion.getMaxX(); ++x)
|
||||||
|
{
|
||||||
|
const std::string &refZoneName = zoneRegion.getName(x, y);
|
||||||
|
if (refZoneName != STRING_UNUSED)
|
||||||
|
{
|
||||||
|
const std::string &zoneName = newZoneRegion.getName(x, y);
|
||||||
|
if ((zoneName != STRING_UNUSED) && (zoneName != STRING_OUT_OF_BOUND))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,129 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef BUILDER_ZONE_BASE_H
|
||||||
|
#define BUILDER_ZONE_BASE_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "landscape_editor_global.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/zone_bank.h>
|
||||||
|
#include <nel/ligo/zone_region.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtGui/QPixmap>
|
||||||
|
#include <QtGui/QGraphicsRectItem>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
class LandscapeSceneBase;
|
||||||
|
class PixmapDatabase;
|
||||||
|
class ZoneRegionObject;
|
||||||
|
|
||||||
|
// Data
|
||||||
|
struct ZonePosition
|
||||||
|
{
|
||||||
|
// Absolute position
|
||||||
|
sint32 x;
|
||||||
|
sint32 y;
|
||||||
|
int region;
|
||||||
|
|
||||||
|
ZonePosition()
|
||||||
|
{
|
||||||
|
x = 0xffffffff;
|
||||||
|
y = 0xffffffff;
|
||||||
|
region = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZonePosition(const sint32 posX, const sint32 posY, const int id)
|
||||||
|
{
|
||||||
|
x = posX;
|
||||||
|
y = posY;
|
||||||
|
region = id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class ZoneBuilderBase
|
||||||
|
@brief ZoneBuilderBase contains all the shared data between the tools and the engine.
|
||||||
|
@details ZoneBank contains the macro zones that is composed of several zones plus a mask.
|
||||||
|
PixmapDatabase contains the graphics for the zones
|
||||||
|
*/
|
||||||
|
class LANDSCAPE_EDITOR_EXPORT ZoneBuilderBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ZoneBuilderBase(LandscapeSceneBase *landscapeScene);
|
||||||
|
virtual ~ZoneBuilderBase();
|
||||||
|
|
||||||
|
/// Init zoneBank and init zone pixmap database
|
||||||
|
bool init(const QString &pathName, bool displayProgress = false);
|
||||||
|
|
||||||
|
/// Zone Region
|
||||||
|
/// @{
|
||||||
|
int loadZoneRegion(const QString &fileName, int defaultId = -1);
|
||||||
|
void deleteZoneRegion(int id);
|
||||||
|
int countZoneRegion() const;
|
||||||
|
ZoneRegionObject *zoneRegion(int id) const;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
NLLIGO::CZoneBank &getZoneBank()
|
||||||
|
{
|
||||||
|
return m_zoneBank;
|
||||||
|
}
|
||||||
|
|
||||||
|
PixmapDatabase *pixmapDatabase() const;
|
||||||
|
|
||||||
|
QString dataPath() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// Scan ./zoneligos dir and add all *.ligozone files to zoneBank
|
||||||
|
bool initZoneBank (const QString &path);
|
||||||
|
|
||||||
|
void calcMask();
|
||||||
|
|
||||||
|
bool checkOverlaps(const NLLIGO::CZoneRegion &newZoneRegion);
|
||||||
|
|
||||||
|
struct LandscapeItem
|
||||||
|
{
|
||||||
|
ZoneRegionObject *zoneRegionObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
sint32 m_minX, m_maxX, m_minY, m_maxY;
|
||||||
|
|
||||||
|
QString m_lastPathName;
|
||||||
|
|
||||||
|
QMap<int, LandscapeItem> m_landscapeMap;
|
||||||
|
|
||||||
|
PixmapDatabase *m_pixmapDatabase;
|
||||||
|
NLLIGO::CZoneBank m_zoneBank;
|
||||||
|
LandscapeSceneBase *m_landscapeSceneBase;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // BUILDER_ZONE_BASE_H
|
|
@ -0,0 +1,107 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef BUILDER_ZONE_REGION_H
|
||||||
|
#define BUILDER_ZONE_REGION_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/zone_bank.h>
|
||||||
|
#include <nel/ligo/zone_region.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
class ZoneBuilder;
|
||||||
|
class ToUpdate;
|
||||||
|
|
||||||
|
// CZoneRegion contains informations about the zones painted.
|
||||||
|
// (Legacy class from old world editor. It needs to refactoring!)
|
||||||
|
class BuilderZoneRegion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit BuilderZoneRegion(uint regionId);
|
||||||
|
|
||||||
|
// New interface
|
||||||
|
bool init(ZoneBuilder *zoneBuilder);
|
||||||
|
void add(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
|
||||||
|
void invertCutEdge(sint32 x, sint32 y, uint8 cePos);
|
||||||
|
void cycleTransition(sint32 x, sint32 y);
|
||||||
|
bool addNotPropagate(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
|
||||||
|
|
||||||
|
/// Brutal adding a zone over empty space do not propagate in any way -> can result
|
||||||
|
/// in inconsistency when trying the propagation mode
|
||||||
|
void addForce (sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
|
||||||
|
void del(sint32 x, sint32 y, bool transition = false, ToUpdate *pUpdate = 0);
|
||||||
|
void move(sint32 x, sint32 y);
|
||||||
|
uint32 countZones();
|
||||||
|
void reduceMin();
|
||||||
|
uint getRegionId() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// An element of the graph
|
||||||
|
struct SMatNode
|
||||||
|
{
|
||||||
|
std::string Name;
|
||||||
|
// Position in the tree (vector of nodes)
|
||||||
|
std::vector<uint32> Arcs;
|
||||||
|
};
|
||||||
|
|
||||||
|
void addTransition(sint32 x, sint32 y, uint8 rot, uint8 flip, NLLIGO::CZoneBankElement *zoneBankElement);
|
||||||
|
|
||||||
|
void addToUpdateAndCreate(BuilderZoneRegion *builderZoneRegion, sint32 sharePos, sint32 x, sint32 y,
|
||||||
|
const std::string &newMat, ToUpdate *ptCreate, ToUpdate *ptUpdate);
|
||||||
|
|
||||||
|
void putTransitions(sint32 x, sint32 y, const NLLIGO::SPiece &mask, const std::string &matName, ToUpdate *ptUpdate);
|
||||||
|
void updateTrans(sint32 x, sint32 y, NLLIGO::CZoneBankElement *zoneBankElement = 0);
|
||||||
|
|
||||||
|
std::string getNextMatInTree(const std::string &matA, const std::string &matB);
|
||||||
|
|
||||||
|
/// Find the fastest way between posA and posB in the MatTree (Dijkstra)
|
||||||
|
void tryPath(uint32 posA, uint32 posB, std::vector<uint32> &path);
|
||||||
|
|
||||||
|
void set(sint32 x, sint32 y, sint32 posX, sint32 posY, const std::string &zoneName, bool transition = false);
|
||||||
|
void setRot(sint32 x, sint32 y, uint8 rot);
|
||||||
|
void setFlip(sint32 x, sint32 y, uint8 flip);
|
||||||
|
void resize(sint32 newMinX, sint32 newMaxX, sint32 newMinY, sint32 newMaxY);
|
||||||
|
|
||||||
|
void placePiece(sint32 x, sint32 y, uint8 rot, uint8 flip,
|
||||||
|
NLLIGO::SPiece &sMask, NLLIGO::SPiece &sPosX, NLLIGO::SPiece &sPosY,
|
||||||
|
const std::string &eltName);
|
||||||
|
|
||||||
|
uint m_regionId;
|
||||||
|
|
||||||
|
// To use the global mask
|
||||||
|
ZoneBuilder *m_zoneBuilder;
|
||||||
|
|
||||||
|
// The tree of transition between materials
|
||||||
|
std::vector<SMatNode> m_matTree;
|
||||||
|
|
||||||
|
bool m_firstInit;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // BUILDER_ZONE_REGION_H
|
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 5.3 KiB |
|
@ -0,0 +1,178 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "landscape_actions.h"
|
||||||
|
#include "builder_zone.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
LigoTileCommand::LigoTileCommand(const LigoData &data, const ZonePosition &zonePos,
|
||||||
|
ZoneBuilder *zoneBuilder, LandscapeScene *scene,
|
||||||
|
QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_zoneBuilder(zoneBuilder),
|
||||||
|
m_scene(scene)
|
||||||
|
{
|
||||||
|
// Backup position
|
||||||
|
m_zonePos = zonePos;
|
||||||
|
|
||||||
|
// Backup new data
|
||||||
|
m_newLigoData = data;
|
||||||
|
|
||||||
|
// Backup old data
|
||||||
|
m_zoneBuilder->ligoData(m_oldLigoData, m_zonePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
LigoTileCommand::~LigoTileCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LigoTileCommand::undo ()
|
||||||
|
{
|
||||||
|
m_zoneBuilder->setLigoData(m_oldLigoData, m_zonePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LigoTileCommand::redo ()
|
||||||
|
{
|
||||||
|
m_zoneBuilder->setLigoData(m_newLigoData, m_zonePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
UndoScanRegionCommand::UndoScanRegionCommand(bool direction, ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_direction(direction),
|
||||||
|
m_zoneBuilder(zoneBuilder),
|
||||||
|
m_scene(scene)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UndoScanRegionCommand::~UndoScanRegionCommand()
|
||||||
|
{
|
||||||
|
m_zonePositionList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UndoScanRegionCommand::setScanList(const QList<ZonePosition> &zonePositionList)
|
||||||
|
{
|
||||||
|
m_zonePositionList = zonePositionList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UndoScanRegionCommand::undo()
|
||||||
|
{
|
||||||
|
if (m_direction)
|
||||||
|
applyChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UndoScanRegionCommand::redo()
|
||||||
|
{
|
||||||
|
if (!m_direction)
|
||||||
|
applyChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UndoScanRegionCommand::applyChanges()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_zonePositionList.size(); ++i)
|
||||||
|
m_scene->deleteItemZone(m_zonePositionList.at(i));
|
||||||
|
|
||||||
|
for (int i = 0; i < m_zonePositionList.size(); ++i)
|
||||||
|
{
|
||||||
|
LigoData data;
|
||||||
|
m_zoneBuilder->ligoData(data, m_zonePositionList.at(i));
|
||||||
|
m_scene->createItemZone(data, m_zonePositionList.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LigoResizeCommand::LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
|
||||||
|
sint32 newMinY, sint32 newMaxY, ZoneBuilder *zoneBuilder,
|
||||||
|
QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_zoneBuilder(zoneBuilder)
|
||||||
|
{
|
||||||
|
m_index = index;
|
||||||
|
m_newMinX = newMinX;
|
||||||
|
m_newMaxX = newMaxX;
|
||||||
|
m_newMinY = newMinY;
|
||||||
|
m_newMaxY = newMaxY;
|
||||||
|
|
||||||
|
// Backup old region zone
|
||||||
|
m_oldZoneRegion = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
LigoResizeCommand::~LigoResizeCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LigoResizeCommand::undo ()
|
||||||
|
{
|
||||||
|
// Restore old region zone
|
||||||
|
m_zoneBuilder->zoneRegion(m_index)->setLigoZoneRegion(m_oldZoneRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LigoResizeCommand::redo ()
|
||||||
|
{
|
||||||
|
// Get the zone region
|
||||||
|
NLLIGO::CZoneRegion ®ion = m_zoneBuilder->zoneRegion(m_index)->ligoZoneRegion();
|
||||||
|
|
||||||
|
sint32 i, j;
|
||||||
|
std::vector<LigoData> newZones;
|
||||||
|
newZones.resize((1 + m_newMaxX - m_newMinX) * (1 + m_newMaxY - m_newMinY));
|
||||||
|
|
||||||
|
sint32 newStride = 1 + m_newMaxX - m_newMinX;
|
||||||
|
sint32 Stride = 1 + region.getMaxX() - region.getMinX();
|
||||||
|
|
||||||
|
for (j = m_newMinY; j <= m_newMaxY; ++j)
|
||||||
|
for (i = m_newMinX; i <= m_newMaxX; ++i)
|
||||||
|
{
|
||||||
|
// Ref on the new value
|
||||||
|
LigoData &data = newZones[(i - m_newMinX) + (j - m_newMinY) * newStride];
|
||||||
|
|
||||||
|
// In the old array ?
|
||||||
|
if ((i >= region.getMinX()) && (i <= region.getMaxX()) &&
|
||||||
|
(j >= region.getMinY()) && (j <= region.getMaxY()))
|
||||||
|
{
|
||||||
|
// Backup values
|
||||||
|
m_zoneBuilder->ligoData(data, ZonePosition(i, j, m_index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
region.resize(m_newMinX, m_newMaxX, m_newMinY, m_newMaxY);
|
||||||
|
|
||||||
|
for (j = m_newMinY; j <= m_newMaxY; ++j)
|
||||||
|
for (i = m_newMinX; i <= m_newMaxX; ++i)
|
||||||
|
{
|
||||||
|
// Ref on the new value
|
||||||
|
const LigoData &data = newZones[(i - m_newMinX) + (j - m_newMinY) * newStride];
|
||||||
|
|
||||||
|
region.setName(i, j, data.zoneName);
|
||||||
|
region.setPosX(i, j, data.posX);
|
||||||
|
region.setPosY(i, j, data.posY);
|
||||||
|
region.setRot(i, j, data.rot);
|
||||||
|
region.setFlip(i, j, data.flip);
|
||||||
|
uint k;
|
||||||
|
for (k = 0; k < 4; k++)
|
||||||
|
{
|
||||||
|
region.setSharingMatNames(i, j, k, data.sharingMatNames[k]);
|
||||||
|
region.setSharingCutEdges(i, j, k, data.sharingCutEdges[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,111 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef LANDSCAPE_ACTIONS_H
|
||||||
|
#define LANDSCAPE_ACTIONS_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "builder_zone.h"
|
||||||
|
#include "landscape_scene.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QUndoCommand>
|
||||||
|
#include <QtGui/QGraphicsScene>
|
||||||
|
#include <QtGui/QGraphicsItem>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class LigoTileCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class LigoTileCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LigoTileCommand(const LigoData &data, const ZonePosition &zonePos,
|
||||||
|
ZoneBuilder *zoneBuilder, LandscapeScene *scene,
|
||||||
|
QUndoCommand *parent = 0);
|
||||||
|
virtual ~LigoTileCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ZonePosition m_zonePos;
|
||||||
|
LigoData m_newLigoData;
|
||||||
|
LigoData m_oldLigoData;
|
||||||
|
ZoneBuilder *m_zoneBuilder;
|
||||||
|
LandscapeScene *m_scene;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class UndoScanRegionCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class UndoScanRegionCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UndoScanRegionCommand(bool direction, ZoneBuilder *zoneBuilder, LandscapeScene *scene, QUndoCommand *parent = 0);
|
||||||
|
virtual ~UndoScanRegionCommand();
|
||||||
|
|
||||||
|
void setScanList(const QList<ZonePosition> &zonePositionList);
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void applyChanges();
|
||||||
|
|
||||||
|
bool m_direction;
|
||||||
|
QList<ZonePosition> m_zonePositionList;
|
||||||
|
ZoneBuilder *m_zoneBuilder;
|
||||||
|
LandscapeScene *m_scene;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class LigoResizeCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class LigoResizeCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LigoResizeCommand(int index, sint32 newMinX, sint32 newMaxX,
|
||||||
|
sint32 newMinY, sint32 newMaxY, ZoneBuilder *zoneBuilder,
|
||||||
|
QUndoCommand *parent = 0);
|
||||||
|
virtual ~LigoResizeCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_index;
|
||||||
|
sint32 m_newMinX;
|
||||||
|
sint32 m_newMaxX;
|
||||||
|
sint32 m_newMinY;
|
||||||
|
sint32 m_newMaxY;
|
||||||
|
NLLIGO::CZoneRegion m_oldZoneRegion;
|
||||||
|
ZoneBuilder *m_zoneBuilder;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // LANDSCAPE_ACTIONS_H
|
|
@ -1,5 +1,9 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
|
<file>icons/ic_nel_zones.png</file>
|
||||||
|
<file>icons/ic_snapshot.png</file>
|
||||||
|
<file>icons/ic_grid.png</file>
|
||||||
|
<file>icons/ic_nel_transition_land.png</file>
|
||||||
<file>icons/ic_nel_landscape_item.png</file>
|
<file>icons/ic_nel_landscape_item.png</file>
|
||||||
<file>icons/ic_nel_landscape_settings.png</file>
|
<file>icons/ic_nel_landscape_settings.png</file>
|
||||||
<file>icons/ic_nel_world_editor.png</file>
|
<file>icons/ic_nel_world_editor.png</file>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -22,13 +21,19 @@ namespace LandscapeEditor
|
||||||
{
|
{
|
||||||
namespace Constants
|
namespace Constants
|
||||||
{
|
{
|
||||||
const char * const LANDSCAPE_EDITOR_PLUGIN = "LandscapeEditor";
|
const char *const LANDSCAPE_EDITOR_PLUGIN = "LandscapeEditor";
|
||||||
|
|
||||||
//settings
|
//settings
|
||||||
const char * const LANDSCAPE_EDITOR_SECTION = "LandscapeEditor";
|
const char *const LANDSCAPE_EDITOR_SECTION = "LandscapeEditor";
|
||||||
|
const char *const LANDSCAPE_WINDOW_STATE = "LandscapeWindowState";
|
||||||
|
const char *const LANDSCAPE_WINDOW_GEOMETRY = "LandscapeWindowGeometry";
|
||||||
|
const char *const LANDSCAPE_DATA_DIRECTORY = "LandscapeDataDirectory";
|
||||||
|
const char *const LANDSCAPE_USE_OPENGL = "LandscapeUseOpenGL";
|
||||||
|
|
||||||
//resources
|
//resources
|
||||||
const char * const ICON_LANDSCAPE_ITEM = ":/icons/ic_nel_landscape_item.png";
|
const char *const ICON_LANDSCAPE_ITEM = ":/icons/ic_nel_landscape_item.png";
|
||||||
|
const char *const ICON_ZONE_ITEM = ":/icons/ic_nel_zone.png";
|
||||||
|
const char *const ICON_LANDSCAPE_ZONES = ":/icons/ic_nel_zones.png";
|
||||||
|
|
||||||
|
|
||||||
} // namespace Constants
|
} // namespace Constants
|
||||||
|
|
|
@ -68,33 +68,6 @@ void LandscapeEditorPlugin::setNelContext(NLMISC::INelContext *nelContext)
|
||||||
m_libContext = new NLMISC::CLibraryContext(*nelContext);
|
m_libContext = new NLMISC::CLibraryContext(*nelContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LandscapeEditorPlugin::name() const
|
|
||||||
{
|
|
||||||
return tr("LandscapeEditor");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LandscapeEditorPlugin::version() const
|
|
||||||
{
|
|
||||||
return "0.0.1";
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LandscapeEditorPlugin::vendor() const
|
|
||||||
{
|
|
||||||
return "GSoC2011_dnk-88";
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LandscapeEditorPlugin::description() const
|
|
||||||
{
|
|
||||||
return "Landscape editor ovqt plugin.";
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList LandscapeEditorPlugin::dependencies() const
|
|
||||||
{
|
|
||||||
QStringList list;
|
|
||||||
list.append(Core::Constants::OVQT_CORE_PLUGIN);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LandscapeEditorPlugin::addAutoReleasedObject(QObject *obj)
|
void LandscapeEditorPlugin::addAutoReleasedObject(QObject *obj)
|
||||||
{
|
{
|
||||||
m_plugMan->addObject(obj);
|
m_plugMan->addObject(obj);
|
||||||
|
@ -124,5 +97,4 @@ QWidget *LandscapeEditorContext::widget()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_EXPORT_PLUGIN(LandscapeEditor::LandscapeEditorPlugin)
|
Q_EXPORT_PLUGIN(LandscapeEditor::LandscapeEditorPlugin)
|
|
@ -1,5 +1,4 @@
|
||||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -35,11 +34,6 @@ namespace NLMISC
|
||||||
class CLibraryContext;
|
class CLibraryContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ExtensionSystem
|
|
||||||
{
|
|
||||||
class IPluginSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace LandscapeEditor
|
namespace LandscapeEditor
|
||||||
{
|
{
|
||||||
class LandscapeEditorWindow;
|
class LandscapeEditorWindow;
|
||||||
|
@ -55,15 +49,8 @@ public:
|
||||||
bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString);
|
bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString);
|
||||||
void extensionsInitialized();
|
void extensionsInitialized();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
void setNelContext(NLMISC::INelContext *nelContext);
|
void setNelContext(NLMISC::INelContext *nelContext);
|
||||||
|
|
||||||
QString name() const;
|
|
||||||
QString version() const;
|
|
||||||
QString vendor() const;
|
|
||||||
QString description() const;
|
|
||||||
QStringList dependencies() const;
|
|
||||||
|
|
||||||
void addAutoReleasedObject(QObject *obj);
|
void addAutoReleasedObject(QObject *obj);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -78,7 +65,7 @@ class LandscapeEditorContext: public Core::IContext
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
LandscapeEditorContext(QObject *parent = 0);
|
explicit LandscapeEditorContext(QObject *parent = 0);
|
||||||
virtual ~LandscapeEditorContext() {}
|
virtual ~LandscapeEditorContext() {}
|
||||||
|
|
||||||
virtual QString id() const
|
virtual QString id() const
|
||||||
|
@ -91,7 +78,7 @@ public:
|
||||||
}
|
}
|
||||||
virtual QIcon icon() const
|
virtual QIcon icon() const
|
||||||
{
|
{
|
||||||
return QIcon();
|
return QIcon(Constants::ICON_LANDSCAPE_ITEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void open();
|
virtual void open();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -18,8 +17,14 @@
|
||||||
// Project includes
|
// Project includes
|
||||||
#include "landscape_editor_window.h"
|
#include "landscape_editor_window.h"
|
||||||
#include "landscape_editor_constants.h"
|
#include "landscape_editor_constants.h"
|
||||||
|
#include "builder_zone.h"
|
||||||
|
#include "zone_region_editor.h"
|
||||||
|
#include "landscape_scene.h"
|
||||||
|
#include "project_settings_dialog.h"
|
||||||
|
#include "snapshot_dialog.h"
|
||||||
|
|
||||||
#include "../core/icore.h"
|
#include "../core/icore.h"
|
||||||
|
#include "../core/menu_manager.h"
|
||||||
#include "../core/core_constants.h"
|
#include "../core/core_constants.h"
|
||||||
|
|
||||||
// NeL includes
|
// NeL includes
|
||||||
|
@ -27,26 +32,78 @@
|
||||||
|
|
||||||
// Qt includes
|
// Qt includes
|
||||||
#include <QtCore/QSettings>
|
#include <QtCore/QSettings>
|
||||||
|
#include <QtGui/QMenu>
|
||||||
#include <QtGui/QFileDialog>
|
#include <QtGui/QFileDialog>
|
||||||
|
#include <QtGui/QMessageBox>
|
||||||
|
#include <QtGui/QStatusBar>
|
||||||
|
|
||||||
namespace LandscapeEditor
|
namespace LandscapeEditor
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static const int LANDSCAPE_ID = 32;
|
||||||
|
int NewLandCounter = 0;
|
||||||
QString _lastDir;
|
QString _lastDir;
|
||||||
|
|
||||||
LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
|
LandscapeEditorWindow::LandscapeEditorWindow(QWidget *parent)
|
||||||
: QMainWindow(parent)
|
: QMainWindow(parent),
|
||||||
|
m_currentItem(0),
|
||||||
|
m_landscapeScene(0),
|
||||||
|
m_zoneBuilder(0),
|
||||||
|
m_undoStack(0),
|
||||||
|
m_oglWidget(0)
|
||||||
{
|
{
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
m_undoStack = new QUndoStack(this);
|
m_undoStack = new QUndoStack(this);
|
||||||
|
m_landscapeScene = new LandscapeScene(160, this);
|
||||||
|
|
||||||
|
m_zoneBuilder = new ZoneBuilder(m_landscapeScene, m_ui.zoneListWidget, m_undoStack);
|
||||||
|
m_ui.zoneListWidget->setZoneBuilder(m_zoneBuilder);
|
||||||
|
m_ui.zoneListWidget->updateUi();
|
||||||
|
|
||||||
|
m_landscapeScene->setZoneBuilder(m_zoneBuilder);
|
||||||
|
m_ui.graphicsView->setScene(m_landscapeScene);
|
||||||
|
|
||||||
|
m_ui.newLandAction->setIcon(QIcon(Core::Constants::ICON_NEW));
|
||||||
|
m_ui.saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
|
||||||
|
m_ui.saveLandAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
|
||||||
|
m_ui.saveAsLandAction->setIcon(QIcon(Core::Constants::ICON_SAVE_AS));
|
||||||
|
m_ui.zonesDockWidget->toggleViewAction()->setIcon(QIcon(Constants::ICON_LANDSCAPE_ZONES));
|
||||||
|
m_ui.landscapesDockWidget->toggleViewAction()->setIcon(QIcon(Constants::ICON_ZONE_ITEM));
|
||||||
|
|
||||||
|
m_ui.deleteLandAction->setEnabled(false);
|
||||||
|
|
||||||
createMenus();
|
createMenus();
|
||||||
|
createToolBars();
|
||||||
readSettings();
|
readSettings();
|
||||||
|
|
||||||
|
connect(m_ui.saveAction, SIGNAL(triggered()), this, SLOT(save()));
|
||||||
|
connect(m_ui.projectSettingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings()));
|
||||||
|
connect(m_ui.snapshotAction, SIGNAL(triggered()), this, SLOT(openSnapshotDialog()));
|
||||||
|
connect(m_ui.enableGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool)));
|
||||||
|
|
||||||
|
connect(m_ui.newLandAction, SIGNAL(triggered()), this, SLOT(newLand()));
|
||||||
|
connect(m_ui.setActiveLandAction, SIGNAL(triggered()), this, SLOT(setActiveLand()));
|
||||||
|
connect(m_ui.saveLandAction, SIGNAL(triggered()), this, SLOT(saveSelectedLand()));
|
||||||
|
connect(m_ui.saveAsLandAction, SIGNAL(triggered()), this, SLOT(saveAsSelectedLand()));
|
||||||
|
connect(m_ui.deleteLandAction, SIGNAL(triggered()), this, SLOT(deleteSelectedLand()));
|
||||||
|
connect(m_ui.transitionModeAction, SIGNAL(toggled(bool)), m_landscapeScene, SLOT(setTransitionMode(bool)));
|
||||||
|
|
||||||
|
connect(m_ui.landscapesListWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenu()));
|
||||||
|
m_ui.landscapesListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
|
m_statusBarTimer = new QTimer(this);
|
||||||
|
connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar()));
|
||||||
|
|
||||||
|
m_statusInfo = new QLabel(this);
|
||||||
|
m_statusInfo->hide();
|
||||||
|
Core::ICore::instance()->mainWindow()->statusBar()->addPermanentWidget(m_statusInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
LandscapeEditorWindow::~LandscapeEditorWindow()
|
LandscapeEditorWindow::~LandscapeEditorWindow()
|
||||||
{
|
{
|
||||||
writeSettings();
|
writeSettings();
|
||||||
|
delete m_zoneBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUndoStack *LandscapeEditorWindow::undoStack() const
|
QUndoStack *LandscapeEditorWindow::undoStack() const
|
||||||
|
@ -65,18 +122,281 @@ void LandscapeEditorWindow::open()
|
||||||
{
|
{
|
||||||
QStringList list = fileNames;
|
QStringList list = fileNames;
|
||||||
_lastDir = QFileInfo(list.front()).absolutePath();
|
_lastDir = QFileInfo(list.front()).absolutePath();
|
||||||
|
Q_FOREACH(QString fileName, fileNames)
|
||||||
|
{
|
||||||
|
int row = createLandscape(fileName);
|
||||||
|
if (row != -1)
|
||||||
|
setActiveLandscape(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setCursor(Qt::ArrowCursor);
|
setCursor(Qt::ArrowCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::save()
|
||||||
|
{
|
||||||
|
saveLandscape(m_ui.landscapesListWidget->row(m_currentItem), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::openProjectSettings()
|
||||||
|
{
|
||||||
|
ProjectSettingsDialog *dialog = new ProjectSettingsDialog(m_zoneBuilder->dataPath(), this);
|
||||||
|
dialog->show();
|
||||||
|
int ok = dialog->exec();
|
||||||
|
if (ok == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
m_zoneBuilder->init(dialog->dataPath(), true);
|
||||||
|
m_ui.zoneListWidget->updateUi();
|
||||||
|
}
|
||||||
|
delete dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::openSnapshotDialog()
|
||||||
|
{
|
||||||
|
SnapshotDialog *dialog = new SnapshotDialog(this);
|
||||||
|
dialog->show();
|
||||||
|
int ok = dialog->exec();
|
||||||
|
if (ok == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this,
|
||||||
|
tr("Save screenshot landscape"), _lastDir,
|
||||||
|
tr("Image file (*.png)"));
|
||||||
|
|
||||||
|
setCursor(Qt::WaitCursor);
|
||||||
|
|
||||||
|
NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->currentZoneRegion()->ligoZoneRegion();
|
||||||
|
sint32 regionMinX = zoneRegion.getMinX();
|
||||||
|
sint32 regionMaxX = zoneRegion.getMaxX();
|
||||||
|
sint32 regionMinY = zoneRegion.getMinY();
|
||||||
|
sint32 regionMaxY = zoneRegion.getMaxY();
|
||||||
|
|
||||||
|
int regionWidth = (regionMaxX - regionMinX + 1);
|
||||||
|
int regionHeight = (regionMaxY - regionMinY + 1);
|
||||||
|
|
||||||
|
int cellSize = m_landscapeScene->cellSize();
|
||||||
|
QRectF rect(regionMinX * cellSize, abs(regionMaxY) * cellSize, regionWidth * cellSize, regionHeight * cellSize);
|
||||||
|
|
||||||
|
if (dialog->isCustomSize())
|
||||||
|
{
|
||||||
|
int widthSnapshot = dialog->widthSnapshot();
|
||||||
|
int heightSnapshot = dialog->heightSnapshot();
|
||||||
|
if (dialog->isKeepRatio())
|
||||||
|
heightSnapshot = (widthSnapshot / regionWidth) * regionHeight;
|
||||||
|
|
||||||
|
m_landscapeScene->snapshot(fileName, widthSnapshot, heightSnapshot, rect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_landscapeScene->snapshot(fileName, regionWidth * dialog->resolutionZone(),
|
||||||
|
regionHeight * dialog->resolutionZone(), rect);
|
||||||
|
}
|
||||||
|
setCursor(Qt::ArrowCursor);
|
||||||
|
}
|
||||||
|
delete dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::customContextMenu()
|
||||||
|
{
|
||||||
|
if (m_ui.landscapesListWidget->currentRow() == -1)
|
||||||
|
return;
|
||||||
|
QMenu *popurMenu = new QMenu(this);
|
||||||
|
popurMenu->addAction(m_ui.setActiveLandAction);
|
||||||
|
popurMenu->addAction(m_ui.saveLandAction);
|
||||||
|
popurMenu->addAction(m_ui.saveAsLandAction);
|
||||||
|
popurMenu->addAction(m_ui.deleteLandAction);
|
||||||
|
popurMenu->exec(QCursor::pos());
|
||||||
|
delete popurMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::newLand()
|
||||||
|
{
|
||||||
|
int row = createLandscape(QString());
|
||||||
|
if (row != -1)
|
||||||
|
setActiveLandscape(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::setActiveLand()
|
||||||
|
{
|
||||||
|
setActiveLandscape(m_ui.landscapesListWidget->currentRow());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::saveSelectedLand()
|
||||||
|
{
|
||||||
|
saveLandscape(m_ui.landscapesListWidget->currentRow(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::saveAsSelectedLand()
|
||||||
|
{
|
||||||
|
saveLandscape(m_ui.landscapesListWidget->currentRow(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::deleteSelectedLand()
|
||||||
|
{
|
||||||
|
int row = m_ui.landscapesListWidget->currentRow();
|
||||||
|
int current_row = m_ui.landscapesListWidget->row(m_currentItem);
|
||||||
|
QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
|
||||||
|
if (row == current_row)
|
||||||
|
{
|
||||||
|
if (row == 0)
|
||||||
|
++row;
|
||||||
|
else
|
||||||
|
--row;
|
||||||
|
setActiveLandscape(row);
|
||||||
|
}
|
||||||
|
m_zoneBuilder->deleteZoneRegion(item->data(LANDSCAPE_ID).toInt());
|
||||||
|
m_ui.landscapesListWidget->removeItemWidget(item);
|
||||||
|
delete item;
|
||||||
|
|
||||||
|
if (m_ui.landscapesListWidget->count() == 1)
|
||||||
|
m_ui.deleteLandAction->setEnabled(false);
|
||||||
|
|
||||||
|
m_undoStack->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int LandscapeEditorWindow::createLandscape(const QString &fileName)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
id = m_zoneBuilder->createZoneRegion();
|
||||||
|
else
|
||||||
|
id = m_zoneBuilder->createZoneRegion(fileName);
|
||||||
|
|
||||||
|
if (id == -1)
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, "Landscape Editor", tr("Cannot add this zone because it overlaps existing ones"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ZoneRegionObject *zoneRegion = m_zoneBuilder->zoneRegion(id);
|
||||||
|
m_ui.graphicsView->setCenter(QPointF(zoneRegion->ligoZoneRegion().getMinX() * m_landscapeScene->cellSize(),
|
||||||
|
abs(zoneRegion->ligoZoneRegion().getMinY()) * m_landscapeScene->cellSize()));
|
||||||
|
|
||||||
|
QListWidgetItem *item;
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
item = new QListWidgetItem(QString("NewLandscape%1").arg(NewLandCounter++), m_ui.landscapesListWidget);
|
||||||
|
else
|
||||||
|
item = new QListWidgetItem(fileName, m_ui.landscapesListWidget);
|
||||||
|
|
||||||
|
item->setData(LANDSCAPE_ID, id);
|
||||||
|
item->setFont(QFont("SansSerif", 9, QFont::Normal));
|
||||||
|
|
||||||
|
if (m_ui.landscapesListWidget->count() > 1)
|
||||||
|
m_ui.deleteLandAction->setEnabled(true);
|
||||||
|
|
||||||
|
return m_ui.landscapesListWidget->count() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::setActiveLandscape(int row)
|
||||||
|
{
|
||||||
|
if ((0 <= row) && (row < m_ui.landscapesListWidget->count()))
|
||||||
|
{
|
||||||
|
if (m_currentItem != 0)
|
||||||
|
m_currentItem->setFont(QFont("SansSerif", 9, QFont::Normal));
|
||||||
|
|
||||||
|
QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
|
||||||
|
item->setFont(QFont("SansSerif", 9, QFont::Bold));
|
||||||
|
m_zoneBuilder->setCurrentZoneRegion(item->data(LANDSCAPE_ID).toInt());
|
||||||
|
m_currentItem = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::saveLandscape(int row, bool force)
|
||||||
|
{
|
||||||
|
if ((0 <= row) && (row < m_ui.landscapesListWidget->count()))
|
||||||
|
{
|
||||||
|
QListWidgetItem *item = m_ui.landscapesListWidget->item(row);
|
||||||
|
ZoneRegionObject *regionObject = m_zoneBuilder->zoneRegion(item->data(LANDSCAPE_ID).toInt());
|
||||||
|
if ((!force) || (regionObject->fileName().empty()))
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this,
|
||||||
|
tr("Save NeL Ligo land file"), _lastDir,
|
||||||
|
tr("NeL Ligo land file (*.land)"));
|
||||||
|
if (!fileName.isEmpty())
|
||||||
|
{
|
||||||
|
regionObject->setFileName(fileName.toStdString());
|
||||||
|
regionObject->save();
|
||||||
|
regionObject->setModified(false);
|
||||||
|
item->setText(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regionObject->save();
|
||||||
|
regionObject->setModified(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::showEvent(QShowEvent *showEvent)
|
||||||
|
{
|
||||||
|
QMainWindow::showEvent(showEvent);
|
||||||
|
if (m_oglWidget != 0)
|
||||||
|
m_oglWidget->makeCurrent();
|
||||||
|
m_statusInfo->show();
|
||||||
|
m_statusBarTimer->start(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::hideEvent(QHideEvent *hideEvent)
|
||||||
|
{
|
||||||
|
QMainWindow::hideEvent(hideEvent);
|
||||||
|
m_statusInfo->hide();
|
||||||
|
m_statusBarTimer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::updateStatusBar()
|
||||||
|
{
|
||||||
|
m_statusInfo->setText(m_landscapeScene->zoneNameFromMousePos());
|
||||||
|
}
|
||||||
|
|
||||||
void LandscapeEditorWindow::createMenus()
|
void LandscapeEditorWindow::createMenus()
|
||||||
{
|
{
|
||||||
|
Core::MenuManager *menuManager = Core::ICore::instance()->menuManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeEditorWindow::createToolBars()
|
||||||
|
{
|
||||||
|
Core::MenuManager *menuManager = Core::ICore::instance()->menuManager();
|
||||||
|
//QAction *action = menuManager->action(Core::Constants::NEW);
|
||||||
|
//m_ui.fileToolBar->addAction(action);
|
||||||
|
//action = menuManager->action(Core::Constants::SAVE);
|
||||||
|
//m_ui.fileToolBar->addAction(action);
|
||||||
|
//action = menuManager->action(Core::Constants::SAVE_AS);
|
||||||
|
//m_ui.fileToolBar->addAction(action);
|
||||||
|
|
||||||
|
QAction *action = menuManager->action(Core::Constants::OPEN);
|
||||||
|
m_ui.fileToolBar->addAction(m_ui.newLandAction);
|
||||||
|
m_ui.fileToolBar->addAction(action);
|
||||||
|
m_ui.fileToolBar->addAction(m_ui.saveAction);
|
||||||
|
m_ui.fileToolBar->addSeparator();
|
||||||
|
|
||||||
|
action = menuManager->action(Core::Constants::UNDO);
|
||||||
|
if (action != 0)
|
||||||
|
m_ui.fileToolBar->addAction(action);
|
||||||
|
|
||||||
|
action = menuManager->action(Core::Constants::REDO);
|
||||||
|
if (action != 0)
|
||||||
|
m_ui.fileToolBar->addAction(action);
|
||||||
|
|
||||||
|
m_ui.zoneToolBar->insertAction(m_ui.enableGridAction, m_ui.landscapesDockWidget->toggleViewAction());
|
||||||
|
m_ui.zoneToolBar->insertAction(m_ui.enableGridAction, m_ui.zonesDockWidget->toggleViewAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LandscapeEditorWindow::readSettings()
|
void LandscapeEditorWindow::readSettings()
|
||||||
{
|
{
|
||||||
QSettings *settings = Core::ICore::instance()->settings();
|
QSettings *settings = Core::ICore::instance()->settings();
|
||||||
settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
|
settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
|
||||||
|
restoreState(settings->value(Constants::LANDSCAPE_WINDOW_STATE).toByteArray());
|
||||||
|
restoreGeometry(settings->value(Constants::LANDSCAPE_WINDOW_GEOMETRY).toByteArray());
|
||||||
|
|
||||||
|
// Read landscape data directory (contains sub-paths: zone logos, zone bitmaps)
|
||||||
|
m_zoneBuilder->init(settings->value(Constants::LANDSCAPE_DATA_DIRECTORY).toString());
|
||||||
|
m_ui.zoneListWidget->updateUi();
|
||||||
|
|
||||||
|
// Use OpenGL graphics system instead raster graphics system
|
||||||
|
if (settings->value(Constants::LANDSCAPE_USE_OPENGL, false).toBool())
|
||||||
|
{
|
||||||
|
m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer));
|
||||||
|
m_ui.graphicsView->setViewport(m_oglWidget);
|
||||||
|
}
|
||||||
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +404,9 @@ void LandscapeEditorWindow::writeSettings()
|
||||||
{
|
{
|
||||||
QSettings *settings = Core::ICore::instance()->settings();
|
QSettings *settings = Core::ICore::instance()->settings();
|
||||||
settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
|
settings->beginGroup(Constants::LANDSCAPE_EDITOR_SECTION);
|
||||||
|
settings->setValue(Constants::LANDSCAPE_WINDOW_STATE, saveState());
|
||||||
|
settings->setValue(Constants::LANDSCAPE_WINDOW_GEOMETRY, saveGeometry());
|
||||||
|
settings->setValue(Constants::LANDSCAPE_DATA_DIRECTORY, m_zoneBuilder->dataPath());
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
settings->sync();
|
settings->sync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -23,16 +22,22 @@
|
||||||
|
|
||||||
// Qt includes
|
// Qt includes
|
||||||
#include <QtGui/QUndoStack>
|
#include <QtGui/QUndoStack>
|
||||||
|
#include <QtOpenGL/QGLWidget>
|
||||||
|
#include <QtGui/QLabel>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
namespace LandscapeEditor
|
namespace LandscapeEditor
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class LandscapeScene;
|
||||||
|
class ZoneBuilder;
|
||||||
|
|
||||||
class LandscapeEditorWindow: public QMainWindow
|
class LandscapeEditorWindow: public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LandscapeEditorWindow(QWidget *parent = 0);
|
explicit LandscapeEditorWindow(QWidget *parent = 0);
|
||||||
~LandscapeEditorWindow();
|
~LandscapeEditorWindow();
|
||||||
|
|
||||||
QUndoStack *undoStack() const;
|
QUndoStack *undoStack() const;
|
||||||
|
@ -40,14 +45,41 @@ public:
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void open();
|
void open();
|
||||||
|
void save();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
void openProjectSettings();
|
||||||
|
void openSnapshotDialog();
|
||||||
|
void customContextMenu();
|
||||||
|
void updateStatusBar();
|
||||||
|
void newLand();
|
||||||
|
void setActiveLand();
|
||||||
|
void saveSelectedLand();
|
||||||
|
void saveAsSelectedLand();
|
||||||
|
void deleteSelectedLand();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void showEvent(QShowEvent *showEvent);
|
||||||
|
virtual void hideEvent(QHideEvent *hideEvent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createMenus();
|
void createMenus();
|
||||||
|
void createToolBars();
|
||||||
void readSettings();
|
void readSettings();
|
||||||
void writeSettings();
|
void writeSettings();
|
||||||
|
|
||||||
|
void setActiveLandscape(int row);
|
||||||
|
void saveLandscape(int row, bool force);
|
||||||
|
int createLandscape(const QString &fileName);
|
||||||
|
|
||||||
|
QLabel *m_statusInfo;
|
||||||
|
QTimer *m_statusBarTimer;
|
||||||
|
|
||||||
|
QListWidgetItem *m_currentItem;
|
||||||
|
LandscapeScene *m_landscapeScene;
|
||||||
|
ZoneBuilder *m_zoneBuilder;
|
||||||
QUndoStack *m_undoStack;
|
QUndoStack *m_undoStack;
|
||||||
|
QGLWidget *m_oglWidget;
|
||||||
Ui::LandscapeEditorWindow m_ui;
|
Ui::LandscapeEditorWindow m_ui;
|
||||||
}; /* class LandscapeEditorWindow */
|
}; /* class LandscapeEditorWindow */
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,42 @@
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="margin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QGraphicsView" name="graphicsView"/>
|
<widget class="LandscapeEditor::LandscapeView" name="graphicsView">
|
||||||
|
<property name="sceneRect">
|
||||||
|
<rectf>
|
||||||
|
<x>0.000000000000000</x>
|
||||||
|
<y>0.000000000000000</y>
|
||||||
|
<width>0.000000000000000</width>
|
||||||
|
<height>0.000000000000000</height>
|
||||||
|
</rectf>
|
||||||
|
</property>
|
||||||
|
<property name="dragMode">
|
||||||
|
<enum>QGraphicsView::NoDrag</enum>
|
||||||
|
</property>
|
||||||
|
<property name="transformationAnchor">
|
||||||
|
<enum>QGraphicsView::AnchorUnderMouse</enum>
|
||||||
|
</property>
|
||||||
|
<property name="resizeAnchor">
|
||||||
|
<enum>QGraphicsView::AnchorUnderMouse</enum>
|
||||||
|
</property>
|
||||||
|
<property name="viewportUpdateMode">
|
||||||
|
<enum>QGraphicsView::FullViewportUpdate</enum>
|
||||||
|
</property>
|
||||||
|
<property name="optimizationFlags">
|
||||||
|
<set>QGraphicsView::DontSavePainterState</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QToolBar" name="toolBar">
|
<widget class="QToolBar" name="fileToolBar">
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>toolBar</string>
|
<string>toolBar</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -35,7 +65,177 @@
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QDockWidget" name="zonesDockWidget">
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_zones.png</normaloff>:/icons/ic_nel_zones.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Zones</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="dockWidgetArea">
|
||||||
|
<number>2</number>
|
||||||
|
</attribute>
|
||||||
|
<widget class="LandscapeEditor::ListZonesWidget" name="zoneListWidget"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QDockWidget" name="landscapesDockWidget">
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_zone.png</normaloff>:/icons/ic_nel_zone.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Landscapes</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="dockWidgetArea">
|
||||||
|
<number>1</number>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QWidget" name="dockWidgetContents">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<property name="margin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QListWidget" name="landscapesListWidget"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="zoneToolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="transitionModeAction"/>
|
||||||
|
<addaction name="enableGridAction"/>
|
||||||
|
<addaction name="projectSettingsAction"/>
|
||||||
|
<addaction name="snapshotAction"/>
|
||||||
|
</widget>
|
||||||
|
<action name="projectSettingsAction">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Project settings</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="enableGridAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_grid.png</normaloff>:/icons/ic_grid.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>EnableGrid</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Show/Hide Grid</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+G</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="snapshotAction">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_snapshot.png</normaloff>:/icons/ic_snapshot.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>snapshot</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="saveAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="setActiveLandAction">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_zone.png</normaloff>:/icons/ic_nel_zone.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Set active</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Set active selected landscape</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="saveLandAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save selected landscape</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="saveAsLandAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save As landscape</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save as selected landscape</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="deleteLandAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Delete selected landscape</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="newLandAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>New</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Create new landscape</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="transitionModeAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_landscape_item.png</normaloff>
|
||||||
|
<normalon>:/icons/ic_nel_transition_land.png</normalon>:/icons/ic_nel_landscape_item.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Transition mode</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enable transition mode</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>LandscapeEditor::ListZonesWidget</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>list_zones_widget.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>LandscapeEditor::LandscapeView</class>
|
||||||
|
<extends>QGraphicsView</extends>
|
||||||
|
<header>landscape_view.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="landscape_editor.qrc"/>
|
<include location="landscape_editor.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -0,0 +1,498 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "landscape_scene.h"
|
||||||
|
#include "pixmap_database.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QPainter>
|
||||||
|
#include <QtGui/QGraphicsPixmapItem>
|
||||||
|
#include <QtGui/QGraphicsSimpleTextItem>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
static const int ZONE_NAME = 0;
|
||||||
|
static const int LAYER_ZONES = 2;
|
||||||
|
static const int LAYER_EMPTY_ZONES = 3;
|
||||||
|
static const int LAYER_BLACKOUT = 4;
|
||||||
|
const char *const LAYER_BLACKOUT_NAME = "blackout";
|
||||||
|
|
||||||
|
const int MAX_SCENE_WIDTH = 256;
|
||||||
|
const int MAX_SCENE_HEIGHT = 256;
|
||||||
|
|
||||||
|
LandscapeScene::LandscapeScene(int sizeCell, QObject *parent)
|
||||||
|
: QGraphicsScene(parent),
|
||||||
|
m_cellSize(sizeCell),
|
||||||
|
m_transitionMode(false),
|
||||||
|
m_mouseButton(Qt::NoButton),
|
||||||
|
m_zoneBuilder(0)
|
||||||
|
{
|
||||||
|
setSceneRect(QRectF(0, m_cellSize, MAX_SCENE_WIDTH * m_cellSize, MAX_SCENE_HEIGHT * m_cellSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
LandscapeScene::~LandscapeScene()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int LandscapeScene::cellSize() const
|
||||||
|
{
|
||||||
|
return m_cellSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::setZoneBuilder(ZoneBuilder *zoneBuilder)
|
||||||
|
{
|
||||||
|
m_zoneBuilder = zoneBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsItem *LandscapeScene::createItemZone(const LigoData &data, const ZonePosition &zonePos)
|
||||||
|
{
|
||||||
|
if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (data.zoneName == STRING_UNUSED)
|
||||||
|
return createItemEmptyZone(zonePos);
|
||||||
|
|
||||||
|
if ((m_zoneBuilder == 0) || (data.zoneName.empty()))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Get image from pixmap database
|
||||||
|
QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(data.zoneName.c_str()));
|
||||||
|
if (pixmap == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Rotate the image counterclockwise
|
||||||
|
QMatrix matrix;
|
||||||
|
matrix.rotate(-data.rot * 90.0);
|
||||||
|
|
||||||
|
QGraphicsPixmapItem *item;
|
||||||
|
|
||||||
|
if (data.flip == 0)
|
||||||
|
{
|
||||||
|
item = addPixmap(pixmap->transformed(matrix, Qt::SmoothTransformation));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// mirror image
|
||||||
|
QImage mirrorImage = pixmap->toImage();
|
||||||
|
QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false));
|
||||||
|
item = addPixmap(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation));
|
||||||
|
}
|
||||||
|
// Enable bilinear filtering
|
||||||
|
item->setTransformationMode(Qt::SmoothTransformation);
|
||||||
|
|
||||||
|
sint32 sizeX = 1, sizeY = 1;
|
||||||
|
sizeX = float(pixmap->width()) / m_zoneBuilder->pixmapDatabase()->textureSize();
|
||||||
|
sizeY = float(pixmap->width()) / m_zoneBuilder->pixmapDatabase()->textureSize();
|
||||||
|
|
||||||
|
sint32 deltaX = 0, deltaY = 0;
|
||||||
|
|
||||||
|
// Calculate offset for graphics item (for items with size that are larger than 1)
|
||||||
|
if ((sizeX > 1) || (sizeY > 1))
|
||||||
|
{
|
||||||
|
if (data.flip == 0)
|
||||||
|
{
|
||||||
|
switch (data.rot)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
deltaX = -data.posX;
|
||||||
|
deltaY = -data.posY + sizeY - 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
deltaX = -(sizeY - 1 - data.posY);
|
||||||
|
deltaY = -data.posX + sizeX - 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
deltaX = -(sizeX - 1 - data.posX);
|
||||||
|
deltaY = data.posY;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
deltaX = -data.posY;
|
||||||
|
deltaY = data.posX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (data.rot)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
deltaX = -(sizeX - 1 - data.posX);
|
||||||
|
deltaY = -data.posY + sizeY - 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
deltaX = -(sizeY - 1 - data.posY);
|
||||||
|
deltaY = +data.posX;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
deltaX = -data.posX;
|
||||||
|
deltaY = data.posY;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
deltaX = -data.posY;
|
||||||
|
deltaY = -data.posX + sizeX - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set position graphics item with offset for large piece
|
||||||
|
item->setPos((zonePos.x + deltaX) * m_cellSize, (abs(int(zonePos.y + deltaY))) * m_cellSize);
|
||||||
|
|
||||||
|
// The size graphics item should be equal or proportional m_cellSize
|
||||||
|
item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
|
||||||
|
|
||||||
|
item->setData(ZONE_NAME, QString(data.zoneName.c_str()));
|
||||||
|
|
||||||
|
// for not full item zone
|
||||||
|
item->setZValue(LAYER_ZONES);
|
||||||
|
|
||||||
|
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsItem *LandscapeScene::createItemEmptyZone(const ZonePosition &zonePos)
|
||||||
|
{
|
||||||
|
if (m_zoneBuilder == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (checkUnderZone(zonePos.x, zonePos.y))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Get image from pixmap database
|
||||||
|
QPixmap *pixmap = m_zoneBuilder->pixmapDatabase()->pixmap(QString(STRING_UNUSED));
|
||||||
|
|
||||||
|
if (pixmap == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
QGraphicsPixmapItem *item = addPixmap(*pixmap);
|
||||||
|
|
||||||
|
// Enable bilinear filtering
|
||||||
|
item->setTransformationMode(Qt::SmoothTransformation);
|
||||||
|
|
||||||
|
// Set position graphics item
|
||||||
|
item->setPos(zonePos.x * m_cellSize, abs(int(zonePos.y)) * m_cellSize);
|
||||||
|
|
||||||
|
// The size graphics item should be equal or proportional m_cellSize
|
||||||
|
item->setScale(float(m_cellSize) / m_zoneBuilder->pixmapDatabase()->textureSize());
|
||||||
|
|
||||||
|
// for not full item zone
|
||||||
|
item->setZValue(LAYER_EMPTY_ZONES);
|
||||||
|
|
||||||
|
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsRectItem *LandscapeScene::createLayerBlackout(const NLLIGO::CZoneRegion &zoneRegion)
|
||||||
|
{
|
||||||
|
QGraphicsRectItem *rectItem = addRect(zoneRegion.getMinX() * m_cellSize,
|
||||||
|
abs(zoneRegion.getMaxY()) * m_cellSize,
|
||||||
|
(abs(zoneRegion.getMaxX() - zoneRegion.getMinX()) + 1) * m_cellSize,
|
||||||
|
(abs(zoneRegion.getMaxY() - zoneRegion.getMinY()) + 1) * m_cellSize,
|
||||||
|
Qt::NoPen, QBrush(QColor(0, 0, 0, 50)));
|
||||||
|
|
||||||
|
rectItem->setZValue(LAYER_BLACKOUT);
|
||||||
|
rectItem->setData(ZONE_NAME, QString(LAYER_BLACKOUT_NAME));
|
||||||
|
return rectItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::deleteItemZone(const ZonePosition &zonePos)
|
||||||
|
{
|
||||||
|
QGraphicsItem *item = itemAt(zonePos.x * m_cellSize, abs(zonePos.y) * m_cellSize);
|
||||||
|
if ((item != 0) && (item->data(ZONE_NAME).toString() != QString(LAYER_BLACKOUT_NAME)))
|
||||||
|
{
|
||||||
|
removeItem(item);
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
|
||||||
|
{
|
||||||
|
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
|
||||||
|
{
|
||||||
|
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string zoneName = zoneRegion.getName(i, j);
|
||||||
|
if (zoneName == STRING_UNUSED)
|
||||||
|
{
|
||||||
|
ZonePosition zonePos(i, j, -1);
|
||||||
|
QGraphicsItem *item = createItemEmptyZone(zonePos);
|
||||||
|
}
|
||||||
|
else if (!zoneName.empty())
|
||||||
|
{
|
||||||
|
LigoData data;
|
||||||
|
ZonePosition zonePos(i, j, -1);
|
||||||
|
data.zoneName = zoneName;
|
||||||
|
data.rot = zoneRegion.getRot(i, j);
|
||||||
|
data.flip = zoneRegion.getFlip(i, j);
|
||||||
|
data.posX = zoneRegion.getPosX(i, j);
|
||||||
|
data.posY = zoneRegion.getPosY(i, j);
|
||||||
|
QGraphicsItem *item = createItemZone(data, zonePos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
|
||||||
|
{
|
||||||
|
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
|
||||||
|
{
|
||||||
|
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
|
||||||
|
{
|
||||||
|
deleteItemZone(ZonePosition(i, -j, -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::snapshot(const QString &fileName, int width, int height, const QRectF &landRect)
|
||||||
|
{
|
||||||
|
if (m_zoneBuilder == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Create image
|
||||||
|
QImage image(landRect.width(), landRect.height(), QImage::Format_RGB888);
|
||||||
|
QPainter painter(&image);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
|
||||||
|
// Add white background
|
||||||
|
painter.setBrush(QBrush(Qt::white));
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.drawRect(0, 0, landRect.width(), landRect.height());
|
||||||
|
|
||||||
|
// Paint landscape
|
||||||
|
render(&painter, QRectF(0, 0, landRect.width(), landRect.height()), landRect);
|
||||||
|
|
||||||
|
QImage scaledImage = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
scaledImage.save(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LandscapeScene::zoneNameFromMousePos() const
|
||||||
|
{
|
||||||
|
if ((m_posY > 0) || (m_posY < -MAX_SCENE_HEIGHT) ||
|
||||||
|
(m_posX < 0) || (m_posX > MAX_SCENE_WIDTH))
|
||||||
|
return "NOT A VALID ZONE";
|
||||||
|
|
||||||
|
return QString("%1_%2%3 %4 %5 ").arg(-m_posY).arg(QChar('A' + (m_posX/26))).
|
||||||
|
arg(QChar('A' + (m_posX%26))).arg(m_mouseX, 0,'f',2).arg(-m_mouseY, 0,'f',2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
qreal x = mouseEvent->scenePos().x();
|
||||||
|
qreal y = mouseEvent->scenePos().y();
|
||||||
|
if ((x < 0) || (y < 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_posX = sint32(floor(x / m_cellSize));
|
||||||
|
m_posY = sint32(-floor(y / m_cellSize));
|
||||||
|
|
||||||
|
if (m_zoneBuilder == 0)
|
||||||
|
return;
|
||||||
|
if (m_transitionMode)
|
||||||
|
{
|
||||||
|
if (mouseEvent->button() == Qt::LeftButton)
|
||||||
|
|
||||||
|
// Need add offset(= cellSize) on y axes
|
||||||
|
m_zoneBuilder->addTransition(sint(x), sint(-y + m_cellSize));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mouseEvent->button() == Qt::LeftButton)
|
||||||
|
m_zoneBuilder->addZone(m_posX, m_posY);
|
||||||
|
else if (mouseEvent->button() == Qt::RightButton)
|
||||||
|
m_zoneBuilder->delZone(m_posX, m_posY);
|
||||||
|
}
|
||||||
|
m_mouseButton = mouseEvent->button();
|
||||||
|
|
||||||
|
QGraphicsScene::mousePressEvent(mouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
qreal x = mouseEvent->scenePos().x();
|
||||||
|
qreal y = mouseEvent->scenePos().y();
|
||||||
|
|
||||||
|
sint32 posX = sint32(floor(x / m_cellSize));
|
||||||
|
sint32 posY = sint32(-floor(y / m_cellSize));
|
||||||
|
|
||||||
|
if ((m_posX != posX || m_posY != posY) &&
|
||||||
|
(m_mouseButton == Qt::LeftButton ||
|
||||||
|
m_mouseButton == Qt::RightButton))
|
||||||
|
{
|
||||||
|
if (m_transitionMode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_mouseButton == Qt::LeftButton)
|
||||||
|
m_zoneBuilder->addZone(posX, posY);
|
||||||
|
else if (m_mouseButton == Qt::RightButton)
|
||||||
|
m_zoneBuilder->delZone(posX, posY);
|
||||||
|
}
|
||||||
|
m_posX = posX;
|
||||||
|
m_posY = posY;
|
||||||
|
QApplication::processEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_posX = posX;
|
||||||
|
m_posY = posY;
|
||||||
|
|
||||||
|
m_mouseX = mouseEvent->scenePos().x();
|
||||||
|
m_mouseY = mouseEvent->scenePos().y() - m_cellSize;
|
||||||
|
QGraphicsScene::mouseMoveEvent(mouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
m_mouseButton = Qt::NoButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandscapeScene::checkUnderZone(const int posX, const int posY)
|
||||||
|
{
|
||||||
|
QGraphicsItem *item = itemAt((posX * m_cellSize), abs(posY) * m_cellSize);
|
||||||
|
if (item != 0)
|
||||||
|
{
|
||||||
|
//if (item->data(ZONE_NAME) == QString(LAYER_BLACKOUT_NAME))
|
||||||
|
// return false;
|
||||||
|
//else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandscapeScene::transitionMode() const
|
||||||
|
{
|
||||||
|
return m_transitionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::setTransitionMode(bool enabled)
|
||||||
|
{
|
||||||
|
m_transitionMode = enabled;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::drawForeground(QPainter *painter, const QRectF &rect)
|
||||||
|
{
|
||||||
|
QGraphicsScene::drawForeground(painter, rect);
|
||||||
|
if ((m_zoneBuilder->currentIdZoneRegion() != -1) && (m_transitionMode))
|
||||||
|
drawTransition(painter, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeScene::drawTransition(QPainter *painter, const QRectF &rect)
|
||||||
|
{
|
||||||
|
int left = int(floor(rect.left() / m_cellSize));
|
||||||
|
int right = int(floor(rect.right() / m_cellSize));
|
||||||
|
int top = int(floor(rect.top() / m_cellSize));
|
||||||
|
int bottom = int(floor(rect.bottom() / m_cellSize));
|
||||||
|
|
||||||
|
QVector<QLine> redLines;
|
||||||
|
QVector<QLine> whiteLines;
|
||||||
|
|
||||||
|
for (int i = left; i < right + 1; ++i)
|
||||||
|
{
|
||||||
|
for (int j = top; j < bottom + 1; ++j)
|
||||||
|
{
|
||||||
|
// Get LIGO data
|
||||||
|
NLLIGO::CZoneRegion &zoneRegion = m_zoneBuilder->currentZoneRegion()->ligoZoneRegion();
|
||||||
|
uint8 ceUp = zoneRegion.getCutEdge (i, -j, 0);
|
||||||
|
uint8 ceLeft = zoneRegion.getCutEdge (i, -j, 2);
|
||||||
|
if ((ceUp > 0) && (ceUp < 3))
|
||||||
|
{
|
||||||
|
// Calculate position vertical lines
|
||||||
|
int x1, x2, y1, y2;
|
||||||
|
|
||||||
|
y1 = j * m_cellSize + m_cellSize / 12.0f;
|
||||||
|
y2 = y1 - (m_cellSize / 6.0f);
|
||||||
|
|
||||||
|
x1 = i * m_cellSize + 3.0f * m_cellSize / 12.0f;
|
||||||
|
x2 = i * m_cellSize + 5.0f * m_cellSize / 12.0f;
|
||||||
|
if (ceUp == 1)
|
||||||
|
{
|
||||||
|
whiteLines.push_back(QLine(x1, y1, x1, y2));
|
||||||
|
whiteLines.push_back(QLine(x2, y1, x2, y2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
redLines.push_back(QLine(x1, y1, x1, y2));
|
||||||
|
redLines.push_back(QLine(x2, y1, x2, y2));
|
||||||
|
}
|
||||||
|
|
||||||
|
x1 = i * m_cellSize + 7.0f * m_cellSize / 12.0f;
|
||||||
|
x2 = i * m_cellSize + 9.0f * m_cellSize / 12.0f;
|
||||||
|
if (ceUp == 1)
|
||||||
|
{
|
||||||
|
redLines.push_back(QLine(x1, y1, x1, y2));
|
||||||
|
redLines.push_back(QLine(x2, y1, x2, y2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
whiteLines.push_back(QLine(x1, y1, x1, y2));
|
||||||
|
whiteLines.push_back(QLine(x2, y1, x2, y2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((ceLeft > 0) && (ceLeft < 3))
|
||||||
|
{
|
||||||
|
// Calculate position horizontal lines
|
||||||
|
int x1, x2, y1, y2;
|
||||||
|
|
||||||
|
x1 = i * m_cellSize - m_cellSize / 12.0f;
|
||||||
|
x2 = x1 + (m_cellSize / 6.0f);
|
||||||
|
|
||||||
|
y1 = j * m_cellSize + 3.0f * m_cellSize / 12.0f;
|
||||||
|
y2 = j * m_cellSize + 5.0f * m_cellSize / 12.0f;
|
||||||
|
if (ceLeft == 1)
|
||||||
|
{
|
||||||
|
redLines.push_back(QLine(x1, y1, x2, y1));
|
||||||
|
redLines.push_back(QLine(x1, y2, x2, y2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
whiteLines.push_back(QLine(x1, y1, x2, y1));
|
||||||
|
whiteLines.push_back(QLine(x1, y2, x2, y2));
|
||||||
|
}
|
||||||
|
|
||||||
|
y1 = j * m_cellSize + 7.0f * m_cellSize / 12.0f;
|
||||||
|
y2 = j * m_cellSize + 9.0f * m_cellSize / 12.0f;
|
||||||
|
if (ceLeft == 1)
|
||||||
|
{
|
||||||
|
whiteLines.push_back(QLine(x1, y1, x2, y1));
|
||||||
|
whiteLines.push_back(QLine(x1, y2, x2, y2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
redLines.push_back(QLine(x1, y1, x2, y1));
|
||||||
|
redLines.push_back(QLine(x1, y2, x2, y2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw lines
|
||||||
|
painter->setPen(QPen(Qt::red, 0, Qt::SolidLine));
|
||||||
|
painter->drawLines(redLines);
|
||||||
|
painter->setPen(QPen(Qt::white, 0, Qt::SolidLine));
|
||||||
|
painter->drawLines(whiteLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef LANDSCAPE_SCENE_H
|
||||||
|
#define LANDSCAPE_SCENE_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "zone_region_editor.h"
|
||||||
|
#include "builder_zone.h"
|
||||||
|
#include "landscape_editor_global.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/zone_region.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QGraphicsScene>
|
||||||
|
#include <QtGui/QGraphicsSceneMouseEvent>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class LandscapeScene
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class LandscapeScene : public QGraphicsScene
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
LandscapeScene(int sizeCell = 160, QObject *parent = 0);
|
||||||
|
virtual ~LandscapeScene();
|
||||||
|
|
||||||
|
int cellSize() const;
|
||||||
|
void setZoneBuilder(ZoneBuilder *zoneBuilder);
|
||||||
|
|
||||||
|
QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos);
|
||||||
|
QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos);
|
||||||
|
QGraphicsRectItem *createLayerBlackout(const NLLIGO::CZoneRegion &zoneRegion);
|
||||||
|
void deleteItemZone(const ZonePosition &zonePos);
|
||||||
|
|
||||||
|
void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
|
||||||
|
void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
|
||||||
|
|
||||||
|
void snapshot(const QString &fileName, int width, int height, const QRectF &landRect);
|
||||||
|
|
||||||
|
QString zoneNameFromMousePos() const;
|
||||||
|
bool transitionMode() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void setTransitionMode(bool enabled);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
virtual void drawForeground(QPainter *painter, const QRectF &rect);
|
||||||
|
|
||||||
|
void drawTransition(QPainter *painter, const QRectF &rect);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool checkUnderZone(const int posX, const int posY);
|
||||||
|
|
||||||
|
int m_cellSize;
|
||||||
|
bool m_transitionMode;
|
||||||
|
qreal m_mouseX, m_mouseY;
|
||||||
|
sint32 m_posX, m_posY;
|
||||||
|
Qt::MouseButton m_mouseButton;
|
||||||
|
ZoneBuilder *m_zoneBuilder;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // LANDSCAPE_SCENE_H
|
|
@ -0,0 +1,331 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "landscape_scene_base.h"
|
||||||
|
#include "pixmap_database.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QPainter>
|
||||||
|
#include <QtGui/QGraphicsPixmapItem>
|
||||||
|
#include <QtGui/QGraphicsSimpleTextItem>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
static const int ZONE_NAME = 0;
|
||||||
|
static const int LAYER_ZONES = 2;
|
||||||
|
static const int LAYER_EMPTY_ZONES = 3;
|
||||||
|
|
||||||
|
// TODO: delete
|
||||||
|
const char *const LAYER_BLACKOUT_NAME = "blackout";
|
||||||
|
|
||||||
|
const int MAX_SCENE_WIDTH = 256;
|
||||||
|
const int MAX_SCENE_HEIGHT = 256;
|
||||||
|
|
||||||
|
LandscapeSceneBase::LandscapeSceneBase(int sizeCell, QObject *parent)
|
||||||
|
: QGraphicsScene(parent),
|
||||||
|
m_cellSize(sizeCell),
|
||||||
|
m_zoneBuilderBase(0)
|
||||||
|
{
|
||||||
|
setSceneRect(QRectF(0, m_cellSize, MAX_SCENE_WIDTH * m_cellSize, MAX_SCENE_HEIGHT * m_cellSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
LandscapeSceneBase::~LandscapeSceneBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int LandscapeSceneBase::cellSize() const
|
||||||
|
{
|
||||||
|
return m_cellSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeSceneBase::setZoneBuilder(ZoneBuilderBase *zoneBuilder)
|
||||||
|
{
|
||||||
|
m_zoneBuilderBase = zoneBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsItem *LandscapeSceneBase::createItemZone(const LigoData &data, const ZonePosition &zonePos)
|
||||||
|
{
|
||||||
|
if ((data.zoneName == STRING_OUT_OF_BOUND) || (checkUnderZone(zonePos.x, zonePos.y)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (data.zoneName == STRING_UNUSED)
|
||||||
|
return createItemEmptyZone(zonePos);
|
||||||
|
|
||||||
|
if ((m_zoneBuilderBase == 0) || (data.zoneName.empty()))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Get image from pixmap database
|
||||||
|
QPixmap *pixmap = m_zoneBuilderBase->pixmapDatabase()->pixmap(QString(data.zoneName.c_str()));
|
||||||
|
if (pixmap == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Rotate the image counter clockwise
|
||||||
|
QMatrix matrix;
|
||||||
|
matrix.rotate(-data.rot * 90.0);
|
||||||
|
|
||||||
|
QGraphicsPixmapItem *item;
|
||||||
|
|
||||||
|
if (data.flip == 0)
|
||||||
|
{
|
||||||
|
item = addPixmap(pixmap->transformed(matrix, Qt::SmoothTransformation));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// mirror image
|
||||||
|
QImage mirrorImage = pixmap->toImage();
|
||||||
|
QPixmap mirrorPixmap = QPixmap::fromImage(mirrorImage.mirrored(true, false));
|
||||||
|
item = addPixmap(mirrorPixmap.transformed(matrix, Qt::SmoothTransformation));
|
||||||
|
}
|
||||||
|
// Enable bilinear filtering
|
||||||
|
item->setTransformationMode(Qt::SmoothTransformation);
|
||||||
|
|
||||||
|
sint32 sizeX = 1, sizeY = 1;
|
||||||
|
sizeX = float(pixmap->width()) / m_zoneBuilderBase->pixmapDatabase()->textureSize();
|
||||||
|
sizeY = float(pixmap->width()) / m_zoneBuilderBase->pixmapDatabase()->textureSize();
|
||||||
|
|
||||||
|
sint32 deltaX = 0, deltaY = 0;
|
||||||
|
|
||||||
|
// Calculate offset for graphics item (for items with size that are larger than 1)
|
||||||
|
if ((sizeX > 1) || (sizeY > 1))
|
||||||
|
{
|
||||||
|
if (data.flip == 0)
|
||||||
|
{
|
||||||
|
switch (data.rot)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
deltaX = -data.posX;
|
||||||
|
deltaY = -data.posY + sizeY - 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
deltaX = -(sizeY - 1 - data.posY);
|
||||||
|
deltaY = -data.posX + sizeX - 1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
deltaX = -(sizeX - 1 - data.posX);
|
||||||
|
deltaY = data.posY;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
deltaX = -data.posY;
|
||||||
|
deltaY = data.posX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (data.rot)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
deltaX = -(sizeX - 1 - data.posX);
|
||||||
|
deltaY = -data.posY + sizeY - 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
deltaX = -(sizeY - 1 - data.posY);
|
||||||
|
deltaY = +data.posX;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
deltaX = -data.posX;
|
||||||
|
deltaY = data.posY;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
deltaX = -data.posY;
|
||||||
|
deltaY = -data.posX + sizeX - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set position graphics item with offset for large piece
|
||||||
|
item->setPos((zonePos.x + deltaX) * m_cellSize, (abs(int(zonePos.y + deltaY))) * m_cellSize);
|
||||||
|
|
||||||
|
// The size graphics item should be equal or proportional m_cellSize
|
||||||
|
item->setScale(float(m_cellSize) / m_zoneBuilderBase->pixmapDatabase()->textureSize());
|
||||||
|
|
||||||
|
item->setData(ZONE_NAME, QString(data.zoneName.c_str()));
|
||||||
|
|
||||||
|
// for not full item zone
|
||||||
|
item->setZValue(LAYER_ZONES);
|
||||||
|
|
||||||
|
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsItem *LandscapeSceneBase::createItemEmptyZone(const ZonePosition &zonePos)
|
||||||
|
{
|
||||||
|
if (m_zoneBuilderBase == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (checkUnderZone(zonePos.x, zonePos.y))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Get image from pixmap database
|
||||||
|
QPixmap *pixmap = m_zoneBuilderBase->pixmapDatabase()->pixmap(QString(STRING_UNUSED));
|
||||||
|
if (pixmap == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
QGraphicsPixmapItem *item = addPixmap(*pixmap);
|
||||||
|
|
||||||
|
// Enable bilinear filtering
|
||||||
|
item->setTransformationMode(Qt::SmoothTransformation);
|
||||||
|
|
||||||
|
// Set position graphics item
|
||||||
|
item->setPos(zonePos.x * m_cellSize, abs(int(zonePos.y)) * m_cellSize);
|
||||||
|
|
||||||
|
// The size graphics item should be equal or proportional m_cellSize
|
||||||
|
item->setScale(float(m_cellSize) / m_zoneBuilderBase->pixmapDatabase()->textureSize());
|
||||||
|
|
||||||
|
// for not full item zone
|
||||||
|
item->setZValue(LAYER_EMPTY_ZONES);
|
||||||
|
|
||||||
|
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeSceneBase::deleteItemZone(const ZonePosition &zonePos)
|
||||||
|
{
|
||||||
|
QList<QGraphicsItem *> listItems = items(QPointF(zonePos.x * m_cellSize + 10, abs(zonePos.y) * m_cellSize + 10),
|
||||||
|
Qt::IntersectsItemBoundingRect, Qt::AscendingOrder);
|
||||||
|
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||||
|
{
|
||||||
|
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item) != 0)
|
||||||
|
{
|
||||||
|
removeItem(item);
|
||||||
|
delete item;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeSceneBase::addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
|
||||||
|
{
|
||||||
|
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
|
||||||
|
{
|
||||||
|
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string zoneName = zoneRegion.getName(i, j);
|
||||||
|
if (zoneName == STRING_UNUSED)
|
||||||
|
{
|
||||||
|
ZonePosition zonePos(i, j, -1);
|
||||||
|
QGraphicsItem *item = createItemEmptyZone(zonePos);
|
||||||
|
}
|
||||||
|
else if (!zoneName.empty())
|
||||||
|
{
|
||||||
|
LigoData data;
|
||||||
|
ZonePosition zonePos(i, j, -1);
|
||||||
|
data.zoneName = zoneName;
|
||||||
|
data.rot = zoneRegion.getRot(i, j);
|
||||||
|
data.flip = zoneRegion.getFlip(i, j);
|
||||||
|
data.posX = zoneRegion.getPosX(i, j);
|
||||||
|
data.posY = zoneRegion.getPosY(i, j);
|
||||||
|
QGraphicsItem *item = createItemZone(data, zonePos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeSceneBase::delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
|
||||||
|
{
|
||||||
|
for (sint32 i = zoneRegion.getMinX(); i <= zoneRegion.getMaxX(); ++i)
|
||||||
|
{
|
||||||
|
for (sint32 j = zoneRegion.getMinY(); j <= zoneRegion.getMaxY(); ++j)
|
||||||
|
{
|
||||||
|
|
||||||
|
deleteItemZone(ZonePosition(i, -j, -1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeSceneBase::snapshot(const QString &fileName, int width, int height, const QRectF &landRect)
|
||||||
|
{
|
||||||
|
if (m_zoneBuilderBase == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Create image
|
||||||
|
QImage image(landRect.width(), landRect.height(), QImage::Format_RGB888);
|
||||||
|
QPainter painter(&image);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
|
||||||
|
// Add white background
|
||||||
|
painter.setBrush(QBrush(Qt::white));
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.drawRect(0, 0, landRect.width(), landRect.height());
|
||||||
|
|
||||||
|
// Paint landscape
|
||||||
|
render(&painter, QRectF(0, 0, landRect.width(), landRect.height()), landRect);
|
||||||
|
|
||||||
|
QImage scaledImage = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
scaledImage.save(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LandscapeSceneBase::zoneNameFromMousePos() const
|
||||||
|
{
|
||||||
|
if ((m_posY > 0) || (m_posY < -MAX_SCENE_HEIGHT) ||
|
||||||
|
(m_posX < 0) || (m_posX > MAX_SCENE_WIDTH))
|
||||||
|
return "NOT A VALID ZONE";
|
||||||
|
|
||||||
|
return QString("%1_%2%3 %4 %5 ").arg(-m_posY+1).arg(QChar('A' + (m_posX/26))).
|
||||||
|
arg(QChar('A' + (m_posX%26))).arg(m_mouseX, 0,'f',2).arg(-m_mouseY, 0,'f',2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeSceneBase::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
QGraphicsScene::mousePressEvent(mouseEvent);
|
||||||
|
|
||||||
|
qreal x = mouseEvent->scenePos().x();
|
||||||
|
qreal y = mouseEvent->scenePos().y();
|
||||||
|
m_posX = sint32(floor(x / m_cellSize));
|
||||||
|
m_posY = sint32(-floor(y / m_cellSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeSceneBase::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
m_mouseX = mouseEvent->scenePos().x();
|
||||||
|
m_mouseY = mouseEvent->scenePos().y() - m_cellSize;
|
||||||
|
|
||||||
|
m_posX = sint32(floor(m_mouseX / m_cellSize));
|
||||||
|
m_posY = sint32(-floor(m_mouseY / m_cellSize));
|
||||||
|
|
||||||
|
QGraphicsScene::mouseMoveEvent(mouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandscapeSceneBase::checkUnderZone(const int posX, const int posY)
|
||||||
|
{
|
||||||
|
// TODO: Why crash program?
|
||||||
|
// QList<QGraphicsItem *> listItems = items(QPointF(posX * m_cellSize + 10, abs(posY) * m_cellSize + 10),
|
||||||
|
// Qt::IntersectsItemBoundingRect, Qt::AscendingOrder);
|
||||||
|
|
||||||
|
QList<QGraphicsItem *> listItems = items();
|
||||||
|
|
||||||
|
QPointF point(posX, abs(posY));
|
||||||
|
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||||
|
{
|
||||||
|
if (item->pos() == point)
|
||||||
|
{
|
||||||
|
if (qgraphicsitem_cast<QGraphicsPixmapItem *>(item) != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,79 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef LANDSCAPE_SCENE_BASE_H
|
||||||
|
#define LANDSCAPE_SCENE_BASE_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "landscape_editor_global.h"
|
||||||
|
#include "builder_zone_base.h"
|
||||||
|
#include "zone_region_editor.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/zone_region.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QGraphicsScene>
|
||||||
|
#include <QtGui/QGraphicsSceneMouseEvent>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class LandscapeSceneBase
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class LANDSCAPE_EDITOR_EXPORT LandscapeSceneBase : public QGraphicsScene
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
LandscapeSceneBase(int sizeCell = 160, QObject *parent = 0);
|
||||||
|
virtual ~LandscapeSceneBase();
|
||||||
|
|
||||||
|
int cellSize() const;
|
||||||
|
void setZoneBuilder(ZoneBuilderBase *zoneBuilder);
|
||||||
|
|
||||||
|
QGraphicsItem *createItemZone(const LigoData &data, const ZonePosition &zonePos);
|
||||||
|
QGraphicsItem *createItemEmptyZone(const ZonePosition &zonePos);
|
||||||
|
void deleteItemZone(const ZonePosition &zonePos);
|
||||||
|
|
||||||
|
void addZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
|
||||||
|
void delZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
|
||||||
|
|
||||||
|
void snapshot(const QString &fileName, int width, int height, const QRectF &landRect);
|
||||||
|
|
||||||
|
QString zoneNameFromMousePos() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool checkUnderZone(const int posX, const int posY);
|
||||||
|
|
||||||
|
int m_cellSize;
|
||||||
|
qreal m_mouseX, m_mouseY;
|
||||||
|
sint32 m_posX, m_posY;
|
||||||
|
ZoneBuilderBase *m_zoneBuilderBase;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // LANDSCAPE_SCENE_BASE_H
|
|
@ -0,0 +1,254 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "landscape_view.h"
|
||||||
|
#include "landscape_editor_constants.h"
|
||||||
|
|
||||||
|
#include "../core/icore.h"
|
||||||
|
#include "../core/core_constants.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
LandscapeView::LandscapeView(QWidget *parent)
|
||||||
|
: QGraphicsView(parent),
|
||||||
|
m_visibleGrid(true),
|
||||||
|
m_visibleText(true)
|
||||||
|
{
|
||||||
|
setTransformationAnchor(AnchorUnderMouse);
|
||||||
|
setBackgroundBrush(QBrush(Qt::lightGray));
|
||||||
|
|
||||||
|
m_cellSize = 160;
|
||||||
|
m_maxView = 0.06;
|
||||||
|
m_minView = 32.0;
|
||||||
|
m_maxViewText = 0.6;
|
||||||
|
|
||||||
|
//A modified version of centerOn(), handles special cases
|
||||||
|
setCenter(QPointF(500.0, 500.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
LandscapeView::~LandscapeView()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LandscapeView::isVisibleGrid() const
|
||||||
|
{
|
||||||
|
return m_visibleGrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::setVisibleGrid(bool visible)
|
||||||
|
{
|
||||||
|
m_visibleGrid = visible;
|
||||||
|
scene()->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::setVisibleText(bool visible)
|
||||||
|
{
|
||||||
|
m_visibleText = visible;
|
||||||
|
scene()->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::wheelEvent(QWheelEvent *event)
|
||||||
|
{
|
||||||
|
//How fast we zoom
|
||||||
|
float numSteps = (( event->delta() / 8 ) / 15) * 1.2;
|
||||||
|
|
||||||
|
QMatrix mat = matrix();
|
||||||
|
QPointF mousePosition = event->pos();
|
||||||
|
|
||||||
|
mat.translate((width() / 2) - mousePosition.x(), (height() / 2) - mousePosition.y());
|
||||||
|
|
||||||
|
if ( numSteps > 0 )
|
||||||
|
mat.scale(numSteps, numSteps);
|
||||||
|
else
|
||||||
|
mat.scale(-1 / numSteps, -1 / numSteps);
|
||||||
|
|
||||||
|
mat.translate(mousePosition.x() - (width() / 2), mousePosition.y() - (height() / 2));
|
||||||
|
|
||||||
|
//Adjust to the new center for correct zooming
|
||||||
|
setMatrix(mat);
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
QGraphicsView::mousePressEvent(event);
|
||||||
|
if (event->button() != Qt::MiddleButton)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//For panning the view
|
||||||
|
m_lastPanPoint = event->pos();
|
||||||
|
setCursor(Qt::ClosedHandCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
if(!m_lastPanPoint.isNull())
|
||||||
|
{
|
||||||
|
//Get how much we panned
|
||||||
|
QPointF delta = mapToScene(m_lastPanPoint) - mapToScene(event->pos());
|
||||||
|
m_lastPanPoint = event->pos();
|
||||||
|
|
||||||
|
//Update the center ie. do the pan
|
||||||
|
setCenter(getCenter() + delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsView::mouseMoveEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
m_lastPanPoint = QPoint();
|
||||||
|
setCursor(Qt::ArrowCursor);
|
||||||
|
QGraphicsView::mouseReleaseEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
//Get the rectangle of the visible area in scene coords
|
||||||
|
QRectF visibleArea = mapToScene(rect()).boundingRect();
|
||||||
|
setCenter(visibleArea.center());
|
||||||
|
|
||||||
|
//Call the subclass resize so the scrollbars are updated correctly
|
||||||
|
QGraphicsView::resizeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::setCenter(const QPointF ¢erPoint)
|
||||||
|
{
|
||||||
|
//Get the rectangle of the visible area in scene coords
|
||||||
|
QRectF visibleArea = mapToScene(rect()).boundingRect();
|
||||||
|
|
||||||
|
//Get the scene area
|
||||||
|
QRectF sceneBounds = sceneRect();
|
||||||
|
|
||||||
|
double boundX = visibleArea.width() / 2.0;
|
||||||
|
double boundY = visibleArea.height() / 2.0;
|
||||||
|
double boundWidth = sceneBounds.width() - 2.0 * boundX;
|
||||||
|
double boundHeight = sceneBounds.height() - 2.0 * boundY;
|
||||||
|
|
||||||
|
//The max boundary that the centerPoint can be to
|
||||||
|
QRectF bounds(boundX, boundY, boundWidth, boundHeight);
|
||||||
|
|
||||||
|
if(bounds.contains(centerPoint))
|
||||||
|
{
|
||||||
|
//We are within the bounds
|
||||||
|
m_currentCenterPoint = centerPoint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//We need to clamp or use the center of the screen
|
||||||
|
if(visibleArea.contains(sceneBounds))
|
||||||
|
{
|
||||||
|
//Use the center of scene ie. we can see the whole scene
|
||||||
|
m_currentCenterPoint = sceneBounds.center();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_currentCenterPoint = centerPoint;
|
||||||
|
|
||||||
|
//We need to clamp the center. The centerPoint is too large
|
||||||
|
if (centerPoint.x() > bounds.x() + bounds.width())
|
||||||
|
m_currentCenterPoint.setX(bounds.x() + bounds.width());
|
||||||
|
else if(centerPoint.x() < bounds.x())
|
||||||
|
m_currentCenterPoint.setX(bounds.x());
|
||||||
|
|
||||||
|
if(centerPoint.y() > bounds.y() + bounds.height())
|
||||||
|
m_currentCenterPoint.setY(bounds.y() + bounds.height());
|
||||||
|
else if(centerPoint.y() < bounds.y())
|
||||||
|
m_currentCenterPoint.setY(bounds.y());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Update the scrollbars
|
||||||
|
centerOn(m_currentCenterPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF LandscapeView::getCenter() const
|
||||||
|
{
|
||||||
|
//return m_currentCenterPoint;
|
||||||
|
return mapToScene(viewport()->rect().center());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::drawForeground(QPainter *painter, const QRectF &rect)
|
||||||
|
{
|
||||||
|
QGraphicsView::drawForeground(painter, rect);
|
||||||
|
|
||||||
|
if (!m_visibleGrid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
painter->setPen(QPen(Qt::white, 0, Qt::SolidLine));
|
||||||
|
drawGrid(painter, rect);
|
||||||
|
|
||||||
|
if (!m_visibleText)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (transform().m11() > m_maxViewText)
|
||||||
|
{
|
||||||
|
painter->setPen(QPen(Qt::white, 0.5, Qt::SolidLine));
|
||||||
|
drawZoneNames(painter, rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::drawGrid(QPainter *painter, const QRectF &rect)
|
||||||
|
{
|
||||||
|
qreal left = m_cellSize * floor(rect.left() / m_cellSize);
|
||||||
|
qreal top = m_cellSize * floor(rect.top() / m_cellSize);
|
||||||
|
|
||||||
|
QVector<QLine> lines;
|
||||||
|
|
||||||
|
// Calculate vertical lines
|
||||||
|
while (left < rect.right())
|
||||||
|
{
|
||||||
|
lines.push_back(QLine(int(left), int(rect.bottom()), int(left), int(rect.top())));
|
||||||
|
left += m_cellSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate horizontal lines
|
||||||
|
while (top < rect.bottom())
|
||||||
|
{
|
||||||
|
lines.push_back(QLine(int(rect.left()), int(top), int(rect.right()), int(top)));
|
||||||
|
top += m_cellSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw lines
|
||||||
|
painter->drawLines(lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LandscapeView::drawZoneNames(QPainter *painter, const QRectF &rect)
|
||||||
|
{
|
||||||
|
int leftSide = int(floor(rect.left() / m_cellSize));
|
||||||
|
int rightSide = int(floor(rect.right() / m_cellSize));
|
||||||
|
int topSide = int(floor(rect.top() / m_cellSize));
|
||||||
|
int bottomSide = int(floor(rect.bottom() / m_cellSize));
|
||||||
|
|
||||||
|
for (int i = leftSide; i < rightSide + 1; ++i)
|
||||||
|
{
|
||||||
|
for (int j = topSide; j < bottomSide + 1; ++j)
|
||||||
|
{
|
||||||
|
QString text = QString("%1_%2%3").arg(j).arg(QChar('A' + (i / 26))).arg(QChar('A' + (i % 26)));
|
||||||
|
painter->drawText(i * m_cellSize + 5, j * m_cellSize + 15, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,84 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef LANDSCAPE_VIEW_H
|
||||||
|
#define LANDSCAPE_VIEW_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "landscape_editor_global.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QGraphicsView>
|
||||||
|
#include <QtGui/QWheelEvent>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class LandscapeView
|
||||||
|
@brief Provides graphics view for viewing zone regions.
|
||||||
|
@details Also provides zooming, panning and displaying grid
|
||||||
|
*/
|
||||||
|
class LANDSCAPE_EDITOR_EXPORT LandscapeView: public QGraphicsView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LandscapeView(QWidget *parent = 0);
|
||||||
|
virtual ~LandscapeView();
|
||||||
|
|
||||||
|
//Set the current centerpoint in the
|
||||||
|
void setCenter(const QPointF ¢erPoint);
|
||||||
|
QPointF getCenter() const;
|
||||||
|
|
||||||
|
bool isVisibleGrid() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
|
||||||
|
/// Enable/disable displaying grid.
|
||||||
|
void setVisibleGrid(bool visible);
|
||||||
|
|
||||||
|
/// Enable/disable displaying text(coord.) above each zone bricks.
|
||||||
|
void setVisibleText(bool visible);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
protected:
|
||||||
|
//Take over the interaction
|
||||||
|
virtual void wheelEvent(QWheelEvent *event);
|
||||||
|
virtual void mousePressEvent(QMouseEvent *event);
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent *event);
|
||||||
|
virtual void mouseReleaseEvent(QMouseEvent *event);
|
||||||
|
virtual void drawForeground(QPainter *painter, const QRectF &rect);
|
||||||
|
virtual void resizeEvent(QResizeEvent *event);
|
||||||
|
|
||||||
|
void drawGrid(QPainter *painter, const QRectF &rect);
|
||||||
|
void drawZoneNames(QPainter *painter, const QRectF &rect);
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_visibleGrid, m_visibleText;
|
||||||
|
qreal m_maxView, m_minView, m_maxViewText;
|
||||||
|
int m_cellSize;
|
||||||
|
|
||||||
|
//Holds the current centerpoint for the view, used for panning and zooming
|
||||||
|
QPointF m_currentCenterPoint;
|
||||||
|
|
||||||
|
//From panning the view
|
||||||
|
QPoint m_lastPanPoint;
|
||||||
|
}; /* class LandscapeView */
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // LANDSCAPE_VIEW_H
|
|
@ -0,0 +1,137 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "list_zones_model.h"
|
||||||
|
#include "builder_zone.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QtGui/QProgressDialog>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
ListZonesModel::ListZonesModel(int scaleRatio, QObject *parent)
|
||||||
|
: QAbstractListModel(parent),
|
||||||
|
m_scaleRatio(scaleRatio)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
ListZonesModel::~ListZonesModel()
|
||||||
|
{
|
||||||
|
resetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ListZonesModel::rowCount(const QModelIndex & /* parent */) const
|
||||||
|
{
|
||||||
|
return m_listNames.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ListZonesModel::columnCount(const QModelIndex & /* parent */) const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ListZonesModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
switch (role)
|
||||||
|
{
|
||||||
|
case Qt::TextAlignmentRole:
|
||||||
|
return int(Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return m_listNames.at(index.row());
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
{
|
||||||
|
QPixmap *pixmap = getPixmap(m_listNames.at(index.row()));
|
||||||
|
return qVariantFromValue(*pixmap);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ListZonesModel::headerData(int section, Qt::Orientation, int role) const
|
||||||
|
{
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesModel::setScaleRatio(int scaleRatio)
|
||||||
|
{
|
||||||
|
m_scaleRatio = scaleRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesModel::setListZones(QStringList &listZones)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_listNames.clear();
|
||||||
|
m_listNames = listZones;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesModel::resetModel()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
QStringList listNames(m_pixmapMap.keys());
|
||||||
|
Q_FOREACH(QString name, listNames)
|
||||||
|
{
|
||||||
|
QPixmap *pixmap = m_pixmapMap.value(name);
|
||||||
|
delete pixmap;
|
||||||
|
}
|
||||||
|
m_pixmapMap.clear();
|
||||||
|
m_listNames.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesModel::rebuildModel(PixmapDatabase *pixmapDatabase)
|
||||||
|
{
|
||||||
|
resetModel();
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
QStringList listNames;
|
||||||
|
listNames = pixmapDatabase->listPixmaps();
|
||||||
|
|
||||||
|
Q_FOREACH(QString name, listNames)
|
||||||
|
{
|
||||||
|
QPixmap *pixmap = pixmapDatabase->pixmap(name);
|
||||||
|
QPixmap *smallPixmap = new QPixmap(pixmap->scaled(pixmap->width() / m_scaleRatio, pixmap->height() / m_scaleRatio));
|
||||||
|
m_pixmapMap.insert(name, smallPixmap);
|
||||||
|
}
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap *ListZonesModel::getPixmap(const QString &zoneName) const
|
||||||
|
{
|
||||||
|
QPixmap *result = 0;
|
||||||
|
if (!m_pixmapMap.contains(zoneName))
|
||||||
|
nlwarning("QPixmap %s not found", zoneName.toStdString().c_str());
|
||||||
|
else
|
||||||
|
result = m_pixmapMap.value(zoneName);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,79 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef LIST_ZONES_MODEL_H
|
||||||
|
#define LIST_ZONES_MODEL_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/zone_bank.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtGui/QPixmap>
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
class PixmapDatabase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class ListZonesModel
|
||||||
|
@brief ListZonesModel is used for managed list bricks by ListZonesWidget
|
||||||
|
@details ListZonesModel contains the small images for QListView
|
||||||
|
*/
|
||||||
|
class ListZonesModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ListZonesModel(int scaleRatio = 4, QObject *parent = 0);
|
||||||
|
~ListZonesModel();
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent) const;
|
||||||
|
int columnCount(const QModelIndex &parent) const;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
|
int role) const;
|
||||||
|
|
||||||
|
/// Set size for small pixmaps
|
||||||
|
/// Value should be set before calling rebuildModel
|
||||||
|
void setScaleRatio(int scaleRatio);
|
||||||
|
|
||||||
|
/// Delete all small images and reset model
|
||||||
|
void resetModel();
|
||||||
|
|
||||||
|
/// Set current list zones which will be available in QListView
|
||||||
|
void setListZones(QStringList &listZones);
|
||||||
|
|
||||||
|
/// Build own pixmaps database(all images are scaled: width/scaleRatio, height/scaleRatio) from pixmapDatabase
|
||||||
|
void rebuildModel(PixmapDatabase *pixmapDatabase);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Get pixmap
|
||||||
|
/// @return QPixmap* if the image is in the database ; otherwise returns 0.
|
||||||
|
QPixmap *getPixmap(const QString &zoneName) const;
|
||||||
|
|
||||||
|
int m_scaleRatio;
|
||||||
|
QMap<QString, QPixmap *> m_pixmapMap;
|
||||||
|
QStringList m_listNames;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // LIST_ZONES_MODEL_H
|
|
@ -0,0 +1,308 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "list_zones_widget.h"
|
||||||
|
#include "list_zones_model.h"
|
||||||
|
#include "builder_zone.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
#include <nel/ligo/zone_bank.h>
|
||||||
|
#include <nel/ligo/zone_region.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QIcon>
|
||||||
|
#include <QtCore/QModelIndex>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
ListZonesWidget::ListZonesWidget(QWidget *parent)
|
||||||
|
: QWidget(parent),
|
||||||
|
m_rotCycle(0),
|
||||||
|
m_flipCycle(0),
|
||||||
|
m_listZonesModel(0),
|
||||||
|
m_zoneBuilder(0)
|
||||||
|
{
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
|
m_listZonesModel = new ListZonesModel(4, this);
|
||||||
|
m_ui.listView->setModel(m_listZonesModel);
|
||||||
|
|
||||||
|
m_ui.addFilterButton_1->setChecked(false);
|
||||||
|
m_ui.addFilterButton_2->setChecked(false);
|
||||||
|
m_ui.addFilterButton_3->setChecked(false);
|
||||||
|
|
||||||
|
connect(m_ui.categoryTypeComboBox_1, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_1(QString)));
|
||||||
|
connect(m_ui.categoryTypeComboBox_2, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_2(QString)));
|
||||||
|
connect(m_ui.categoryTypeComboBox_3, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_3(QString)));
|
||||||
|
connect(m_ui.categoryTypeComboBox_4, SIGNAL(currentIndexChanged(QString)), this, SLOT(updateFilters_4(QString)));
|
||||||
|
connect(m_ui.categoryValueComboBox_1, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
|
||||||
|
connect(m_ui.categoryValueComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
|
||||||
|
connect(m_ui.categoryValueComboBox_3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
|
||||||
|
connect(m_ui.categoryValueComboBox_4, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
|
||||||
|
connect(m_ui.logicComboBox_2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
|
||||||
|
connect(m_ui.logicComboBox_3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
|
||||||
|
connect(m_ui.logicComboBox_4, SIGNAL(currentIndexChanged(int)), this, SLOT(updateListZones()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ListZonesWidget::~ListZonesWidget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesWidget::updateUi()
|
||||||
|
{
|
||||||
|
if (m_zoneBuilder == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
disableSignals(true);
|
||||||
|
std::vector<std::string> listCategoryType;
|
||||||
|
m_zoneBuilder->getZoneBank().getCategoriesType(listCategoryType);
|
||||||
|
|
||||||
|
QStringList listCategories;
|
||||||
|
|
||||||
|
listCategories << STRING_UNUSED;
|
||||||
|
for (size_t i = 0; i < listCategoryType.size(); ++i)
|
||||||
|
listCategories << QString(listCategoryType[i].c_str());
|
||||||
|
|
||||||
|
m_ui.categoryTypeComboBox_1->clear();
|
||||||
|
m_ui.categoryTypeComboBox_2->clear();
|
||||||
|
m_ui.categoryTypeComboBox_3->clear();
|
||||||
|
m_ui.categoryTypeComboBox_4->clear();
|
||||||
|
m_ui.categoryValueComboBox_1->clear();
|
||||||
|
m_ui.categoryValueComboBox_2->clear();
|
||||||
|
m_ui.categoryValueComboBox_3->clear();
|
||||||
|
m_ui.categoryValueComboBox_4->clear();
|
||||||
|
|
||||||
|
m_ui.categoryTypeComboBox_1->addItems(listCategories);
|
||||||
|
m_ui.categoryTypeComboBox_2->addItems(listCategories);
|
||||||
|
m_ui.categoryTypeComboBox_3->addItems(listCategories);
|
||||||
|
m_ui.categoryTypeComboBox_4->addItems(listCategories);
|
||||||
|
|
||||||
|
disableSignals(false);
|
||||||
|
|
||||||
|
m_listZonesModel->rebuildModel(m_zoneBuilder->pixmapDatabase());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ListZonesWidget::currentZoneName()
|
||||||
|
{
|
||||||
|
QString zoneName = "";
|
||||||
|
QModelIndex index = m_ui.listView->currentIndex();
|
||||||
|
if (index.isValid())
|
||||||
|
zoneName = index.data().toString();
|
||||||
|
if (m_ui.zoneSelectComboBox->currentIndex() == 1)
|
||||||
|
{
|
||||||
|
// Random value
|
||||||
|
if (m_listSelection.size() > 0)
|
||||||
|
{
|
||||||
|
uint32 randZone = uint32(NLMISC::frand(m_listSelection.size()));
|
||||||
|
NLMISC::clamp(randZone, (uint32)0, uint32(m_listSelection.size() - 1));
|
||||||
|
zoneName = m_listSelection[randZone];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_ui.zoneSelectComboBox->currentIndex() == 2)
|
||||||
|
{
|
||||||
|
// Full cycle
|
||||||
|
if (m_listSelection.size() > 0)
|
||||||
|
{
|
||||||
|
zoneName = m_listSelection[m_zoneNameCycle];
|
||||||
|
m_zoneNameCycle++;
|
||||||
|
m_zoneNameCycle = m_zoneNameCycle % m_listSelection.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return zoneName;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ListZonesWidget::currentRot()
|
||||||
|
{
|
||||||
|
int rot = m_ui.rotComboBox->currentIndex();
|
||||||
|
if (rot == 4)
|
||||||
|
{
|
||||||
|
// Random value
|
||||||
|
uint32 randRot = uint32(NLMISC::frand(4.0));
|
||||||
|
NLMISC::clamp(randRot, (uint32)0, (uint32)3);
|
||||||
|
rot = int(randRot);
|
||||||
|
}
|
||||||
|
else if (rot == 5)
|
||||||
|
{
|
||||||
|
// Full cycle
|
||||||
|
rot = m_rotCycle;
|
||||||
|
m_rotCycle++;
|
||||||
|
m_rotCycle = m_rotCycle % 4;
|
||||||
|
}
|
||||||
|
return rot;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ListZonesWidget::currentFlip()
|
||||||
|
{
|
||||||
|
int flip = m_ui.flipComboBox->currentIndex();
|
||||||
|
if (flip == 2)
|
||||||
|
{
|
||||||
|
// Random value
|
||||||
|
uint32 randFlip = uint32(NLMISC::frand(2.0));
|
||||||
|
NLMISC::clamp (randFlip, (uint32)0, (uint32)1);
|
||||||
|
flip = int(randFlip);
|
||||||
|
}
|
||||||
|
else if (flip == 3)
|
||||||
|
{
|
||||||
|
// Full cycle
|
||||||
|
flip = m_flipCycle;
|
||||||
|
m_flipCycle++;
|
||||||
|
m_flipCycle = m_flipCycle % 2;
|
||||||
|
}
|
||||||
|
return flip;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListZonesWidget::isNotPropogate() const
|
||||||
|
{
|
||||||
|
return m_ui.propogateCheckBox->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListZonesWidget::isForce() const
|
||||||
|
{
|
||||||
|
return m_ui.forceCheckBox->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesWidget::setZoneBuilder(ZoneBuilder *zoneBuilder)
|
||||||
|
{
|
||||||
|
m_zoneBuilder = zoneBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesWidget::updateFilters_1(const QString &value)
|
||||||
|
{
|
||||||
|
disableSignals(true);
|
||||||
|
std::vector<std::string> allCategoryValues;
|
||||||
|
m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
|
||||||
|
m_ui.categoryValueComboBox_1->clear();
|
||||||
|
for(size_t i = 0; i < allCategoryValues.size(); ++i)
|
||||||
|
m_ui.categoryValueComboBox_1->addItem(QString(allCategoryValues[i].c_str()));
|
||||||
|
|
||||||
|
disableSignals(false);
|
||||||
|
updateListZones();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesWidget::updateFilters_2(const QString &value)
|
||||||
|
{
|
||||||
|
disableSignals(true);
|
||||||
|
std::vector<std::string> allCategoryValues;
|
||||||
|
m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
|
||||||
|
|
||||||
|
m_ui.categoryValueComboBox_2->clear();
|
||||||
|
for(size_t i = 0; i < allCategoryValues.size(); ++i)
|
||||||
|
m_ui.categoryValueComboBox_2->addItem(QString(allCategoryValues[i].c_str()));
|
||||||
|
|
||||||
|
disableSignals(false);
|
||||||
|
updateListZones();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesWidget::updateFilters_3(const QString &value)
|
||||||
|
{
|
||||||
|
disableSignals(true);
|
||||||
|
std::vector<std::string> allCategoryValues;
|
||||||
|
m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
|
||||||
|
|
||||||
|
m_ui.categoryValueComboBox_3->clear();
|
||||||
|
for(size_t i = 0; i < allCategoryValues.size(); ++i)
|
||||||
|
m_ui.categoryValueComboBox_3->addItem(QString(allCategoryValues[i].c_str()));
|
||||||
|
|
||||||
|
disableSignals(false);
|
||||||
|
updateListZones();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesWidget::updateFilters_4(const QString &value)
|
||||||
|
{
|
||||||
|
disableSignals(true);
|
||||||
|
std::vector<std::string> allCategoryValues;
|
||||||
|
m_zoneBuilder->getZoneBank().getCategoryValues(value.toStdString(), allCategoryValues);
|
||||||
|
|
||||||
|
m_ui.categoryValueComboBox_4->clear();
|
||||||
|
for(size_t i = 0; i < allCategoryValues.size(); ++i)
|
||||||
|
m_ui.categoryValueComboBox_4->addItem(QString(allCategoryValues[i].c_str()));
|
||||||
|
|
||||||
|
disableSignals(false);
|
||||||
|
updateListZones();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesWidget::updateListZones()
|
||||||
|
{
|
||||||
|
// Execute the filter
|
||||||
|
NLLIGO::CZoneBank &zoneBank = m_zoneBuilder->getZoneBank();
|
||||||
|
zoneBank.resetSelection ();
|
||||||
|
|
||||||
|
if(m_ui.categoryTypeComboBox_1->currentIndex() > 0 )
|
||||||
|
zoneBank.addOrSwitch (m_ui.categoryTypeComboBox_1->currentText().toStdString()
|
||||||
|
, m_ui.categoryValueComboBox_1->currentText().toStdString());
|
||||||
|
|
||||||
|
if(m_ui.categoryTypeComboBox_2->currentIndex() > 0 )
|
||||||
|
{
|
||||||
|
if (m_ui.logicComboBox_2->currentIndex() == 0) // AND switch wanted
|
||||||
|
zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_2->currentText().toStdString()
|
||||||
|
,m_ui.categoryValueComboBox_2->currentText().toStdString());
|
||||||
|
else // OR switch wanted
|
||||||
|
zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_2->currentText().toStdString()
|
||||||
|
,m_ui.categoryValueComboBox_2->currentText().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_ui.categoryTypeComboBox_3->currentIndex() > 0 )
|
||||||
|
{
|
||||||
|
if (m_ui.logicComboBox_3->currentIndex() == 0) // AND switch wanted
|
||||||
|
zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_3->currentText().toStdString()
|
||||||
|
,m_ui.categoryValueComboBox_3->currentText().toStdString());
|
||||||
|
else // OR switch wanted
|
||||||
|
zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_3->currentText().toStdString()
|
||||||
|
,m_ui.categoryValueComboBox_3->currentText().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_ui.categoryTypeComboBox_4->currentIndex() > 0 )
|
||||||
|
{
|
||||||
|
if (m_ui.logicComboBox_4->currentIndex() == 0) // AND switch wanted
|
||||||
|
zoneBank.addAndSwitch(m_ui.categoryTypeComboBox_4->currentText().toStdString()
|
||||||
|
,m_ui.categoryValueComboBox_4->currentText().toStdString());
|
||||||
|
else // OR switch wanted
|
||||||
|
zoneBank.addOrSwitch(m_ui.categoryTypeComboBox_4->currentText().toStdString()
|
||||||
|
,m_ui.categoryValueComboBox_4->currentText().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<NLLIGO::CZoneBankElement *> currentSelection;
|
||||||
|
zoneBank.getSelection (currentSelection);
|
||||||
|
|
||||||
|
m_listSelection.clear();
|
||||||
|
m_zoneNameCycle = 0;
|
||||||
|
for (size_t i = 0; i < currentSelection.size(); ++i)
|
||||||
|
m_listSelection << currentSelection[i]->getName().c_str();
|
||||||
|
|
||||||
|
m_listZonesModel->setListZones(m_listSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListZonesWidget::disableSignals(bool block)
|
||||||
|
{
|
||||||
|
m_ui.categoryTypeComboBox_1->blockSignals(block);
|
||||||
|
m_ui.categoryTypeComboBox_2->blockSignals(block);
|
||||||
|
m_ui.categoryTypeComboBox_3->blockSignals(block);
|
||||||
|
m_ui.categoryTypeComboBox_4->blockSignals(block);
|
||||||
|
m_ui.categoryValueComboBox_1->blockSignals(block);
|
||||||
|
m_ui.categoryValueComboBox_2->blockSignals(block);
|
||||||
|
m_ui.categoryValueComboBox_3->blockSignals(block);
|
||||||
|
m_ui.categoryValueComboBox_4->blockSignals(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,83 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef LIST_ZONES_WIDGET_H
|
||||||
|
#define LIST_ZONES_WIDGET_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "ui_list_zones_widget.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
class ListZonesModel;
|
||||||
|
class ZoneBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class ZoneListWidget
|
||||||
|
@brief ZoneListWidget displays list available zones in accordance with the filter settings
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class ListZonesWidget: public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ListZonesWidget(QWidget *parent = 0);
|
||||||
|
~ListZonesWidget();
|
||||||
|
|
||||||
|
void updateUi();
|
||||||
|
|
||||||
|
/// Set zone builder, call this method before using this class
|
||||||
|
void setZoneBuilder(ZoneBuilder *zoneBuilder);
|
||||||
|
|
||||||
|
/// Get current zone name which user selected from list.
|
||||||
|
QString currentZoneName();
|
||||||
|
|
||||||
|
/// Get current rotation value which user selected (Rot 0-0deg, 1-90deg, 2-180deg, 3-270deg).
|
||||||
|
int currentRot();
|
||||||
|
|
||||||
|
/// Get current flip value which user selected (Flip 0-false, 1-true).
|
||||||
|
int currentFlip();
|
||||||
|
|
||||||
|
bool isNotPropogate() const;
|
||||||
|
bool isForce() const;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void updateFilters_1(const QString &value);
|
||||||
|
void updateFilters_2(const QString &value);
|
||||||
|
void updateFilters_3(const QString &value);
|
||||||
|
void updateFilters_4(const QString &value);
|
||||||
|
void updateListZones();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void disableSignals(bool block);
|
||||||
|
|
||||||
|
int m_rotCycle, m_flipCycle;
|
||||||
|
int m_zoneNameCycle;
|
||||||
|
QStringList m_listSelection;
|
||||||
|
|
||||||
|
ListZonesModel *m_listZonesModel;
|
||||||
|
ZoneBuilder *m_zoneBuilder;
|
||||||
|
Ui::ListZonesWidget m_ui;
|
||||||
|
}; /* ZoneListWidget */
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // LIST_ZONES_WIDGET_H
|
|
@ -0,0 +1,493 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ListZonesWidget</class>
|
||||||
|
<widget class="QWidget" name="ListZonesWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>359</width>
|
||||||
|
<height>579</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<property name="margin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Filter</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<property name="margin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="categoryTypeComboBox_1"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QComboBox" name="categoryValueComboBox_1"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QComboBox" name="zoneSelectComboBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Select</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Random</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fyll cycle</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="categoryTypeComboBox_2">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QComboBox" name="categoryValueComboBox_2">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3">
|
||||||
|
<widget class="QComboBox" name="logicComboBox_2">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>And</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Or</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="categoryTypeComboBox_3">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QComboBox" name="categoryValueComboBox_3">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<widget class="QComboBox" name="logicComboBox_3">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>And</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Or</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QComboBox" name="categoryTypeComboBox_4">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QComboBox" name="categoryValueComboBox_4">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="3">
|
||||||
|
<widget class="QComboBox" name="logicComboBox_4">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>And</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Or</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QToolButton" name="addFilterButton_1">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../core/core.qrc">
|
||||||
|
<normaloff>:/core/icons/ic_nel_add_item.png</normaloff>
|
||||||
|
<normalon>:/core/icons/ic_nel_delete_item.png</normalon>:/core/icons/ic_nel_add_item.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QToolButton" name="addFilterButton_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../core/core.qrc">
|
||||||
|
<normaloff>:/core/icons/ic_nel_add_item.png</normaloff>
|
||||||
|
<normalon>:/core/icons/ic_nel_delete_item.png</normalon>:/core/icons/ic_nel_add_item.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QToolButton" name="addFilterButton_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../core/core.qrc">
|
||||||
|
<normaloff>:/core/icons/ic_nel_add_item.png</normaloff>
|
||||||
|
<normalon>:/core/icons/ic_nel_delete_item.png</normalon>:/core/icons/ic_nel_add_item.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Placement</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="margin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QComboBox" name="rotComboBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>0°</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>90°</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>180°</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>270°</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Random</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Full cycle</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="flipComboBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>NoFlip</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Flip</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Random</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Fyll cycle</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QCheckBox" name="forceCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Force</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3">
|
||||||
|
<widget class="QCheckBox" name="propogateCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Not propogate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QListView" name="listView">
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollMode">
|
||||||
|
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../core/core.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_1</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>categoryTypeComboBox_2</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>20</x>
|
||||||
|
<y>36</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>81</x>
|
||||||
|
<y>53</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_1</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>categoryValueComboBox_2</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>24</x>
|
||||||
|
<y>32</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>181</x>
|
||||||
|
<y>50</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_1</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>logicComboBox_2</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>20</x>
|
||||||
|
<y>31</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>301</x>
|
||||||
|
<y>55</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_2</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>categoryTypeComboBox_3</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>27</x>
|
||||||
|
<y>62</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>57</x>
|
||||||
|
<y>75</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_2</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>categoryValueComboBox_3</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>23</x>
|
||||||
|
<y>58</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>156</x>
|
||||||
|
<y>76</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_2</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>logicComboBox_3</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>23</x>
|
||||||
|
<y>53</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>255</x>
|
||||||
|
<y>77</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_3</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>categoryTypeComboBox_4</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>32</x>
|
||||||
|
<y>94</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>44</x>
|
||||||
|
<y>104</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_3</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>categoryValueComboBox_4</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>32</x>
|
||||||
|
<y>94</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>207</x>
|
||||||
|
<y>103</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_3</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>logicComboBox_4</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>21</x>
|
||||||
|
<y>81</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>278</x>
|
||||||
|
<y>104</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_2</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>addFilterButton_3</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>15</x>
|
||||||
|
<y>59</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>16</x>
|
||||||
|
<y>80</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>addFilterButton_1</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>addFilterButton_2</receiver>
|
||||||
|
<slot>setVisible(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>13</x>
|
||||||
|
<y>35</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>17</x>
|
||||||
|
<y>60</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<plugin-spec>
|
||||||
|
<library-name>ovqt_plugin_landscape_editor</library-name>
|
||||||
|
<name>LandscapeEditor</name>
|
||||||
|
<version>0.8</version>
|
||||||
|
<vendor>GSoC2011_dnk-88</vendor>
|
||||||
|
<description>Landscape editor ovqt plugin.</description>
|
||||||
|
<dependencies>
|
||||||
|
<dependency plugin-name="Core" version="0.8"/>
|
||||||
|
</dependencies>
|
||||||
|
</plugin-spec>
|
|
@ -0,0 +1,154 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "pixmap_database.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
#include <nel/ligo/zone_region.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
#include <QtGui/QPainter>
|
||||||
|
#include <QtGui/QMessageBox>
|
||||||
|
#include <QtGui/QApplication>
|
||||||
|
#include <QtGui/QProgressDialog>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
PixmapDatabase::PixmapDatabase(int textureSize)
|
||||||
|
: m_textureSize(textureSize),
|
||||||
|
m_errorPixmap(0)
|
||||||
|
{
|
||||||
|
// Create pixmap for case if pixmap and LIGO files not found
|
||||||
|
m_errorPixmap = new QPixmap(QSize(m_textureSize, m_textureSize));
|
||||||
|
QPainter painter(m_errorPixmap);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
painter.fillRect(m_errorPixmap->rect(), QBrush(QColor(Qt::black)));
|
||||||
|
painter.setFont(QFont("Helvetica [Cronyx]", 14));
|
||||||
|
painter.setPen(QPen(Qt::red, 2, Qt::SolidLine));
|
||||||
|
painter.drawText(m_errorPixmap->rect(), Qt::AlignCenter | Qt::TextWordWrap,
|
||||||
|
QObject::tr("Pixmap and LIGO files not found."));
|
||||||
|
painter.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
PixmapDatabase::~PixmapDatabase()
|
||||||
|
{
|
||||||
|
delete m_errorPixmap;
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PixmapDatabase::loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank, bool displayProgress)
|
||||||
|
{
|
||||||
|
QProgressDialog *progressDialog;
|
||||||
|
std::vector<std::string> listNames;
|
||||||
|
zoneBank.getCategoryValues ("zone", listNames);
|
||||||
|
if (displayProgress)
|
||||||
|
{
|
||||||
|
progressDialog = new QProgressDialog(QObject::tr("Loading ligo zones."), QObject::tr("Cancel"), 0, listNames.size());
|
||||||
|
progressDialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint i = 0; i < listNames.size(); ++i)
|
||||||
|
{
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
if (displayProgress)
|
||||||
|
progressDialog->setValue(i);
|
||||||
|
|
||||||
|
NLLIGO::CZoneBankElement *zoneBankItem = zoneBank.getElementByZoneName (listNames[i]);
|
||||||
|
|
||||||
|
// Read the texture file
|
||||||
|
QString zonePixmapName(listNames[i].c_str());
|
||||||
|
uint8 sizeX = zoneBankItem->getSizeX();
|
||||||
|
uint8 sizeY = zoneBankItem->getSizeY();
|
||||||
|
|
||||||
|
QPixmap *pixmap = new QPixmap(zonePath + zonePixmapName + ".png");
|
||||||
|
if (pixmap->isNull())
|
||||||
|
{
|
||||||
|
// Generate filled pixmap if could not load pixmap
|
||||||
|
QPixmap *emptyPixmap = new QPixmap(QSize(sizeX * m_textureSize, sizeY * m_textureSize));
|
||||||
|
QPainter painter(emptyPixmap);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
painter.fillRect(emptyPixmap->rect(), QBrush(QColor(Qt::black)));
|
||||||
|
painter.setFont(QFont("Helvetica [Cronyx]", 18));
|
||||||
|
painter.setPen(QPen(Qt::red, 2, Qt::SolidLine));
|
||||||
|
painter.drawText(emptyPixmap->rect(), Qt::AlignCenter, QObject::tr("Pixmap not found"));
|
||||||
|
painter.end();
|
||||||
|
delete pixmap;
|
||||||
|
m_pixmapMap.insert(zonePixmapName, emptyPixmap);
|
||||||
|
nlwarning(QString("not found " + zonePath + zonePixmapName + ".png").toStdString().c_str());
|
||||||
|
}
|
||||||
|
// All pixmaps must be have same size
|
||||||
|
else if (pixmap->width() != sizeX * m_textureSize)
|
||||||
|
{
|
||||||
|
QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(sizeX * m_textureSize, sizeY * m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
delete pixmap;
|
||||||
|
m_pixmapMap.insert(zonePixmapName, scaledPixmap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_pixmapMap.insert(zonePixmapName, pixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap *pixmap = new QPixmap(zonePath + "_unused_.png");
|
||||||
|
QPixmap *scaledPixmap = new QPixmap(pixmap->scaled(m_textureSize, m_textureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
delete pixmap;
|
||||||
|
m_pixmapMap.insert(QString(STRING_UNUSED), scaledPixmap);
|
||||||
|
|
||||||
|
if (displayProgress)
|
||||||
|
delete progressDialog;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PixmapDatabase::reset()
|
||||||
|
{
|
||||||
|
QStringList listNames(m_pixmapMap.keys());
|
||||||
|
Q_FOREACH(QString name, listNames)
|
||||||
|
{
|
||||||
|
QPixmap *pixmap = m_pixmapMap.value(name);
|
||||||
|
delete pixmap;
|
||||||
|
}
|
||||||
|
m_pixmapMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList PixmapDatabase::listPixmaps() const
|
||||||
|
{
|
||||||
|
return m_pixmapMap.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap *PixmapDatabase::pixmap(const QString &zoneName) const
|
||||||
|
{
|
||||||
|
QPixmap *result = m_errorPixmap;
|
||||||
|
if (!m_pixmapMap.contains(zoneName))
|
||||||
|
nlwarning("QPixmap %s not found", zoneName.toStdString().c_str());
|
||||||
|
else
|
||||||
|
result = m_pixmapMap.value(zoneName);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PixmapDatabase::textureSize() const
|
||||||
|
{
|
||||||
|
return m_textureSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PIXMAP_DATABASE_H
|
||||||
|
#define PIXMAP_DATABASE_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "landscape_editor_global.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/zone_bank.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtGui/QPixmap>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class PixmapDatabase
|
||||||
|
@brief PixmapDatabase contains the image database
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class LANDSCAPE_EDITOR_EXPORT PixmapDatabase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PixmapDatabase(int textureSize = 256);
|
||||||
|
~PixmapDatabase();
|
||||||
|
|
||||||
|
/// Load all images(png) from zonePath, list images gets from zoneBank
|
||||||
|
bool loadPixmaps(const QString &zonePath, NLLIGO::CZoneBank &zoneBank, bool displayProgress = false);
|
||||||
|
|
||||||
|
/// Unload all images
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
/// Get list names all loaded pixmaps
|
||||||
|
QStringList listPixmaps() const;
|
||||||
|
|
||||||
|
/// Get original pixmap
|
||||||
|
/// @return QPixmap* if the image is in the database ;
|
||||||
|
/// otherwise returns pixmap which contains error message.
|
||||||
|
QPixmap *pixmap(const QString &zoneName) const;
|
||||||
|
|
||||||
|
int textureSize() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int m_textureSize;
|
||||||
|
QPixmap *m_errorPixmap;
|
||||||
|
QMap<QString, QPixmap *> m_pixmapMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // PIXMAP_DATABASE_H
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "project_settings_dialog.h"
|
||||||
|
#include "landscape_editor_constants.h"
|
||||||
|
|
||||||
|
#include "../core/icore.h"
|
||||||
|
#include "../core/core_constants.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QSettings>
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
ProjectSettingsDialog::ProjectSettingsDialog(const QString &dataPath, QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
{
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
m_ui.pathLineEdit->setText(dataPath);
|
||||||
|
setFixedHeight(sizeHint().height());
|
||||||
|
connect(m_ui.selectPathButton, SIGNAL(clicked()), this, SLOT(selectPath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectSettingsDialog::~ProjectSettingsDialog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ProjectSettingsDialog::dataPath() const
|
||||||
|
{
|
||||||
|
return m_ui.pathLineEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectSettingsDialog::selectPath()
|
||||||
|
{
|
||||||
|
QString dataPath = QFileDialog::getExistingDirectory(this, tr("Select data path"), m_ui.pathLineEdit->text());
|
||||||
|
if (!dataPath.isEmpty())
|
||||||
|
m_ui.pathLineEdit->setText(dataPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PROJECT_SETTINGS_DIALOG_H
|
||||||
|
#define PROJECT_SETTINGS_DIALOG_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "ui_project_settings_dialog.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
class ProjectSettingsDialog: public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProjectSettingsDialog(const QString &dataPath, QWidget *parent = 0);
|
||||||
|
~ProjectSettingsDialog();
|
||||||
|
|
||||||
|
QString dataPath() const;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void selectPath();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Ui::ProjectSettingsDialog m_ui;
|
||||||
|
}; /* class ProjectSettingsDialog */
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // PROJECT_SETTINGS_DIALOG_H
|
|
@ -0,0 +1,90 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ProjectSettingsDialog</class>
|
||||||
|
<widget class="QDialog" name="ProjectSettingsDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>419</width>
|
||||||
|
<height>67</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Project settings</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Data directory:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>pathLineEdit</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="pathLineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QToolButton" name="selectPathButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="3">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="landscape_editor.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ProjectSettingsDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>257</x>
|
||||||
|
<y>83</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>ProjectSettingsDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>325</x>
|
||||||
|
<y>83</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -0,0 +1,228 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>SnapshotDialog</class>
|
||||||
|
<widget class="QDialog" name="SnapshotDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>230</width>
|
||||||
|
<height>187</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Snapshot</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_snapshot.png</normaloff>:/icons/ic_snapshot.png</iconset>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="originalSizeRadioButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Original size</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="resSpinBox">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>1024</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>128</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QRadioButton" name="customSizeRadioButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Custom size</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="widthSpinBox">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99999</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>512</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Height:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>heightSpinBox</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="heightSpinBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99999</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>512</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Width:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>widthSpinBox</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="QCheckBox" name="keepRatioCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Keep bitmap ratio</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>originalSizeRadioButton</tabstop>
|
||||||
|
<tabstop>customSizeRadioButton</tabstop>
|
||||||
|
<tabstop>widthSpinBox</tabstop>
|
||||||
|
<tabstop>heightSpinBox</tabstop>
|
||||||
|
<tabstop>keepRatioCheckBox</tabstop>
|
||||||
|
<tabstop>buttonBox</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources>
|
||||||
|
<include location="landscape_editor.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>SnapshotDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>227</x>
|
||||||
|
<y>164</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>158</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>SnapshotDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>276</x>
|
||||||
|
<y>170</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>285</x>
|
||||||
|
<y>158</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>customSizeRadioButton</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>groupBox</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>59</x>
|
||||||
|
<y>39</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>78</x>
|
||||||
|
<y>62</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>keepRatioCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>heightSpinBox</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>84</x>
|
||||||
|
<y>122</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>178</x>
|
||||||
|
<y>106</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>keepRatioCheckBox</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>label_2</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>55</x>
|
||||||
|
<y>129</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>48</x>
|
||||||
|
<y>103</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "snapshot_dialog.h"
|
||||||
|
#include "landscape_editor_constants.h"
|
||||||
|
|
||||||
|
#include "../core/icore.h"
|
||||||
|
#include "../core/core_constants.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QSettings>
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
SnapshotDialog::SnapshotDialog(QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
{
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
setFixedHeight(sizeHint().height());
|
||||||
|
}
|
||||||
|
|
||||||
|
SnapshotDialog::~SnapshotDialog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SnapshotDialog::isCustomSize() const
|
||||||
|
{
|
||||||
|
return m_ui.customSizeRadioButton->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SnapshotDialog::isKeepRatio() const
|
||||||
|
{
|
||||||
|
return m_ui.keepRatioCheckBox->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SnapshotDialog::resolutionZone() const
|
||||||
|
{
|
||||||
|
return m_ui.resSpinBox->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SnapshotDialog::widthSnapshot() const
|
||||||
|
{
|
||||||
|
return m_ui.widthSpinBox->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SnapshotDialog::heightSnapshot() const
|
||||||
|
{
|
||||||
|
return m_ui.heightSpinBox->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef SNAPSHOT_DIALOG_H
|
||||||
|
#define SNAPSHOT_DIALOG_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "ui_shapshot_dialog.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
class SnapshotDialog: public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SnapshotDialog(QWidget *parent = 0);
|
||||||
|
~SnapshotDialog();
|
||||||
|
|
||||||
|
bool isCustomSize() const;
|
||||||
|
bool isKeepRatio() const;
|
||||||
|
int resolutionZone() const;
|
||||||
|
int widthSnapshot() const;
|
||||||
|
int heightSnapshot() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Ui::SnapshotDialog m_ui;
|
||||||
|
}; /* class SnapshotDialog */
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // SNAPSHOT_DIALOG_H
|
|
@ -0,0 +1,181 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "zone_region_editor.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
#include <nel/misc/file.h>
|
||||||
|
#include <nel/misc/i_xml.h>
|
||||||
|
#include <nel/misc/o_xml.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QMessageBox>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
ZoneRegionObject::ZoneRegionObject()
|
||||||
|
{
|
||||||
|
m_fileName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneRegionObject::~ZoneRegionObject()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneRegionObject::load(const std::string &fileName)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Open it
|
||||||
|
NLMISC::CIFile fileIn;
|
||||||
|
if (fileIn.open(fileName))
|
||||||
|
{
|
||||||
|
NLMISC::CIXml xml(true);
|
||||||
|
xml.init(fileIn);
|
||||||
|
m_zoneRegion.serial(xml);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nlwarning("Can't open file %s for reading", fileName.c_str());
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NLMISC::Exception &e)
|
||||||
|
{
|
||||||
|
nlwarning("Error reading file %s : %s", fileName.c_str(), e.what ());
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
if (result)
|
||||||
|
m_fileName = fileName;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneRegionObject::save()
|
||||||
|
{
|
||||||
|
if (m_fileName.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool result = true;
|
||||||
|
// Save the landscape
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
// Open file for writing
|
||||||
|
NLMISC::COFile fileOut;
|
||||||
|
if (fileOut.open(m_fileName, false, false, true))
|
||||||
|
{
|
||||||
|
// Be careful with the flushing of the COXml object
|
||||||
|
{
|
||||||
|
NLMISC::COXml xmlOut;
|
||||||
|
xmlOut.init(&fileOut);
|
||||||
|
m_zoneRegion.serial(xmlOut);
|
||||||
|
// Done
|
||||||
|
m_modified = false;
|
||||||
|
}
|
||||||
|
fileOut.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nlwarning("Can't open file %s for writing.", m_fileName.c_str());
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NLMISC::Exception &e)
|
||||||
|
{
|
||||||
|
nlwarning("Error writing file %s : %s", m_fileName.c_str(), e.what());
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ZoneRegionObject::fileName() const
|
||||||
|
{
|
||||||
|
return m_fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneRegionObject::setFileName(const std::string &fileName)
|
||||||
|
{
|
||||||
|
m_fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneRegionObject::ligoData(LigoData &data, const sint32 x, const sint32 y)
|
||||||
|
{
|
||||||
|
data.posX = m_zoneRegion.getPosX(x, y);
|
||||||
|
data.posY = m_zoneRegion.getPosY(x, y);
|
||||||
|
data.zoneName = m_zoneRegion.getName(x, y);
|
||||||
|
data.rot = m_zoneRegion.getRot(x, y);
|
||||||
|
data.flip = m_zoneRegion.getFlip(x, y);
|
||||||
|
data.sharingMatNames[0] = m_zoneRegion.getSharingMatNames(x, y, 0);
|
||||||
|
data.sharingMatNames[1] = m_zoneRegion.getSharingMatNames(x, y, 1);
|
||||||
|
data.sharingMatNames[2] = m_zoneRegion.getSharingMatNames(x, y, 2);
|
||||||
|
data.sharingMatNames[3] = m_zoneRegion.getSharingMatNames(x, y, 3);
|
||||||
|
data.sharingCutEdges[0] = m_zoneRegion.getSharingCutEdges(x, y, 0);
|
||||||
|
data.sharingCutEdges[1] = m_zoneRegion.getSharingCutEdges(x, y, 1);
|
||||||
|
data.sharingCutEdges[2] = m_zoneRegion.getSharingCutEdges(x, y, 2);
|
||||||
|
data.sharingCutEdges[3] = m_zoneRegion.getSharingCutEdges(x, y, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneRegionObject::setLigoData(const LigoData &data, const sint32 x, const sint32 y)
|
||||||
|
{
|
||||||
|
m_zoneRegion.setPosX(x, y, data.posX);
|
||||||
|
m_zoneRegion.setPosY(x, y, data.posY);
|
||||||
|
m_zoneRegion.setName(x, y, data.zoneName);
|
||||||
|
m_zoneRegion.setRot(x, y, data.rot);
|
||||||
|
m_zoneRegion.setFlip(x, y, data.flip);
|
||||||
|
m_zoneRegion.setSharingMatNames(x, y, 0, data.sharingMatNames[0]);
|
||||||
|
m_zoneRegion.setSharingMatNames(x, y, 1, data.sharingMatNames[1]);
|
||||||
|
m_zoneRegion.setSharingMatNames(x, y, 2, data.sharingMatNames[2]);
|
||||||
|
m_zoneRegion.setSharingMatNames(x, y, 3, data.sharingMatNames[3]);
|
||||||
|
m_zoneRegion.setSharingCutEdges(x, y, 0, data.sharingCutEdges[0]);
|
||||||
|
m_zoneRegion.setSharingCutEdges(x, y, 1, data.sharingCutEdges[1]);
|
||||||
|
m_zoneRegion.setSharingCutEdges(x, y, 2, data.sharingCutEdges[2]);
|
||||||
|
m_zoneRegion.setSharingCutEdges(x, y, 3, data.sharingCutEdges[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
NLLIGO::CZoneRegion &ZoneRegionObject::ligoZoneRegion()
|
||||||
|
{
|
||||||
|
return m_zoneRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneRegionObject::setLigoZoneRegion(const NLLIGO::CZoneRegion &zoneRegion)
|
||||||
|
{
|
||||||
|
m_zoneRegion = zoneRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneRegionObject::checkPos(const sint32 x, const sint32 y)
|
||||||
|
{
|
||||||
|
return ((x >= m_zoneRegion.getMinX()) &&
|
||||||
|
(x <= m_zoneRegion.getMaxX()) &&
|
||||||
|
(y >= m_zoneRegion.getMinY()) &&
|
||||||
|
(y <= m_zoneRegion.getMaxY()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneRegionObject::isModified() const
|
||||||
|
{
|
||||||
|
return m_modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneRegionObject::setModified(bool modified)
|
||||||
|
{
|
||||||
|
m_modified = modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,133 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef LANDSCAPE_EDITOR_H
|
||||||
|
#define LANDSCAPE_EDITOR_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "landscape_editor_global.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/zone_bank.h>
|
||||||
|
#include <nel/ligo/zone_region.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
// Data
|
||||||
|
struct LigoData
|
||||||
|
{
|
||||||
|
uint8 posX;
|
||||||
|
uint8 posY;
|
||||||
|
uint8 rot;
|
||||||
|
uint8 flip;
|
||||||
|
std::string zoneName;
|
||||||
|
std::string sharingMatNames[4];
|
||||||
|
uint8 sharingCutEdges[4];
|
||||||
|
|
||||||
|
LigoData()
|
||||||
|
{
|
||||||
|
posX = 0;
|
||||||
|
posY = 0;
|
||||||
|
zoneName = "";
|
||||||
|
rot = 0;
|
||||||
|
flip = 0;
|
||||||
|
sharingMatNames[0] = "";
|
||||||
|
sharingMatNames[1] = "";
|
||||||
|
sharingMatNames[2] = "";
|
||||||
|
sharingMatNames[3] = "";
|
||||||
|
sharingCutEdges[0] = 0;
|
||||||
|
sharingCutEdges[1] = 0;
|
||||||
|
sharingCutEdges[2] = 0;
|
||||||
|
sharingCutEdges[3] = 0;
|
||||||
|
}
|
||||||
|
bool operator!= (const LigoData &other) const
|
||||||
|
{
|
||||||
|
return (posX != other.posX) ||
|
||||||
|
(posY != other.posY) ||
|
||||||
|
(rot != other.rot) ||
|
||||||
|
(flip != other.flip) ||
|
||||||
|
(zoneName != other.zoneName) ||
|
||||||
|
(sharingMatNames[0] != other.sharingMatNames[0]) ||
|
||||||
|
(sharingMatNames[1] != other.sharingMatNames[1]) ||
|
||||||
|
(sharingMatNames[2] != other.sharingMatNames[2]) ||
|
||||||
|
(sharingMatNames[3] != other.sharingMatNames[3]) ||
|
||||||
|
(sharingCutEdges[0] != other.sharingCutEdges[0]) ||
|
||||||
|
(sharingCutEdges[1] != other.sharingCutEdges[1]) ||
|
||||||
|
(sharingCutEdges[2] != other.sharingCutEdges[2]) ||
|
||||||
|
(sharingCutEdges[3] != other.sharingCutEdges[3]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class ZoneRegionObject
|
||||||
|
@brief The class contains NLLIGO::CZoneRegion object and provides basic operations above it
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class LANDSCAPE_EDITOR_EXPORT ZoneRegionObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZoneRegionObject();
|
||||||
|
~ZoneRegionObject();
|
||||||
|
|
||||||
|
/// Load landscape data from file
|
||||||
|
bool load(const std::string &fileName);
|
||||||
|
|
||||||
|
/// Save landscape data to file (before save, should set file name).
|
||||||
|
bool save();
|
||||||
|
|
||||||
|
/// Get ligo data
|
||||||
|
void ligoData(LigoData &data, const sint32 x, const sint32 y);
|
||||||
|
|
||||||
|
/// Set ligo data
|
||||||
|
void setLigoData(const LigoData &data, const sint32 x, const sint32 y);
|
||||||
|
|
||||||
|
/// Get file name
|
||||||
|
std::string fileName() const;
|
||||||
|
|
||||||
|
/// Set file name, use for saving data in file
|
||||||
|
void setFileName(const std::string &fileName);
|
||||||
|
|
||||||
|
/// Accessor to LIGO CZoneRegion
|
||||||
|
NLLIGO::CZoneRegion &ligoZoneRegion();
|
||||||
|
|
||||||
|
void setLigoZoneRegion(const NLLIGO::CZoneRegion &zoneRegion);
|
||||||
|
|
||||||
|
/// Check position, it belongs to the landscape
|
||||||
|
bool checkPos(const sint32 x, const sint32 y);
|
||||||
|
|
||||||
|
/// Helper flag to know if the zone region has been modified
|
||||||
|
/// @{
|
||||||
|
bool isModified() const;
|
||||||
|
|
||||||
|
void setModified(bool modified);
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_modified;
|
||||||
|
bool m_editable;
|
||||||
|
std::string m_fileName;
|
||||||
|
NLLIGO::CZoneRegion m_zoneRegion;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
||||||
|
|
||||||
|
#endif // LANDSCAPE_EDITOR_H
|
|
@ -0,0 +1,70 @@
|
||||||
|
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${LIBXML2_INCLUDE_DIR}
|
||||||
|
${QT_INCLUDES}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/qtpropertybrowser
|
||||||
|
)
|
||||||
|
|
||||||
|
FILE(GLOB SRC *.cpp *.h)
|
||||||
|
|
||||||
|
SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_manager.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin_spec.h)
|
||||||
|
|
||||||
|
SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h
|
||||||
|
world_editor_window.h
|
||||||
|
world_editor_scene.h
|
||||||
|
world_editor_scene_item.h
|
||||||
|
primitives_model.h
|
||||||
|
primitives_view.h
|
||||||
|
project_settings_dialog.h
|
||||||
|
property_editor_widget.h
|
||||||
|
world_editor_settings_page.h
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(OVQT_PLUGIN_WORLD_EDITOR_UIS world_editor_window.ui
|
||||||
|
project_settings_dialog.ui
|
||||||
|
property_editor_widget.ui
|
||||||
|
world_editor_settings_page.ui
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(OVQT_PLUGIN_WORLD_EDITOR_RCS world_editor.qrc)
|
||||||
|
|
||||||
|
SET(QT_USE_QTGUI TRUE)
|
||||||
|
SET(QT_USE_QTOPENGL TRUE)
|
||||||
|
|
||||||
|
QT4_ADD_RESOURCES(OVQT_PLUGIN_WORLD_EDITOR_RC_SRCS ${OVQT_PLUGIN_WORLD_EDITOR_RCS})
|
||||||
|
QT4_WRAP_CPP(OVQT_PLUGIN_WORLD_EDITOR_MOC_SRC ${OVQT_PLUGIN_WORLD_EDITOR_HDR})
|
||||||
|
QT4_WRAP_UI(OVQT_PLUGIN_WORLD_EDITOR_UI_HDRS ${OVQT_PLUGIN_WORLD_EDITOR_UIS})
|
||||||
|
|
||||||
|
SOURCE_GROUP(QtResources FILES ${OVQT_PLUGIN_WORLD_EDITOR_UIS})
|
||||||
|
SOURCE_GROUP(QtGeneratedUiHdr FILES ${OVQT_PLUGIN_WORLD_EDITOR_UI_HDRS})
|
||||||
|
SOURCE_GROUP(QtGeneratedMocQrcSrc FILES ${OVQT_PLUGIN_WORLD_EDITOR_MOC_SRC} OVQT_PLUGIN_WORLD_EDITOR_RC_SRCS)
|
||||||
|
SOURCE_GROUP("World Editor Plugin" FILES ${SRC})
|
||||||
|
SOURCE_GROUP("OVQT Extension System" FILES ${OVQT_EXT_SYS_SRC})
|
||||||
|
|
||||||
|
ADD_LIBRARY(ovqt_plugin_world_editor MODULE ${SRC}
|
||||||
|
${OVQT_PLUGIN_WORLD_EDITOR_MOC_SRC}
|
||||||
|
${OVQT_EXT_SYS_SRC}
|
||||||
|
${OVQT_PLUGIN_WORLD_EDITOR_UI_HDRS}
|
||||||
|
${OVQT_PLUGIN_WORLD_EDITOR_RC_SRCS})
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES( ovqt_plugin_world_editor
|
||||||
|
ovqt_plugin_core
|
||||||
|
ovqt_plugin_landscape_editor
|
||||||
|
nelmisc
|
||||||
|
nel3d
|
||||||
|
qt_property_browser
|
||||||
|
${QT_LIBRARIES}
|
||||||
|
${QT_QTOPENGL_LIBRARY}
|
||||||
|
)
|
||||||
|
|
||||||
|
NL_DEFAULT_PROPS(ovqt_plugin_world_editor "NeL, Tools, 3D: Object Viewer Qt Plugin: World Editor")
|
||||||
|
NL_ADD_RUNTIME_FLAGS(ovqt_plugin_world_editor)
|
||||||
|
NL_ADD_LIB_SUFFIX(ovqt_plugin_world_editor)
|
||||||
|
|
||||||
|
ADD_DEFINITIONS(-DWORLD_EDITOR_LIBRARY ${LIBXML2_DEFINITIONS} -DQT_PLUGIN -DQT_SHARED ${QT_DEFINITIONS})
|
||||||
|
|
||||||
|
INSTALL(TARGETS ovqt_plugin_world_editor LIBRARY DESTINATION ${OVQT_PLUGIN_DIR} RUNTIME DESTINATION ${NL_BIN_PREFIX} ARCHIVE DESTINATION ${OVQT_PLUGIN_DIR} COMPONENT tools3d)
|
||||||
|
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/ovqt_plugin_world_editor.xml DESTINATION ${OVQT_PLUGIN_SPECS_DIR} COMPONENT tools3d)
|
||||||
|
|
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 4 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 43 KiB |
|
@ -0,0 +1,11 @@
|
||||||
|
<plugin-spec>
|
||||||
|
<library-name>ovqt_plugin_world_editor</library-name>
|
||||||
|
<name>WorldEditor</name>
|
||||||
|
<version>0.6</version>
|
||||||
|
<vendor>GSoC2011_dnk-88</vendor>
|
||||||
|
<description>Landscape editor ovqt plugin.</description>
|
||||||
|
<dependencies>
|
||||||
|
<dependency plugin-name="Core" version="0.8"/>
|
||||||
|
<dependency plugin-name="LandscapeEditor" version="0.6"/>
|
||||||
|
</dependencies>
|
||||||
|
</plugin-spec>
|
|
@ -0,0 +1,312 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "primitive_item.h"
|
||||||
|
#include "world_editor_misc.h"
|
||||||
|
#include "world_editor_constants.h"
|
||||||
|
|
||||||
|
#include "../landscape_editor/landscape_editor_constants.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/ligo_config.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QFile>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
Node::Node()
|
||||||
|
: m_parent(0)
|
||||||
|
{
|
||||||
|
setData(Constants::PRIMITIVE_IS_VISIBLE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::~Node()
|
||||||
|
{
|
||||||
|
if (m_parent)
|
||||||
|
m_parent->removeChildNode(this);
|
||||||
|
|
||||||
|
qDeleteAll(m_children);
|
||||||
|
nlassert(m_children.isEmpty());
|
||||||
|
m_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::prependChildNode(Node *node)
|
||||||
|
{
|
||||||
|
// Node is already a child
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
// Node already has a parent
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
m_children.prepend(node);
|
||||||
|
node->m_parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::appendChildNode(Node *node)
|
||||||
|
{
|
||||||
|
// Node is already a child
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
// Node already has a parent
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
m_children.append(node);
|
||||||
|
node->m_parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::insertChildNodeBefore(Node *node, Node *before)
|
||||||
|
{
|
||||||
|
// Node is already a child
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
// Node already has a parent
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
int idx = before ? m_children.indexOf(before) : -1;
|
||||||
|
if (idx == -1)
|
||||||
|
m_children.append(node);
|
||||||
|
else
|
||||||
|
m_children.insert(idx, node);
|
||||||
|
node->m_parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::insertChildNodeAfter(Node *node, Node *after)
|
||||||
|
{
|
||||||
|
// Node is already a child
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
// Node already has a parent
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
int idx = after ? m_children.indexOf(after) : -1;
|
||||||
|
if (idx == -1)
|
||||||
|
m_children.append(node);
|
||||||
|
else
|
||||||
|
m_children.insert(idx + 1, node);
|
||||||
|
node->m_parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::insertChildNode(int pos, Node *node)
|
||||||
|
{
|
||||||
|
// Node is already a child
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
// Node already has a parent
|
||||||
|
nlassert(!m_children.contains(node));
|
||||||
|
|
||||||
|
m_children.insert(pos, node);
|
||||||
|
node->m_parent = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::removeChildNode(Node *node)
|
||||||
|
{
|
||||||
|
nlassert(m_children.contains(node));
|
||||||
|
nlassert(node->parent() == this);
|
||||||
|
|
||||||
|
m_children.removeOne(node);
|
||||||
|
|
||||||
|
node->m_parent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *Node::child(int row)
|
||||||
|
{
|
||||||
|
return m_children.at(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Node::childCount() const
|
||||||
|
{
|
||||||
|
return m_children.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant Node::data(int key) const
|
||||||
|
{
|
||||||
|
return m_data[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Node::setData(int key, const QVariant &data)
|
||||||
|
{
|
||||||
|
m_data[key] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *Node::parent()
|
||||||
|
{
|
||||||
|
return m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Node::row() const
|
||||||
|
{
|
||||||
|
if (m_parent)
|
||||||
|
return m_parent->m_children.indexOf(const_cast<Node *>(this));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::NodeType Node::type() const
|
||||||
|
{
|
||||||
|
return BasicNodeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldEditNode::WorldEditNode(const QString &name)
|
||||||
|
{
|
||||||
|
setData(Qt::DisplayRole, name);
|
||||||
|
setData(Qt::DecorationRole, QIcon(Constants::ICON_WORLD_EDITOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldEditNode::~WorldEditNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditNode::setContext(const QString &name)
|
||||||
|
{
|
||||||
|
m_context = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WorldEditNode::context() const
|
||||||
|
{
|
||||||
|
return m_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditNode::setDataPath(const QString &path)
|
||||||
|
{
|
||||||
|
m_dataPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WorldEditNode::dataPath() const
|
||||||
|
{
|
||||||
|
return m_dataPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::NodeType WorldEditNode::type() const
|
||||||
|
{
|
||||||
|
return WorldEditNodeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
LandscapeNode::LandscapeNode(const QString &name, int id)
|
||||||
|
: m_id(id),
|
||||||
|
m_fileName(name)
|
||||||
|
{
|
||||||
|
setData(Qt::DisplayRole, name);
|
||||||
|
setData(Qt::DecorationRole, QIcon(LandscapeEditor::Constants::ICON_ZONE_ITEM));
|
||||||
|
}
|
||||||
|
|
||||||
|
LandscapeNode::~LandscapeNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString LandscapeNode::fileName() const
|
||||||
|
{
|
||||||
|
return m_fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LandscapeNode::id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::NodeType LandscapeNode::type() const
|
||||||
|
{
|
||||||
|
return LandscapeNodeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimitiveNode::PrimitiveNode(NLLIGO::IPrimitive *primitive)
|
||||||
|
: m_primitive(primitive)
|
||||||
|
{
|
||||||
|
setData(Qt::DisplayRole, QString(m_primitive->getName().c_str()));
|
||||||
|
setData(Qt::ToolTipRole, QString(m_primitive->getClassName().c_str()));
|
||||||
|
|
||||||
|
std::string className;
|
||||||
|
m_primitive->getPropertyByName("class", className);
|
||||||
|
|
||||||
|
// Set Icon
|
||||||
|
QString nameIcon = QString("%1/%2.ico").arg(Constants::PATH_TO_OLD_ICONS).arg(className.c_str());
|
||||||
|
QIcon icon(nameIcon);
|
||||||
|
if (!QFile::exists(nameIcon))
|
||||||
|
{
|
||||||
|
if (primitive->getParent() == NULL)
|
||||||
|
icon = QIcon(Constants::ICON_ROOT_PRIMITIVE);
|
||||||
|
else if (primitive->getNumChildren() == 0)
|
||||||
|
icon = QIcon(Constants::ICON_PROPERTY);
|
||||||
|
else
|
||||||
|
icon = QIcon(Constants::ICON_FOLDER);
|
||||||
|
}
|
||||||
|
setData(Qt::DecorationRole, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimitiveNode::~PrimitiveNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NLLIGO::IPrimitive *PrimitiveNode::primitive() const
|
||||||
|
{
|
||||||
|
return m_primitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NLLIGO::CPrimitiveClass *PrimitiveNode::primitiveClass() const
|
||||||
|
{
|
||||||
|
return Utils::ligoConfig()->getPrimitiveClass(*m_primitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
RootPrimitiveNode *PrimitiveNode::rootPrimitiveNode()
|
||||||
|
{
|
||||||
|
Node *node = this;
|
||||||
|
while (node && (node->type() != Node::RootPrimitiveNodeType))
|
||||||
|
node = node->parent();
|
||||||
|
return static_cast<RootPrimitiveNode *>(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::NodeType PrimitiveNode::type() const
|
||||||
|
{
|
||||||
|
return PrimitiveNodeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
RootPrimitiveNode::RootPrimitiveNode(const QString &name, NLLIGO::CPrimitives *primitives)
|
||||||
|
: PrimitiveNode(primitives->RootNode),
|
||||||
|
m_fileName(name),
|
||||||
|
m_primitives(primitives)
|
||||||
|
{
|
||||||
|
setData(Qt::DisplayRole, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
RootPrimitiveNode::~RootPrimitiveNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NLLIGO::CPrimitives *RootPrimitiveNode::primitives() const
|
||||||
|
{
|
||||||
|
return m_primitives;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RootPrimitiveNode::setFileName(const QString &fileName)
|
||||||
|
{
|
||||||
|
setData(Qt::DisplayRole, fileName);
|
||||||
|
m_fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RootPrimitiveNode::fileName() const
|
||||||
|
{
|
||||||
|
return m_fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::NodeType RootPrimitiveNode::type() const
|
||||||
|
{
|
||||||
|
return RootPrimitiveNodeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,200 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PRIMITIVE_ITEM_H
|
||||||
|
#define PRIMITIVE_ITEM_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/primitive.h>
|
||||||
|
#include <nel/ligo/primitive_class.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QList>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
class RootPrimitiveNode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class Node
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum NodeType
|
||||||
|
{
|
||||||
|
BasicNodeType,
|
||||||
|
WorldEditNodeType,
|
||||||
|
RootPrimitiveNodeType,
|
||||||
|
LandscapeNodeType,
|
||||||
|
PrimitiveNodeType,
|
||||||
|
UserNodeType = 1024
|
||||||
|
};
|
||||||
|
|
||||||
|
Node();
|
||||||
|
virtual ~Node();
|
||||||
|
|
||||||
|
/// Remove child node from the child list.
|
||||||
|
void removeChildNode(Node *node);
|
||||||
|
|
||||||
|
/// Insert node at the beginning of the list.
|
||||||
|
void prependChildNode(Node *node);
|
||||||
|
|
||||||
|
/// Insert node at the end of the list.
|
||||||
|
void appendChildNode(Node *node);
|
||||||
|
|
||||||
|
/// Insert node in front of the node pointed to by the pointer before.
|
||||||
|
void insertChildNodeBefore(Node *node, Node *before);
|
||||||
|
|
||||||
|
/// Insert node in back of the node pointed to by the pointer after.
|
||||||
|
void insertChildNodeAfter(Node *node, Node *after);
|
||||||
|
|
||||||
|
/// Insert node in pos
|
||||||
|
void insertChildNode(int pos, Node *node);
|
||||||
|
|
||||||
|
/// Return the node at index position row in the child list.
|
||||||
|
Node *child(int row);
|
||||||
|
|
||||||
|
/// Return the number of nodes in the list.
|
||||||
|
int childCount() const;
|
||||||
|
|
||||||
|
/// Return a row index this node.
|
||||||
|
int row() const;
|
||||||
|
|
||||||
|
/// Return a pointer to this node's parent item. If this node does not have a parent, 0 is returned.
|
||||||
|
Node *parent();
|
||||||
|
|
||||||
|
/// Set this node's custom data for the key key to value.
|
||||||
|
void setData(int key, const QVariant &data);
|
||||||
|
|
||||||
|
/// Return this node's custom data for the key key as a QVariant.
|
||||||
|
QVariant data(int key) const;
|
||||||
|
|
||||||
|
/// Return a type this node.
|
||||||
|
virtual NodeType type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DISABLE_COPY(Node)
|
||||||
|
|
||||||
|
Node *m_parent;
|
||||||
|
QList<Node *> m_children;
|
||||||
|
QHash<int, QVariant> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class WorldEditNode
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class WorldEditNode: public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WorldEditNode(const QString &name);
|
||||||
|
virtual ~WorldEditNode();
|
||||||
|
|
||||||
|
void setContext(const QString &name);
|
||||||
|
QString context() const;
|
||||||
|
void setDataPath(const QString &path);
|
||||||
|
QString dataPath() const;
|
||||||
|
|
||||||
|
virtual NodeType type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_context;
|
||||||
|
QString m_dataPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class LandscapeNode
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class LandscapeNode: public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LandscapeNode(const QString &name, int id);
|
||||||
|
virtual ~LandscapeNode();
|
||||||
|
|
||||||
|
int id() const;
|
||||||
|
QString fileName() const;
|
||||||
|
|
||||||
|
virtual NodeType type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString m_fileName;
|
||||||
|
int m_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class PrimitiveNode
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class PrimitiveNode: public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PrimitiveNode(NLLIGO::IPrimitive *primitive);
|
||||||
|
virtual ~PrimitiveNode();
|
||||||
|
|
||||||
|
NLLIGO::IPrimitive *primitive() const;
|
||||||
|
const NLLIGO::CPrimitiveClass *primitiveClass() const;
|
||||||
|
RootPrimitiveNode *rootPrimitiveNode();
|
||||||
|
|
||||||
|
virtual NodeType type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NLLIGO::IPrimitive *m_primitive;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class RootPrimitiveNode
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class RootPrimitiveNode: public PrimitiveNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RootPrimitiveNode(const QString &name, NLLIGO::CPrimitives *primitives);
|
||||||
|
virtual ~RootPrimitiveNode();
|
||||||
|
|
||||||
|
NLLIGO::CPrimitives *primitives() const;
|
||||||
|
|
||||||
|
void setFileName(const QString &fileName);
|
||||||
|
QString fileName() const;
|
||||||
|
virtual NodeType type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString m_fileName;
|
||||||
|
NLLIGO::CPrimitives *m_primitives;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef QList<Node *> NodeList;
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
// Enable the use of QVariant with this class.
|
||||||
|
Q_DECLARE_METATYPE(WorldEditor::Node *)
|
||||||
|
|
||||||
|
#endif // PRIMITIVE_ITEM_H
|
|
@ -0,0 +1,328 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "primitive_item.h"
|
||||||
|
#include "primitives_model.h"
|
||||||
|
#include "world_editor_misc.h"
|
||||||
|
#include "world_editor_constants.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
#include <nel/ligo/primitive.h>
|
||||||
|
#include <nel/ligo/primitive_utils.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
PrimitivesTreeModel::PrimitivesTreeModel(QObject *parent)
|
||||||
|
: QAbstractItemModel(parent),
|
||||||
|
m_worldEditNode(0)
|
||||||
|
{
|
||||||
|
m_rootNode = new Node();
|
||||||
|
m_rootNode->setData(Qt::DisplayRole, "Name");
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimitivesTreeModel::~PrimitivesTreeModel()
|
||||||
|
{
|
||||||
|
delete m_rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PrimitivesTreeModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
/* if (parent.isValid())
|
||||||
|
return static_cast<BaseTreeItem *>(parent.internalPointer())->columnCount();
|
||||||
|
else
|
||||||
|
return m_rootItem->columnCount();
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PrimitivesTreeModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
Node *item = static_cast<Node *>(index.internalPointer());
|
||||||
|
switch (role)
|
||||||
|
{
|
||||||
|
// case Qt::TextAlignmentRole:
|
||||||
|
// return int(Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return item->data(Qt::DisplayRole);
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
return item->data(Qt::DecorationRole);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags PrimitivesTreeModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PrimitivesTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||||
|
// return m_rootNode->data(section);
|
||||||
|
return m_rootNode->data(Qt::DisplayRole);
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex PrimitivesTreeModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
if (!hasIndex(row, column, parent))
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
Node *parentNode;
|
||||||
|
|
||||||
|
if (!parent.isValid())
|
||||||
|
parentNode = m_rootNode;
|
||||||
|
else
|
||||||
|
parentNode = static_cast<Node *>(parent.internalPointer());
|
||||||
|
|
||||||
|
Node *childNode = parentNode->child(row);
|
||||||
|
if (childNode)
|
||||||
|
return createIndex(row, column, childNode);
|
||||||
|
else
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex PrimitivesTreeModel::parent(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
Node *childNode = static_cast<Node *>(index.internalPointer());
|
||||||
|
Node *parentNode = childNode->parent();
|
||||||
|
|
||||||
|
if (parentNode == m_rootNode)
|
||||||
|
return QModelIndex();
|
||||||
|
|
||||||
|
return createIndex(parentNode->row(), 0, parentNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PrimitivesTreeModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Node *parentNode;
|
||||||
|
if (parent.column() > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!parent.isValid())
|
||||||
|
parentNode = m_rootNode;
|
||||||
|
else
|
||||||
|
parentNode = static_cast<Node *>(parent.internalPointer());
|
||||||
|
|
||||||
|
return parentNode->childCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
Path PrimitivesTreeModel::pathFromIndex(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
QModelIndex iter = index;
|
||||||
|
Path path;
|
||||||
|
while(iter.isValid())
|
||||||
|
{
|
||||||
|
path.prepend(PathItem(iter.row(), iter.column()));
|
||||||
|
iter = iter.parent();
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path PrimitivesTreeModel::pathFromNode(Node *node)
|
||||||
|
{
|
||||||
|
Node *iter = node;
|
||||||
|
Path path;
|
||||||
|
while(iter != 0)
|
||||||
|
{
|
||||||
|
path.prepend(PathItem(iter->row(), 0));
|
||||||
|
iter = iter->parent();
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex PrimitivesTreeModel::pathToIndex(const Path &path)
|
||||||
|
{
|
||||||
|
QModelIndex iter;
|
||||||
|
for(int i = 0; i < path.size(); i++)
|
||||||
|
{
|
||||||
|
iter = index(path[i].first, path[i].second, iter);
|
||||||
|
}
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *PrimitivesTreeModel::pathToNode(const Path &path)
|
||||||
|
{
|
||||||
|
Node *node = m_rootNode;
|
||||||
|
for(int i = 1; i < path.size(); i++)
|
||||||
|
{
|
||||||
|
node = node->child(path[i].first);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesTreeModel::createWorldEditNode(const QString &fileName)
|
||||||
|
{
|
||||||
|
// World edit node already is created, if yes is showing error message box
|
||||||
|
if (m_worldEditNode != 0)
|
||||||
|
nlerror("World edit node already is created.");
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
m_worldEditNode = new WorldEditNode(fileName);
|
||||||
|
m_rootNode->appendChildNode(m_worldEditNode);
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesTreeModel::deleteWorldEditNode()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
if (m_worldEditNode != 0)
|
||||||
|
{
|
||||||
|
delete m_worldEditNode;
|
||||||
|
m_worldEditNode = 0;
|
||||||
|
}
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrimitivesTreeModel::isWorldEditNodeLoaded() const
|
||||||
|
{
|
||||||
|
if (m_worldEditNode == 0)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path PrimitivesTreeModel::createLandscapeNode(const QString &fileName, int id, int pos)
|
||||||
|
{
|
||||||
|
if (m_worldEditNode == 0)
|
||||||
|
createWorldEditNode("NewWorldEdit");
|
||||||
|
|
||||||
|
QModelIndex parentIndex = index(0, 0, QModelIndex());
|
||||||
|
int insPos = pos;
|
||||||
|
if (pos == -1)
|
||||||
|
insPos = 0;
|
||||||
|
|
||||||
|
beginInsertRows(parentIndex, insPos, insPos);
|
||||||
|
LandscapeNode *newNode = new LandscapeNode(fileName, id);
|
||||||
|
m_worldEditNode->insertChildNode(insPos, newNode);
|
||||||
|
endInsertRows();
|
||||||
|
return pathFromIndex(index(0, 0, index(insPos, 0, QModelIndex())));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Path PrimitivesTreeModel::createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives, int pos)
|
||||||
|
{
|
||||||
|
if (m_worldEditNode == 0)
|
||||||
|
createWorldEditNode("NewWorldEdit");
|
||||||
|
|
||||||
|
QString name = "NewPrimitive";
|
||||||
|
if (!fileName.isEmpty())
|
||||||
|
name = fileName;
|
||||||
|
|
||||||
|
int insPos = pos;
|
||||||
|
|
||||||
|
// Get position
|
||||||
|
if (pos == AtTheEnd)
|
||||||
|
insPos = m_worldEditNode->childCount();
|
||||||
|
|
||||||
|
QModelIndex parentIndex = index(0, 0, QModelIndex());
|
||||||
|
|
||||||
|
// Add root node in tree model
|
||||||
|
beginInsertRows(parentIndex, insPos, insPos);
|
||||||
|
RootPrimitiveNode *newNode = new RootPrimitiveNode(name, primitives);
|
||||||
|
m_worldEditNode->insertChildNode(insPos, newNode);
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
newNode->setData(Constants::PRIMITIVE_FILE_IS_CREATED, !fileName.isEmpty());
|
||||||
|
newNode->setData(Constants::PRIMITIVE_IS_MODIFIED, false);
|
||||||
|
|
||||||
|
QModelIndex rootPrimIndex = index(insPos, 0, parentIndex);
|
||||||
|
|
||||||
|
// Scan childs items and add in the tree model
|
||||||
|
for (uint i = 0; i < primitives->RootNode->getNumChildren(); ++i)
|
||||||
|
{
|
||||||
|
NLLIGO::IPrimitive *childPrim;
|
||||||
|
primitives->RootNode->getChild(childPrim, i);
|
||||||
|
createChildNodes(childPrim, i, rootPrimIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pathFromIndex(rootPrimIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Path PrimitivesTreeModel::createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent, int pos)
|
||||||
|
{
|
||||||
|
QModelIndex parentIndex = pathToIndex(parent);
|
||||||
|
Node *parentNode = static_cast<Node *>(parentIndex.internalPointer());
|
||||||
|
|
||||||
|
int insPos = pos;
|
||||||
|
if (pos == AtTheEnd)
|
||||||
|
insPos = parentNode->childCount();
|
||||||
|
|
||||||
|
createChildNodes(primitive, insPos, parentIndex);
|
||||||
|
|
||||||
|
return pathFromIndex(index(insPos, 0, parentIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesTreeModel::deleteNode(const Path &path)
|
||||||
|
{
|
||||||
|
QModelIndex nodeIndex = pathToIndex(path);
|
||||||
|
QModelIndex parentIndex = nodeIndex.parent();
|
||||||
|
Node *node = static_cast<Node *>(nodeIndex.internalPointer());
|
||||||
|
|
||||||
|
// Scan childs items and delete from the tree model
|
||||||
|
removeChildNodes(node, parentIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesTreeModel::createChildNodes(NLLIGO::IPrimitive *primitive, int pos, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
Node *parentNode = static_cast<Node *>(parent.internalPointer());
|
||||||
|
|
||||||
|
// Add node in the tree model
|
||||||
|
beginInsertRows(parent, pos, pos);
|
||||||
|
PrimitiveNode *newNode = new PrimitiveNode(primitive);
|
||||||
|
parentNode->insertChildNode(pos, newNode);
|
||||||
|
endInsertRows();
|
||||||
|
|
||||||
|
// Scan childs items and add in the tree model
|
||||||
|
QModelIndex childIndex = index(pos, 0, parent);
|
||||||
|
for (uint i = 0; i < primitive->getNumChildren(); ++i)
|
||||||
|
{
|
||||||
|
NLLIGO::IPrimitive *childPrim;
|
||||||
|
primitive->getChild(childPrim, i);
|
||||||
|
createChildNodes(childPrim, i, childIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesTreeModel::removeChildNodes(Node *node, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
// Delete all child nodes from the tree model
|
||||||
|
while (node->childCount() != 0)
|
||||||
|
removeChildNodes(node->child(node->childCount() - 1), parent.child(node->row(), 0));
|
||||||
|
|
||||||
|
// Delete node from the tree model
|
||||||
|
beginRemoveRows(parent, node->row(), node->row());
|
||||||
|
delete node;
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,104 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PRIMITIVES_MODEL_H
|
||||||
|
#define PRIMITIVES_MODEL_H
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/vector.h>
|
||||||
|
#include <nel/ligo/primitive.h>
|
||||||
|
#include <nel/ligo/primitive_class.h>
|
||||||
|
#include <nel/ligo/ligo_config.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
class Node;
|
||||||
|
class WorldEditNode;
|
||||||
|
|
||||||
|
const int AtTheEnd = -1;
|
||||||
|
|
||||||
|
typedef QPair<int, int> PathItem;
|
||||||
|
/*
|
||||||
|
@typedef Path
|
||||||
|
@brief It store a list of row and column numbers which have to walk through from the root index of the model to reach the need item.
|
||||||
|
It is used for undo/redo commands.
|
||||||
|
*/
|
||||||
|
typedef QList<PathItem> Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class PrimitivesTreeModel
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class PrimitivesTreeModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PrimitivesTreeModel(QObject *parent = 0);
|
||||||
|
~PrimitivesTreeModel();
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
|
int role = Qt::DisplayRole) const;
|
||||||
|
QModelIndex index(int row, int column,
|
||||||
|
const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
QModelIndex parent(const QModelIndex &index) const;
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
|
||||||
|
/// Convert QModelIndex to the persistent index - @Path.
|
||||||
|
/// @Path is a list of [row,column] pairs showing us the way through the model.
|
||||||
|
Path pathFromIndex(const QModelIndex &index);
|
||||||
|
QModelIndex pathToIndex(const Path &path);
|
||||||
|
|
||||||
|
Path pathFromNode(Node *node);
|
||||||
|
Node *pathToNode(const Path &path);
|
||||||
|
|
||||||
|
void createWorldEditNode(const QString &fileName);
|
||||||
|
void deleteWorldEditNode();
|
||||||
|
bool isWorldEditNodeLoaded() const;
|
||||||
|
|
||||||
|
/// Add new landscape node in tree model.
|
||||||
|
Path createLandscapeNode(const QString &fileName, int id, int pos = AtTheEnd);
|
||||||
|
|
||||||
|
/// Add new root primitive node and all sub-primitives in the tree model.
|
||||||
|
Path createRootPrimitiveNode(const QString &fileName, NLLIGO::CPrimitives *primitives, int pos = AtTheEnd);
|
||||||
|
|
||||||
|
/// Add new primitive node and all sub-primitives in the tree model.
|
||||||
|
Path createPrimitiveNode(NLLIGO::IPrimitive *primitive, const Path &parent, int pos = AtTheEnd);
|
||||||
|
|
||||||
|
/// Delete node and all child nodes from the tree model
|
||||||
|
void deleteNode(const Path &path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createChildNodes(NLLIGO::IPrimitive *primitive, int pos, const QModelIndex &parent);
|
||||||
|
void removeChildNodes(Node *node, const QModelIndex &parent);
|
||||||
|
|
||||||
|
Node *m_rootNode;
|
||||||
|
WorldEditNode *m_worldEditNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
#endif // PRIMITIVES_MODEL_H
|
|
@ -0,0 +1,458 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "primitives_view.h"
|
||||||
|
#include "primitives_model.h"
|
||||||
|
#include "world_editor_actions.h"
|
||||||
|
#include "world_editor_constants.h"
|
||||||
|
|
||||||
|
#include "../core/core_constants.h"
|
||||||
|
#include "../landscape_editor/landscape_editor_constants.h"
|
||||||
|
#include "../landscape_editor/builder_zone_base.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/primitive.h>
|
||||||
|
#include <nel/ligo/ligo_config.h>
|
||||||
|
#include <nel/ligo/primitive_class.h>
|
||||||
|
#include <nel/ligo/primitive_utils.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QContextMenuEvent>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QtGui/QMenu>
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
PrimitivesView::PrimitivesView(QWidget *parent)
|
||||||
|
: QTreeView(parent),
|
||||||
|
m_undoStack(0),
|
||||||
|
m_worldEditorScene(0),
|
||||||
|
m_zoneBuilder(0),
|
||||||
|
m_primitivesTreeModel(0)
|
||||||
|
{
|
||||||
|
setContextMenuPolicy(Qt::DefaultContextMenu);
|
||||||
|
|
||||||
|
m_unloadAction = new QAction("Unload", this);
|
||||||
|
|
||||||
|
m_saveAction = new QAction("Save", this);
|
||||||
|
m_saveAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
|
||||||
|
|
||||||
|
m_saveAsAction = new QAction("Save As...", this);
|
||||||
|
m_saveAsAction->setIcon(QIcon(Core::Constants::ICON_SAVE_AS));
|
||||||
|
|
||||||
|
m_loadLandAction = new QAction("Load landscape file", this);
|
||||||
|
m_loadLandAction->setIcon(QIcon(LandscapeEditor::Constants::ICON_ZONE_ITEM));
|
||||||
|
|
||||||
|
m_loadPrimitiveAction = new QAction("Load primitive file", this);
|
||||||
|
m_loadPrimitiveAction->setIcon(QIcon(Constants::ICON_ROOT_PRIMITIVE));
|
||||||
|
|
||||||
|
m_newPrimitiveAction = new QAction("New primitive", this);
|
||||||
|
|
||||||
|
m_deleteAction = new QAction("Delete", this);
|
||||||
|
|
||||||
|
m_selectChildrenAction = new QAction("Select children", this);
|
||||||
|
|
||||||
|
m_helpAction = new QAction("Help", this);
|
||||||
|
m_helpAction->setEnabled(false);
|
||||||
|
|
||||||
|
m_showAction = new QAction("Show", this);
|
||||||
|
m_showAction->setEnabled(false);
|
||||||
|
|
||||||
|
m_hideAction = new QAction("Hide", this);
|
||||||
|
m_hideAction->setEnabled(false);
|
||||||
|
|
||||||
|
connect(m_loadLandAction, SIGNAL(triggered()), this, SLOT(loadLandscape()));
|
||||||
|
connect(m_loadPrimitiveAction, SIGNAL(triggered()), this, SLOT(loadRootPrimitive()));
|
||||||
|
connect(m_newPrimitiveAction, SIGNAL(triggered()), this, SLOT(createRootPrimitive()));
|
||||||
|
connect(m_selectChildrenAction, SIGNAL(triggered()), this, SLOT(selectChildren()));
|
||||||
|
connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(deletePrimitives()));
|
||||||
|
connect(m_saveAction, SIGNAL(triggered()), this, SLOT(save()));
|
||||||
|
connect(m_saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));
|
||||||
|
connect(m_unloadAction, SIGNAL(triggered()), this, SLOT(unload()));
|
||||||
|
connect(m_showAction, SIGNAL(triggered()), this, SLOT(showPrimitive()));
|
||||||
|
connect(m_hideAction, SIGNAL(triggered()), this, SLOT(hidePrimitive()));
|
||||||
|
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimitivesView::~PrimitivesView()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::setUndoStack(QUndoStack *undoStack)
|
||||||
|
{
|
||||||
|
m_undoStack = undoStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::setZoneBuilder(LandscapeEditor::ZoneBuilderBase *zoneBuilder)
|
||||||
|
{
|
||||||
|
m_zoneBuilder = zoneBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::setWorldScene(WorldEditorScene *worldEditorScene)
|
||||||
|
{
|
||||||
|
m_worldEditorScene = worldEditorScene;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::setModel(PrimitivesTreeModel *model)
|
||||||
|
{
|
||||||
|
QTreeView::setModel(model);
|
||||||
|
m_primitivesTreeModel = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::loadRootPrimitive()
|
||||||
|
{
|
||||||
|
nlassert(m_undoStack);
|
||||||
|
nlassert(m_primitivesTreeModel);
|
||||||
|
|
||||||
|
QStringList fileNames = QFileDialog::getOpenFileNames(this,
|
||||||
|
tr("Open NeL Ligo primitive file"), m_lastDir,
|
||||||
|
tr("All NeL Ligo primitive files (*.primitive)"));
|
||||||
|
|
||||||
|
setCursor(Qt::WaitCursor);
|
||||||
|
if (!fileNames.isEmpty())
|
||||||
|
{
|
||||||
|
if (fileNames.count() > 1)
|
||||||
|
m_undoStack->beginMacro(tr("Load primitive files"));
|
||||||
|
|
||||||
|
Q_FOREACH(QString fileName, fileNames)
|
||||||
|
{
|
||||||
|
m_lastDir = QFileInfo(fileName).absolutePath();
|
||||||
|
m_undoStack->push(new LoadRootPrimitiveCommand(fileName, m_worldEditorScene, m_primitivesTreeModel, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileNames.count() > 1)
|
||||||
|
m_undoStack->endMacro();
|
||||||
|
}
|
||||||
|
setCursor(Qt::ArrowCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::loadLandscape()
|
||||||
|
{
|
||||||
|
nlassert(m_undoStack);
|
||||||
|
nlassert(m_zoneBuilder);
|
||||||
|
nlassert(m_primitivesTreeModel);
|
||||||
|
|
||||||
|
QStringList fileNames = QFileDialog::getOpenFileNames(this,
|
||||||
|
tr("Open NeL Ligo land file"), m_lastDir,
|
||||||
|
tr("All NeL Ligo land files (*.land)"));
|
||||||
|
|
||||||
|
setCursor(Qt::WaitCursor);
|
||||||
|
if (!fileNames.isEmpty())
|
||||||
|
{
|
||||||
|
if (fileNames.count() > 1)
|
||||||
|
m_undoStack->beginMacro(tr("Load land files"));
|
||||||
|
|
||||||
|
Q_FOREACH(QString fileName, fileNames)
|
||||||
|
{
|
||||||
|
m_lastDir = QFileInfo(fileName).absolutePath();
|
||||||
|
m_undoStack->push(new LoadLandscapeCommand(fileName, m_primitivesTreeModel, m_zoneBuilder));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileNames.count() > 1)
|
||||||
|
m_undoStack->endMacro();
|
||||||
|
}
|
||||||
|
setCursor(Qt::ArrowCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::createRootPrimitive()
|
||||||
|
{
|
||||||
|
nlassert(m_undoStack);
|
||||||
|
nlassert(m_primitivesTreeModel);
|
||||||
|
|
||||||
|
m_undoStack->push(new CreateRootPrimitiveCommand("NewPrimitive", m_primitivesTreeModel));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::selectChildren()
|
||||||
|
{
|
||||||
|
QModelIndexList indexList = selectionModel()->selectedRows();
|
||||||
|
QModelIndex parentIndex = indexList.first();
|
||||||
|
|
||||||
|
selectionModel()->clearSelection();
|
||||||
|
|
||||||
|
QItemSelection itemSelection;
|
||||||
|
selectChildren(parentIndex, itemSelection);
|
||||||
|
selectionModel()->select(itemSelection, QItemSelectionModel::Select);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::save()
|
||||||
|
{
|
||||||
|
nlassert(m_primitivesTreeModel);
|
||||||
|
|
||||||
|
QModelIndexList indexList = selectionModel()->selectedRows();
|
||||||
|
QModelIndex index = indexList.first();
|
||||||
|
|
||||||
|
RootPrimitiveNode *node = static_cast<RootPrimitiveNode *>(index.internalPointer());
|
||||||
|
|
||||||
|
if (node->data(Constants::PRIMITIVE_FILE_IS_CREATED).toBool())
|
||||||
|
{
|
||||||
|
if (!NLLIGO::saveXmlPrimitiveFile(*node->primitives(), node->fileName().toStdString()))
|
||||||
|
QMessageBox::warning(this, "World Editor Qt", tr("Error writing output file: %1").arg(node->fileName()));
|
||||||
|
else
|
||||||
|
node->setData(Constants::PRIMITIVE_IS_MODIFIED, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
saveAs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::saveAs()
|
||||||
|
{
|
||||||
|
nlassert(m_primitivesTreeModel);
|
||||||
|
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this,
|
||||||
|
tr("Save NeL Ligo primitive file"), m_lastDir,
|
||||||
|
tr("NeL Ligo primitive file (*.primitive)"));
|
||||||
|
|
||||||
|
setCursor(Qt::WaitCursor);
|
||||||
|
if (!fileName.isEmpty())
|
||||||
|
{
|
||||||
|
QModelIndexList indexList = selectionModel()->selectedRows();
|
||||||
|
QModelIndex index = indexList.first();
|
||||||
|
|
||||||
|
RootPrimitiveNode *node = static_cast<RootPrimitiveNode *>(index.internalPointer());
|
||||||
|
|
||||||
|
if (!NLLIGO::saveXmlPrimitiveFile(*node->primitives(), fileName.toStdString()))
|
||||||
|
QMessageBox::warning(this, "World Editor Qt", tr("Error writing output file: %1").arg(fileName));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
node->setFileName(fileName);
|
||||||
|
node->setData(Constants::PRIMITIVE_FILE_IS_CREATED, true);
|
||||||
|
node->setData(Constants::PRIMITIVE_IS_MODIFIED, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCursor(Qt::ArrowCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::deletePrimitives()
|
||||||
|
{
|
||||||
|
nlassert(m_undoStack);
|
||||||
|
nlassert(m_primitivesTreeModel);
|
||||||
|
|
||||||
|
QModelIndexList indexList = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
QModelIndex index = indexList.first();
|
||||||
|
|
||||||
|
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
|
||||||
|
|
||||||
|
if (node->primitiveClass()->Deletable)
|
||||||
|
m_undoStack->push(new DeletePrimitiveCommand(index, m_primitivesTreeModel, m_worldEditorScene, this));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::unload()
|
||||||
|
{
|
||||||
|
nlassert(m_undoStack);
|
||||||
|
nlassert(m_primitivesTreeModel);
|
||||||
|
|
||||||
|
QModelIndexList indexList = selectionModel()->selectedRows();
|
||||||
|
QModelIndex index = indexList.first();
|
||||||
|
Node *node = static_cast<Node *>(index.internalPointer());
|
||||||
|
switch (node->type())
|
||||||
|
{
|
||||||
|
case Node::WorldEditNodeType:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Node::LandscapeNodeType:
|
||||||
|
{
|
||||||
|
m_undoStack->push(new UnloadLandscapeCommand(index, m_primitivesTreeModel, m_zoneBuilder));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Node::RootPrimitiveNodeType:
|
||||||
|
{
|
||||||
|
m_undoStack->push(new UnloadRootPrimitiveCommand(index, m_worldEditorScene, m_primitivesTreeModel, this));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::showPrimitive()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::hidePrimitive()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::addNewPrimitiveByClass(int value)
|
||||||
|
{
|
||||||
|
nlassert(m_undoStack);
|
||||||
|
nlassert(m_primitivesTreeModel);
|
||||||
|
|
||||||
|
QModelIndexList indexList = selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
PrimitiveNode *node = static_cast<PrimitiveNode *>(indexList.first().internalPointer());
|
||||||
|
|
||||||
|
// Get class name
|
||||||
|
QString className = node->primitiveClass()->DynamicChildren[value].ClassName.c_str();
|
||||||
|
|
||||||
|
m_undoStack->push(new AddPrimitiveByClassCommand(className, m_primitivesTreeModel->pathFromIndex(indexList.first()),
|
||||||
|
m_worldEditorScene, m_primitivesTreeModel, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::generatePrimitives(int value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::openItem(int value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::contextMenuEvent(QContextMenuEvent *event)
|
||||||
|
{
|
||||||
|
QWidget::contextMenuEvent(event);
|
||||||
|
QModelIndexList indexList = selectionModel()->selectedRows();
|
||||||
|
if (indexList.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMenu *popurMenu = new QMenu(this);
|
||||||
|
|
||||||
|
if (indexList.size() == 1)
|
||||||
|
{
|
||||||
|
Node *node = static_cast<Node *>(indexList.first().internalPointer());
|
||||||
|
switch (node->type())
|
||||||
|
{
|
||||||
|
case Node::WorldEditNodeType:
|
||||||
|
fillMenu_WorldEdit(popurMenu);
|
||||||
|
break;
|
||||||
|
case Node::RootPrimitiveNodeType:
|
||||||
|
fillMenu_RootPrimitive(popurMenu, indexList.first());
|
||||||
|
break;
|
||||||
|
case Node::LandscapeNodeType:
|
||||||
|
fillMenu_Landscape(popurMenu);
|
||||||
|
break;
|
||||||
|
case Node::PrimitiveNodeType:
|
||||||
|
fillMenu_Primitive(popurMenu, indexList.first());
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
popurMenu->exec(event->globalPos());
|
||||||
|
delete popurMenu;
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::selectChildren(const QModelIndex &parent, QItemSelection &itemSelection)
|
||||||
|
{
|
||||||
|
const int rowCount = model()->rowCount(parent);
|
||||||
|
|
||||||
|
QItemSelection mergeItemSelection(parent.child(0, 0), parent.child(rowCount - 1, 0));
|
||||||
|
itemSelection.merge(mergeItemSelection, QItemSelectionModel::Select);
|
||||||
|
|
||||||
|
for (int i = 0; i < rowCount; ++i)
|
||||||
|
{
|
||||||
|
QModelIndex childIndex = parent.child(i, 0);
|
||||||
|
if (model()->rowCount(childIndex) != 0)
|
||||||
|
selectChildren(childIndex, itemSelection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::fillMenu_WorldEdit(QMenu *menu)
|
||||||
|
{
|
||||||
|
//menu->addAction(m_unloadAction);
|
||||||
|
//menu->addAction(m_saveAction);
|
||||||
|
//menu->addAction(m_saveAsAction);
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addAction(m_loadLandAction);
|
||||||
|
menu->addAction(m_loadPrimitiveAction);
|
||||||
|
menu->addAction(m_newPrimitiveAction);
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addAction(m_helpAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::fillMenu_Landscape(QMenu *menu)
|
||||||
|
{
|
||||||
|
menu->addAction(m_unloadAction);
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addAction(m_showAction);
|
||||||
|
menu->addAction(m_hideAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::fillMenu_RootPrimitive(QMenu *menu, const QModelIndex &index)
|
||||||
|
{
|
||||||
|
menu->addAction(m_saveAction);
|
||||||
|
menu->addAction(m_saveAsAction);
|
||||||
|
menu->addAction(m_unloadAction);
|
||||||
|
fillMenu_Primitive(menu, index);
|
||||||
|
menu->removeAction(m_deleteAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrimitivesView::fillMenu_Primitive(QMenu *menu, const QModelIndex &index)
|
||||||
|
{
|
||||||
|
menu->addAction(m_deleteAction);
|
||||||
|
menu->addAction(m_selectChildrenAction);
|
||||||
|
menu->addAction(m_helpAction);
|
||||||
|
menu->addSeparator();
|
||||||
|
menu->addAction(m_showAction);
|
||||||
|
menu->addAction(m_hideAction);
|
||||||
|
|
||||||
|
QSignalMapper *addSignalMapper = new QSignalMapper(menu);
|
||||||
|
QSignalMapper *generateSignalMapper = new QSignalMapper(menu);
|
||||||
|
//QSignalMapper *openSignalMapper = new QSignalMapper(menu);
|
||||||
|
connect(addSignalMapper, SIGNAL(mapped(int)), this, SLOT(addNewPrimitiveByClass(int)));
|
||||||
|
connect(generateSignalMapper, SIGNAL(mapped(int)), this, SLOT(generatePrimitives(int)));
|
||||||
|
//connect(openSignalMapper, SIGNAL(mapped(int)), this, SLOT(openItem(int)));
|
||||||
|
|
||||||
|
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
|
||||||
|
const NLLIGO::CPrimitiveClass *primClass = node->primitiveClass();
|
||||||
|
|
||||||
|
// What class is it ?
|
||||||
|
if (primClass && primClass->DynamicChildren.size())
|
||||||
|
{
|
||||||
|
menu->addSeparator();
|
||||||
|
|
||||||
|
// For each child, add a create method
|
||||||
|
for (size_t i = 0; i < primClass->DynamicChildren.size(); i++)
|
||||||
|
{
|
||||||
|
// Get class name
|
||||||
|
QString className = primClass->DynamicChildren[i].ClassName.c_str();
|
||||||
|
|
||||||
|
// Get icon
|
||||||
|
QIcon icon(QString("%1/%2.ico").arg(Constants::PATH_TO_OLD_ICONS).arg(className));
|
||||||
|
|
||||||
|
// Create and add action in popur menu
|
||||||
|
QAction *action = menu->addAction(icon, tr("Add %1").arg(className));
|
||||||
|
addSignalMapper->setMapping(action, i);
|
||||||
|
connect(action, SIGNAL(triggered()), addSignalMapper, SLOT(map()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// What class is it ?
|
||||||
|
if (primClass && primClass->GeneratedChildren.size())
|
||||||
|
{
|
||||||
|
menu->addSeparator();
|
||||||
|
|
||||||
|
// For each child, add a create method
|
||||||
|
for (size_t i = 0; i < primClass->GeneratedChildren.size(); i++)
|
||||||
|
{
|
||||||
|
// Get class name
|
||||||
|
QString childName = primClass->GeneratedChildren[i].ClassName.c_str();
|
||||||
|
|
||||||
|
// Create and add action in popur menu
|
||||||
|
QAction *action = menu->addAction(tr("Generate %1").arg(childName));
|
||||||
|
generateSignalMapper->setMapping(action, i);
|
||||||
|
connect(action, SIGNAL(triggered()), generateSignalMapper, SLOT(map()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,112 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PRIMITIVES_VIEW_H
|
||||||
|
#define PRIMITIVES_VIEW_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "primitive_item.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/ligo/primitive.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QAction>
|
||||||
|
#include <QtGui/QTreeView>
|
||||||
|
#include <QtCore/QModelIndex>
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
#include <QtCore/QSignalMapper>
|
||||||
|
#include <QtGui/QUndoStack>
|
||||||
|
#include <QtGui/QItemSelection>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
class ZoneBuilderBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
class PrimitivesTreeModel;
|
||||||
|
class WorldEditorScene;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class PrimitivesView
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class PrimitivesView : public QTreeView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PrimitivesView(QWidget *parent = 0);
|
||||||
|
~PrimitivesView();
|
||||||
|
|
||||||
|
void setUndoStack(QUndoStack *undoStack);
|
||||||
|
void setZoneBuilder(LandscapeEditor::ZoneBuilderBase *zoneBuilder);
|
||||||
|
void setWorldScene(WorldEditorScene *worldEditorScene);
|
||||||
|
virtual void setModel(PrimitivesTreeModel *model);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void loadLandscape();
|
||||||
|
void loadRootPrimitive();
|
||||||
|
void createRootPrimitive();
|
||||||
|
void selectChildren();
|
||||||
|
|
||||||
|
void save();
|
||||||
|
void saveAs();
|
||||||
|
void deletePrimitives();
|
||||||
|
void unload();
|
||||||
|
void showPrimitive();
|
||||||
|
void hidePrimitive();
|
||||||
|
void addNewPrimitiveByClass(int value);
|
||||||
|
void generatePrimitives(int value);
|
||||||
|
void openItem(int value);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void contextMenuEvent(QContextMenuEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void selectChildren(const QModelIndex &parent, QItemSelection &itemSelection);
|
||||||
|
void fillMenu_WorldEdit(QMenu *menu);
|
||||||
|
void fillMenu_Landscape(QMenu *menu);
|
||||||
|
void fillMenu_RootPrimitive(QMenu *menu, const QModelIndex &index);
|
||||||
|
void fillMenu_Primitive(QMenu *menu, const QModelIndex &index);
|
||||||
|
|
||||||
|
QString m_lastDir;
|
||||||
|
|
||||||
|
QAction *m_unloadAction;
|
||||||
|
QAction *m_saveAction;
|
||||||
|
QAction *m_saveAsAction;
|
||||||
|
QAction *m_loadLandAction;
|
||||||
|
QAction *m_loadPrimitiveAction;
|
||||||
|
QAction *m_newPrimitiveAction;
|
||||||
|
QAction *m_deleteAction;
|
||||||
|
QAction *m_selectChildrenAction;
|
||||||
|
QAction *m_helpAction;
|
||||||
|
QAction *m_showAction;
|
||||||
|
QAction *m_hideAction;
|
||||||
|
|
||||||
|
QUndoStack *m_undoStack;
|
||||||
|
WorldEditorScene *m_worldEditorScene;
|
||||||
|
LandscapeEditor::ZoneBuilderBase *m_zoneBuilder;
|
||||||
|
PrimitivesTreeModel *m_primitivesTreeModel;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
#endif // PRIMITIVES_VIEW_H
|
|
@ -0,0 +1,68 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "project_settings_dialog.h"
|
||||||
|
#include "world_editor_misc.h"
|
||||||
|
|
||||||
|
#include "../core/icore.h"
|
||||||
|
#include "../core/core_constants.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
#include <nel/ligo/ligo_config.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QSettings>
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
ProjectSettingsDialog::ProjectSettingsDialog(const QString &dataPath, QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
{
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
m_ui.pathLineEdit->setText(dataPath);
|
||||||
|
m_ui.contextComboBox->addItem("empty");
|
||||||
|
|
||||||
|
// Init the combo box
|
||||||
|
const std::vector<std::string> &contexts = Utils::ligoConfig()->getContextString();
|
||||||
|
for (uint i = 0; i < contexts.size(); i++)
|
||||||
|
m_ui.contextComboBox->addItem(QString(contexts[i].c_str()));
|
||||||
|
|
||||||
|
setFixedHeight(sizeHint().height());
|
||||||
|
connect(m_ui.selectPathButton, SIGNAL(clicked()), this, SLOT(selectPath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectSettingsDialog::~ProjectSettingsDialog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ProjectSettingsDialog::dataPath() const
|
||||||
|
{
|
||||||
|
return m_ui.pathLineEdit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectSettingsDialog::selectPath()
|
||||||
|
{
|
||||||
|
QString dataPath = QFileDialog::getExistingDirectory(this, tr("Select data path"), m_ui.pathLineEdit->text());
|
||||||
|
if (!dataPath.isEmpty())
|
||||||
|
m_ui.pathLineEdit->setText(dataPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PROJECT_SETTINGS_DIALOG_WE_H
|
||||||
|
#define PROJECT_SETTINGS_DIALOG_WE_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "ui_project_settings_dialog.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
class ProjectSettingsDialog: public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProjectSettingsDialog(const QString &dataPath, QWidget *parent = 0);
|
||||||
|
~ProjectSettingsDialog();
|
||||||
|
|
||||||
|
QString dataPath() const;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void selectPath();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Ui::ProjectSettingsDialog m_ui;
|
||||||
|
}; /* class ProjectSettingsDialog */
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
#endif // PROJECT_SETTINGS_DIALOG_WE_H
|
|
@ -0,0 +1,103 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ProjectSettingsDialog</class>
|
||||||
|
<widget class="QDialog" name="ProjectSettingsDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>419</width>
|
||||||
|
<height>93</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Project settings</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="../landscape_editor/landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Data directory:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>pathLineEdit</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="pathLineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QToolButton" name="selectPathButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Context:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>contextComboBox</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" colspan="2">
|
||||||
|
<widget class="QComboBox" name="contextComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="3">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../landscape_editor/landscape_editor.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ProjectSettingsDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>257</x>
|
||||||
|
<y>83</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>ProjectSettingsDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>325</x>
|
||||||
|
<y>83</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -0,0 +1,434 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "property_editor_widget.h"
|
||||||
|
#include "world_editor_misc.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QModelIndex>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
PropertyEditorWidget::PropertyEditorWidget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
|
m_stringManager = new QtStringPropertyManager(this);
|
||||||
|
m_boolManager = new QtBoolPropertyManager(this);
|
||||||
|
m_enumManager = new QtEnumPropertyManager(this);
|
||||||
|
m_stringArrayManager = new QtTextPropertyManager(this);
|
||||||
|
|
||||||
|
QtLineEditFactory *lineEditFactory = new QtLineEditFactory(this);
|
||||||
|
QtCheckBoxFactory *boolFactory = new QtCheckBoxFactory(this);
|
||||||
|
QtEnumEditorFactory *enumFactory = new QtEnumEditorFactory(this);
|
||||||
|
QtTextEditorFactory *textFactory = new QtTextEditorFactory(this);
|
||||||
|
|
||||||
|
m_ui.treePropertyBrowser->setFactoryForManager(m_stringManager, lineEditFactory);
|
||||||
|
m_ui.treePropertyBrowser->setFactoryForManager(m_boolManager, boolFactory);
|
||||||
|
m_ui.treePropertyBrowser->setFactoryForManager(m_enumManager, enumFactory);
|
||||||
|
m_ui.treePropertyBrowser->setFactoryForManager(m_stringArrayManager, textFactory);
|
||||||
|
|
||||||
|
m_groupManager = new QtGroupPropertyManager(this);
|
||||||
|
|
||||||
|
connect(m_stringManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(propertyChanged(QtProperty *)));
|
||||||
|
connect(m_boolManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(propertyChanged(QtProperty *)));
|
||||||
|
connect(m_enumManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(propertyChanged(QtProperty *)));
|
||||||
|
connect(m_stringArrayManager, SIGNAL(propertyChanged(QtProperty *)), this, SLOT(propertyChanged(QtProperty *)));
|
||||||
|
|
||||||
|
connect(m_boolManager, SIGNAL(resetProperty(QtProperty *)), this, SLOT(resetProperty(QtProperty *)));
|
||||||
|
connect(m_stringManager, SIGNAL(resetProperty(QtProperty *)), this, SLOT(resetProperty(QtProperty *)));
|
||||||
|
connect(m_enumManager, SIGNAL(resetProperty(QtProperty *)), this, SLOT(resetProperty(QtProperty *)));
|
||||||
|
connect(m_stringArrayManager, SIGNAL(resetProperty(QtProperty *)), this, SLOT(resetProperty(QtProperty *)));
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyEditorWidget::~PropertyEditorWidget()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertyEditorWidget::clearProperties()
|
||||||
|
{
|
||||||
|
m_ui.treePropertyBrowser->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertyEditorWidget::updateSelection(Node *node)
|
||||||
|
{
|
||||||
|
clearProperties();
|
||||||
|
|
||||||
|
if ((node == 0) || (node->type() != Node::PrimitiveNodeType))
|
||||||
|
return;
|
||||||
|
|
||||||
|
blockSignalsOfProperties(true);
|
||||||
|
|
||||||
|
// The parameter list
|
||||||
|
std::list<NLLIGO::CPrimitiveClass::CParameter> parameterList;
|
||||||
|
|
||||||
|
PrimitiveNode *primNode = static_cast<PrimitiveNode *>(node);
|
||||||
|
const NLLIGO::IPrimitive *primitive = primNode->primitive();
|
||||||
|
const NLLIGO::CPrimitiveClass *primClass = primNode->primitiveClass();
|
||||||
|
|
||||||
|
// Use the class or not ?
|
||||||
|
if (primClass)
|
||||||
|
{
|
||||||
|
// For each properties of the class
|
||||||
|
for (uint p = 0; p < primClass->Parameters.size(); p++)
|
||||||
|
{
|
||||||
|
// Is the parameter visible ?
|
||||||
|
if (primClass->Parameters[p].Visible)
|
||||||
|
{
|
||||||
|
if (primClass->Parameters[p].Name == "name")
|
||||||
|
parameterList.push_front(primClass->Parameters[p]);
|
||||||
|
else
|
||||||
|
parameterList.push_back(primClass->Parameters[p]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For each primitive property
|
||||||
|
uint numProp = primitive->getNumProperty();
|
||||||
|
for (uint p = 0; p < numProp; p++)
|
||||||
|
{
|
||||||
|
// Get the property
|
||||||
|
std::string propertyName;
|
||||||
|
const NLLIGO::IProperty *prop;
|
||||||
|
nlverify(primitive->getProperty(p, propertyName, prop));
|
||||||
|
|
||||||
|
// Add a default property
|
||||||
|
NLLIGO::CPrimitiveClass::CParameter defProp(*prop, propertyName.c_str());
|
||||||
|
|
||||||
|
if (defProp.Name == "name")
|
||||||
|
parameterList.push_front(defProp);
|
||||||
|
else
|
||||||
|
parameterList.push_back(defProp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove property class
|
||||||
|
std::list<NLLIGO::CPrimitiveClass::CParameter>::iterator ite = parameterList.begin ();
|
||||||
|
while (ite != parameterList.end ())
|
||||||
|
{
|
||||||
|
std::list<NLLIGO::CPrimitiveClass::CParameter>::iterator next = ite;
|
||||||
|
next++;
|
||||||
|
if (ite->Name == "class")
|
||||||
|
{
|
||||||
|
parameterList.erase(ite);
|
||||||
|
}
|
||||||
|
ite = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProperty *groupNode;
|
||||||
|
groupNode = m_groupManager->addProperty(QString("%1(%2)").arg(node->data(Qt::DisplayRole).toString()).arg(primClass->Name.c_str()));
|
||||||
|
m_ui.treePropertyBrowser->addProperty(groupNode);
|
||||||
|
|
||||||
|
ite = parameterList.begin();
|
||||||
|
while (ite != parameterList.end())
|
||||||
|
{
|
||||||
|
NLLIGO::CPrimitiveClass::CParameter ¶meter = (*ite);
|
||||||
|
QtProperty *prop;
|
||||||
|
NLLIGO::IProperty *ligoProperty = 0;
|
||||||
|
primitive->getPropertyByName(parameter.Name.c_str(), ligoProperty);
|
||||||
|
|
||||||
|
if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::ConstString)
|
||||||
|
prop = addConstStringProperty(ligoProperty, parameter, primitive);
|
||||||
|
else if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::String)
|
||||||
|
prop = addStringProperty(ligoProperty, parameter, primitive);
|
||||||
|
else if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::StringArray)
|
||||||
|
prop = addStringArrayProperty(ligoProperty, parameter, primitive);
|
||||||
|
else if (parameter.Type == NLLIGO::CPrimitiveClass::CParameter::ConstStringArray)
|
||||||
|
prop = addConstStringArrayProperty(ligoProperty, parameter, primitive);
|
||||||
|
else
|
||||||
|
prop = addBoolProperty(ligoProperty, parameter, primitive);
|
||||||
|
|
||||||
|
// Default value ?
|
||||||
|
if ((ligoProperty == NULL) || (ligoProperty->Default))
|
||||||
|
prop->setModified(false);
|
||||||
|
else
|
||||||
|
prop->setModified(true);
|
||||||
|
|
||||||
|
bool staticChildSelected = Utils::ligoConfig()->isStaticChild(*primitive);
|
||||||
|
if (parameter.ReadOnly || (staticChildSelected && (parameter.Name == "name")))
|
||||||
|
prop->setEnabled(false);
|
||||||
|
|
||||||
|
// File ?
|
||||||
|
if (parameter.Filename && (parameter.FileExtension.empty() || parameter.Type != NLLIGO::CPrimitiveClass::CParameter::StringArray))
|
||||||
|
{
|
||||||
|
// TODO: Create an edit box
|
||||||
|
// CHECK: only for ConstString
|
||||||
|
}
|
||||||
|
|
||||||
|
groupNode->addSubProperty(prop);
|
||||||
|
|
||||||
|
ite++;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockSignalsOfProperties(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertyEditorWidget::propertyChanged(QtProperty *property)
|
||||||
|
{
|
||||||
|
nlinfo(QString("property %1 changed").arg(property->propertyName()).toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertyEditorWidget::resetProperty(QtProperty *property)
|
||||||
|
{
|
||||||
|
nlinfo(QString("property %1 reset").arg(property->propertyName()).toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProperty *PropertyEditorWidget::addBoolProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive)
|
||||||
|
{
|
||||||
|
std::string value;
|
||||||
|
std::string name = parameter.Name.c_str();
|
||||||
|
primitive->getPropertyByName(name.c_str(), value);
|
||||||
|
QtProperty *prop = m_boolManager->addProperty(name.c_str());
|
||||||
|
// if (Default)
|
||||||
|
{
|
||||||
|
//DialogProperties->setDefaultValue (this, value);
|
||||||
|
m_boolManager->setValue(prop, bool((value=="true")?1:0));
|
||||||
|
}
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProperty *PropertyEditorWidget::addConstStringProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive)
|
||||||
|
{
|
||||||
|
std::string value;
|
||||||
|
std::string name = parameter.Name.c_str();
|
||||||
|
|
||||||
|
// Get current value
|
||||||
|
primitive->getPropertyByName(name.c_str(), value);
|
||||||
|
|
||||||
|
// Create qt property
|
||||||
|
QtProperty *prop = m_enumManager->addProperty(parameter.Name.c_str());
|
||||||
|
|
||||||
|
QStringList listEnums = getComboValues(parameter);
|
||||||
|
|
||||||
|
if (listEnums.isEmpty())
|
||||||
|
{
|
||||||
|
listEnums << QString(value.c_str()) + tr(" (WRN: Check leveldesign!)");
|
||||||
|
m_enumManager->setEnumNames(prop, listEnums);
|
||||||
|
m_enumManager->setValue(prop, 0);
|
||||||
|
prop->setEnabled(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: check this logic
|
||||||
|
if (parameter.DefaultValue.empty() || (parameter.DefaultValue[0].Name.empty()))
|
||||||
|
listEnums.prepend("");
|
||||||
|
|
||||||
|
// Fill qt property
|
||||||
|
m_enumManager->setEnumNames(prop, listEnums);
|
||||||
|
|
||||||
|
// Find index of current value
|
||||||
|
for (int i = 0; i < listEnums.size(); i++)
|
||||||
|
{
|
||||||
|
if (value == listEnums[i].toStdString())
|
||||||
|
{
|
||||||
|
m_enumManager->setValue(prop, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProperty *PropertyEditorWidget::addStringProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive)
|
||||||
|
{
|
||||||
|
std::string value;
|
||||||
|
std::string name = parameter.Name.c_str();
|
||||||
|
primitive->getPropertyByName(name.c_str(), value);
|
||||||
|
QtProperty *prop = m_stringManager->addProperty(parameter.Name.c_str());
|
||||||
|
m_stringManager->setValue(prop, QString(value.c_str()));
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProperty *PropertyEditorWidget::addStringArrayProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive)
|
||||||
|
{
|
||||||
|
std::string name = parameter.Name.c_str();
|
||||||
|
QtProperty *prop = m_stringArrayManager->addProperty(parameter.Name.c_str());
|
||||||
|
|
||||||
|
const NLLIGO::IProperty *ligoProperty;
|
||||||
|
std::vector<std::string> vectString;
|
||||||
|
|
||||||
|
if (primitive->getPropertyByName(parameter.Name.c_str (), ligoProperty))
|
||||||
|
{
|
||||||
|
const NLLIGO::CPropertyStringArray *const propStringArray = dynamic_cast<const NLLIGO::CPropertyStringArray *> (ligoProperty);
|
||||||
|
if (propStringArray)
|
||||||
|
{
|
||||||
|
const std::vector<std::string> &vectString = propStringArray->StringArray;
|
||||||
|
if (!vectString.empty())
|
||||||
|
{
|
||||||
|
std::string temp;
|
||||||
|
for (size_t i = 0; i < vectString.size(); i++)
|
||||||
|
{
|
||||||
|
temp += vectString[i];
|
||||||
|
if (i != (vectString.size() - 1))
|
||||||
|
temp += '\n';
|
||||||
|
}
|
||||||
|
m_stringArrayManager->setValue(prop, temp.c_str());
|
||||||
|
prop->setToolTip(temp.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_stringArrayManager->setValue(prop, "StringArray :(");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an "EDIT" button if the text is editable (FileExtension != "")
|
||||||
|
if (parameter.FileExtension != "")
|
||||||
|
{
|
||||||
|
// Create an edit box
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProperty *PropertyEditorWidget::addConstStringArrayProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive)
|
||||||
|
{
|
||||||
|
std::string value;
|
||||||
|
std::string name = parameter.Name.c_str();
|
||||||
|
|
||||||
|
// Get current value
|
||||||
|
primitive->getPropertyByName(name.c_str(), value);
|
||||||
|
|
||||||
|
// Create qt property
|
||||||
|
// QtProperty *prop = m_enumManager->addProperty(parameter.Name.c_str());
|
||||||
|
QtProperty *prop = m_stringArrayManager->addProperty(parameter.Name.c_str());
|
||||||
|
|
||||||
|
QStringList listEnums = getComboValues(parameter);
|
||||||
|
|
||||||
|
if (listEnums.isEmpty())
|
||||||
|
{
|
||||||
|
// listEnums << QString(value.c_str()) + tr(" (WRN: Check leveldesign!)");
|
||||||
|
// m_enumManager->setEnumNames(prop, listEnums);
|
||||||
|
// m_enumManager->setValue(prop, 0);
|
||||||
|
prop->setEnabled(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fill qt property
|
||||||
|
m_enumManager->setEnumNames(prop, listEnums);
|
||||||
|
|
||||||
|
// Find index of current value
|
||||||
|
//for (int i = 0; i < listEnums.size(); i++)
|
||||||
|
//{
|
||||||
|
// if (value == listEnums[i].toStdString())
|
||||||
|
// {
|
||||||
|
// m_enumManager->setValue(prop, i);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
const NLLIGO::IProperty *ligoProperty;
|
||||||
|
std::vector<std::string> vectString;
|
||||||
|
|
||||||
|
if (primitive->getPropertyByName (parameter.Name.c_str(), ligoProperty))
|
||||||
|
{
|
||||||
|
const NLLIGO::CPropertyStringArray *const propStringArray = dynamic_cast<const NLLIGO::CPropertyStringArray *> (ligoProperty);
|
||||||
|
if (propStringArray)
|
||||||
|
{
|
||||||
|
const std::vector<std::string> &vectString = propStringArray->StringArray;
|
||||||
|
if (!vectString.empty())
|
||||||
|
{
|
||||||
|
std::string temp;
|
||||||
|
for (size_t i = 0; i < vectString.size(); i++)
|
||||||
|
{
|
||||||
|
temp += vectString[i];
|
||||||
|
if (i != (vectString.size() - 1))
|
||||||
|
temp += '\n';
|
||||||
|
}
|
||||||
|
m_stringArrayManager->setValue(prop, temp.c_str());
|
||||||
|
prop->setToolTip(temp.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_stringArrayManager->setValue(prop, "StringArray :(");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_enumManager->setValue(prop, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList PropertyEditorWidget::getComboValues(const NLLIGO::CPrimitiveClass::CParameter ¶meter)
|
||||||
|
{
|
||||||
|
// TODO: get context value from dialog
|
||||||
|
std::string context("jungle");
|
||||||
|
std::string defaultContext("default");
|
||||||
|
|
||||||
|
std::vector<std::string> listContext;
|
||||||
|
|
||||||
|
if (context != defaultContext)
|
||||||
|
listContext.push_back(context);
|
||||||
|
listContext.push_back(defaultContext);
|
||||||
|
|
||||||
|
QStringList listEnums;
|
||||||
|
|
||||||
|
// Correct fill properties with *both* contexts if the current context is not default and is valid.
|
||||||
|
for (size_t j = 0; j < listContext.size(); j++)
|
||||||
|
{
|
||||||
|
std::map<std::string, NLLIGO::CPrimitiveClass::CParameter::CConstStringValue>::const_iterator ite = parameter.ComboValues.find(listContext[j].c_str());
|
||||||
|
|
||||||
|
if (ite != parameter.ComboValues.end())
|
||||||
|
{
|
||||||
|
std::vector<std::string> pathList;
|
||||||
|
|
||||||
|
// Fill pathList
|
||||||
|
ite->second.appendFilePath(pathList);
|
||||||
|
|
||||||
|
if (parameter.SortEntries)
|
||||||
|
std::sort(pathList.begin(), pathList.end());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < pathList.size(); ++i)
|
||||||
|
listEnums.append(pathList[i].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return listEnums;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropertyEditorWidget::blockSignalsOfProperties(bool block)
|
||||||
|
{
|
||||||
|
m_stringManager->blockSignals(block);
|
||||||
|
m_boolManager->blockSignals(block);
|
||||||
|
m_enumManager->blockSignals(block);
|
||||||
|
m_stringArrayManager->blockSignals(block);
|
||||||
|
}
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,92 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PROPERTY_EDITOR_WIDGET_H
|
||||||
|
#define PROPERTY_EDITOR_WIDGET_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "ui_property_editor_widget.h"
|
||||||
|
#include "primitives_model.h"
|
||||||
|
#include "primitive_item.h"
|
||||||
|
|
||||||
|
|
||||||
|
// 3rdparty
|
||||||
|
#include "qtvariantproperty.h"
|
||||||
|
#include "qtpropertymanager.h"
|
||||||
|
#include "qteditorfactory.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
@class PropertyEditorWidget
|
||||||
|
@brief PropertyEditorWidget
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class PropertyEditorWidget: public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PropertyEditorWidget(QWidget *parent = 0);
|
||||||
|
~PropertyEditorWidget();
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void clearProperties();
|
||||||
|
|
||||||
|
/// Update of selections
|
||||||
|
void updateSelection(Node *node);
|
||||||
|
|
||||||
|
void propertyChanged(QtProperty *property);
|
||||||
|
void resetProperty(QtProperty *property);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QtProperty *addBoolProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive);
|
||||||
|
QtProperty *addConstStringProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive);
|
||||||
|
QtProperty *addStringProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive);
|
||||||
|
QtProperty *addStringArrayProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive);
|
||||||
|
QtProperty *addConstStringArrayProperty(const NLLIGO::IProperty *property,
|
||||||
|
const NLLIGO::CPrimitiveClass::CParameter ¶meter,
|
||||||
|
const NLLIGO::IPrimitive *primitive);
|
||||||
|
|
||||||
|
QStringList getComboValues(const NLLIGO::CPrimitiveClass::CParameter ¶meter);
|
||||||
|
|
||||||
|
void blockSignalsOfProperties(bool block);
|
||||||
|
|
||||||
|
QtBoolPropertyManager *m_boolManager;
|
||||||
|
QtStringPropertyManager *m_stringManager;
|
||||||
|
QtEnumPropertyManager *m_enumManager;
|
||||||
|
QtGroupPropertyManager *m_groupManager;
|
||||||
|
QtTextPropertyManager *m_stringArrayManager;
|
||||||
|
|
||||||
|
Ui::PropertyEditorWidget m_ui;
|
||||||
|
}; /* PropertyEditorWidget */
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
#endif // PROPERTY_EDITOR_WIDGET_H
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>PropertyEditorWidget</class>
|
||||||
|
<widget class="QWidget" name="PropertyEditorWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>183</width>
|
||||||
|
<height>128</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<property name="margin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QtTreePropertyBrowser" name="treePropertyBrowser" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>QtTreePropertyBrowser</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>qttreepropertybrowser.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources>
|
||||||
|
<include location="../core/core.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>icons/ic_nel_select.png</file>
|
||||||
|
<file>icons/ic_nel_scale.png</file>
|
||||||
|
<file>icons/ic_nel_rotate.png</file>
|
||||||
|
<file>icons/ic_nel_move.png</file>
|
||||||
|
<file>icons/ic_nel_turn.png</file>
|
||||||
|
<file>icons/ic_nel_world_editor.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
|
@ -0,0 +1,791 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_actions.h"
|
||||||
|
#include "world_editor_constants.h"
|
||||||
|
#include "world_editor_misc.h"
|
||||||
|
#include "primitive_item.h"
|
||||||
|
#include "world_editor_scene.h"
|
||||||
|
#include "world_editor_scene_item.h"
|
||||||
|
|
||||||
|
// Lanscape Editor plugin
|
||||||
|
#include "../landscape_editor/builder_zone_base.h"
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
#include <nel/misc/path.h>
|
||||||
|
#include <nel/ligo/primitive_utils.h>
|
||||||
|
#include <nel/ligo/primitive.h>
|
||||||
|
#include <nel/ligo/primitive_class.h>
|
||||||
|
#include <nel/misc/file.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QGraphicsView>
|
||||||
|
#include <QPersistentModelIndex>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
QGraphicsItem *getGraphicsItem(Node *node)
|
||||||
|
{
|
||||||
|
QGraphicsItem *result = 0;
|
||||||
|
if (node->type() == Node::PrimitiveNodeType)
|
||||||
|
{
|
||||||
|
PrimitiveNode *primitiveNode = static_cast<PrimitiveNode *>(node);
|
||||||
|
if (primitiveNode != 0)
|
||||||
|
{
|
||||||
|
switch (primitiveNode->primitiveClass()->Type)
|
||||||
|
{
|
||||||
|
case NLLIGO::CPrimitiveClass::Point:
|
||||||
|
case NLLIGO::CPrimitiveClass::Path:
|
||||||
|
case NLLIGO::CPrimitiveClass::Zone:
|
||||||
|
{
|
||||||
|
result = qvariant_cast<AbstractWorldItem *>(primitiveNode->data(Constants::GRAPHICS_DATA_QT4_2D));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene)
|
||||||
|
{
|
||||||
|
PrimitiveNode *node = static_cast<PrimitiveNode *>(primIndex.internalPointer());
|
||||||
|
|
||||||
|
float cellSize = Utils::ligoConfig()->CellSize;
|
||||||
|
if (node != 0)
|
||||||
|
{
|
||||||
|
NLLIGO::IPrimitive *primitive = node->primitive();
|
||||||
|
NLLIGO::CPrimVector *vec = 0;
|
||||||
|
AbstractWorldItem *item = 0;
|
||||||
|
|
||||||
|
// Draw arrow ?
|
||||||
|
bool showArrow = node->primitiveClass()->ShowArrow;
|
||||||
|
|
||||||
|
switch (node->primitiveClass()->Type)
|
||||||
|
{
|
||||||
|
case NLLIGO::CPrimitiveClass::Point:
|
||||||
|
{
|
||||||
|
vec = primitive->getPrimVector();
|
||||||
|
NLLIGO::CPrimPoint *primPoint = static_cast<NLLIGO::CPrimPoint *>(primitive);
|
||||||
|
|
||||||
|
// Have a radius ?
|
||||||
|
std::string strRadius;
|
||||||
|
qreal radius = 0;
|
||||||
|
if (primitive->getPropertyByName ("radius", strRadius))
|
||||||
|
radius = atof(strRadius.c_str());
|
||||||
|
qreal angle = ((2 * NLMISC::Pi - primPoint->Angle) * 180 / NLMISC::Pi);
|
||||||
|
item = scene->addWorldItemPoint(QPointF(vec->x, -vec->y + cellSize),
|
||||||
|
angle, radius, showArrow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NLLIGO::CPrimitiveClass::Path:
|
||||||
|
{
|
||||||
|
QPolygonF polygon;
|
||||||
|
vec = primitive->getPrimVector();
|
||||||
|
int sizeVec = primitive->getNumVector();
|
||||||
|
for (int i = 0; i < sizeVec; ++i)
|
||||||
|
{
|
||||||
|
polygon << QPointF(vec->x, -vec->y + cellSize);
|
||||||
|
++vec;
|
||||||
|
}
|
||||||
|
item = scene->addWorldItemPath(polygon, showArrow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NLLIGO::CPrimitiveClass::Zone:
|
||||||
|
{
|
||||||
|
QPolygonF polygon;
|
||||||
|
vec = primitive->getPrimVector();
|
||||||
|
int sizeVec = primitive->getNumVector();
|
||||||
|
for (int i = 0; i < sizeVec; ++i)
|
||||||
|
{
|
||||||
|
polygon << QPointF(vec->x, cellSize - vec->y);
|
||||||
|
++vec;
|
||||||
|
}
|
||||||
|
item = scene->addWorldItemZone(polygon);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item != 0)
|
||||||
|
{
|
||||||
|
// Get color from world_editor_classes.xml
|
||||||
|
NLMISC::CRGBA color = Utils::ligoConfig()->getPrimitiveColor(*primitive);
|
||||||
|
primitive->getPropertyByName ("Color", color);
|
||||||
|
item->setColor(QColor(color.R, color.G, color.B));
|
||||||
|
|
||||||
|
QVariant variantNode;
|
||||||
|
variantNode.setValue<Node *>(node);
|
||||||
|
item->setData(Constants::WORLD_EDITOR_NODE, variantNode);
|
||||||
|
|
||||||
|
QVariant graphicsData;
|
||||||
|
graphicsData.setValue<AbstractWorldItem *>(item);
|
||||||
|
node->setData(Constants::GRAPHICS_DATA_QT4_2D, graphicsData);
|
||||||
|
|
||||||
|
QVariant persistenVariant;
|
||||||
|
QPersistentModelIndex *persistentIndex = new QPersistentModelIndex(primIndex);
|
||||||
|
persistenVariant.setValue<QPersistentModelIndex *>(persistentIndex);
|
||||||
|
item->setData(Constants::NODE_PERISTENT_INDEX, persistenVariant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = model->rowCount(primIndex);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
addNewGraphicsItems(primIndex.child(i, 0), model, scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene)
|
||||||
|
{
|
||||||
|
Node *node = static_cast<Node *>(primIndex.internalPointer());
|
||||||
|
|
||||||
|
if (node != 0)
|
||||||
|
{
|
||||||
|
QGraphicsItem *item = getGraphicsItem(node);
|
||||||
|
if (item != 0)
|
||||||
|
{
|
||||||
|
delete qvariant_cast<QPersistentModelIndex *>(item->data(Constants::NODE_PERISTENT_INDEX));
|
||||||
|
scene->removeWorldItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = model->rowCount(primIndex);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
removeGraphicsItems(primIndex.child(i, 0), model, scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QPolygonF> polygonsFromItems(const QList<QGraphicsItem *> &items)
|
||||||
|
{
|
||||||
|
QList<QPolygonF> result;
|
||||||
|
Q_FOREACH(QGraphicsItem *item, items)
|
||||||
|
{
|
||||||
|
AbstractWorldItem *worldItem = qgraphicsitem_cast<AbstractWorldItem *>(item);
|
||||||
|
result.push_back(worldItem->polygon());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateWorldCommand::CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_fileName(fileName),
|
||||||
|
m_model(model)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Create new world"));
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateWorldCommand::~CreateWorldCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateWorldCommand::undo()
|
||||||
|
{
|
||||||
|
m_model->deleteWorldEditNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateWorldCommand::redo()
|
||||||
|
{
|
||||||
|
m_model->createWorldEditNode(m_fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadLandscapeCommand::LoadLandscapeCommand(const QString &fileName, PrimitivesTreeModel *model,
|
||||||
|
LandscapeEditor::ZoneBuilderBase *zoneBuilder, QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_id(-1),
|
||||||
|
m_fileName(fileName),
|
||||||
|
m_model(model),
|
||||||
|
m_zoneBuilder(zoneBuilder)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Load land file"));
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadLandscapeCommand::~LoadLandscapeCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadLandscapeCommand::undo()
|
||||||
|
{
|
||||||
|
m_zoneBuilder->deleteZoneRegion(m_id);
|
||||||
|
m_model->deleteNode(landIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadLandscapeCommand::redo()
|
||||||
|
{
|
||||||
|
if (m_id == -1)
|
||||||
|
m_id = m_zoneBuilder->loadZoneRegion(m_fileName);
|
||||||
|
else
|
||||||
|
m_zoneBuilder->loadZoneRegion(m_fileName, m_id);
|
||||||
|
|
||||||
|
landIndex = m_model->createLandscapeNode(m_fileName, m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UnloadLandscapeCommand::UnloadLandscapeCommand(const QModelIndex &index, PrimitivesTreeModel *model,
|
||||||
|
LandscapeEditor::ZoneBuilderBase *zoneBuilder, QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_model(model),
|
||||||
|
m_zoneBuilder(zoneBuilder)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Unload land file"));
|
||||||
|
m_path = m_model->pathFromIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnloadLandscapeCommand::~UnloadLandscapeCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadLandscapeCommand::undo()
|
||||||
|
{
|
||||||
|
m_zoneBuilder->loadZoneRegion(m_fileName, m_id);
|
||||||
|
|
||||||
|
m_model->createLandscapeNode(m_fileName, m_id, m_path.back().first);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadLandscapeCommand::redo()
|
||||||
|
{
|
||||||
|
QModelIndex index = m_model->pathToIndex(m_path);
|
||||||
|
LandscapeNode *node = static_cast<LandscapeNode *>(index.internalPointer());
|
||||||
|
|
||||||
|
m_id = node->id();
|
||||||
|
m_fileName = node->fileName();
|
||||||
|
|
||||||
|
m_zoneBuilder->deleteZoneRegion(m_id);
|
||||||
|
m_model->deleteNode(m_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateRootPrimitiveCommand::CreateRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_fileName(fileName),
|
||||||
|
m_model(model)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Create new primitive"));
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateRootPrimitiveCommand::~CreateRootPrimitiveCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateRootPrimitiveCommand::undo()
|
||||||
|
{
|
||||||
|
QModelIndex index = m_model->pathToIndex(m_rootPrimIndex);
|
||||||
|
|
||||||
|
RootPrimitiveNode *node = static_cast<RootPrimitiveNode *>(index.internalPointer());
|
||||||
|
|
||||||
|
delete node->primitives();
|
||||||
|
|
||||||
|
m_model->deleteNode(m_rootPrimIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateRootPrimitiveCommand::redo()
|
||||||
|
{
|
||||||
|
NLLIGO::CPrimitives *newRootPrim = new NLLIGO::CPrimitives();
|
||||||
|
m_rootPrimIndex = m_model->createRootPrimitiveNode("", newRootPrim);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LoadRootPrimitiveCommand::LoadRootPrimitiveCommand(const QString &fileName, WorldEditorScene *scene,
|
||||||
|
PrimitivesTreeModel *model, QTreeView *view, QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_fileName(fileName),
|
||||||
|
m_scene(scene),
|
||||||
|
m_model(model),
|
||||||
|
m_view(view)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Load primitive file"));
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadRootPrimitiveCommand::~LoadRootPrimitiveCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadRootPrimitiveCommand::undo()
|
||||||
|
{
|
||||||
|
// Disable edit points mode
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
|
||||||
|
m_view->selectionModel()->clearSelection();
|
||||||
|
|
||||||
|
QModelIndex index = m_model->pathToIndex(m_rootPrimIndex);
|
||||||
|
|
||||||
|
removeGraphicsItems(index, m_model, m_scene);
|
||||||
|
|
||||||
|
RootPrimitiveNode *node = static_cast<RootPrimitiveNode *>(index.internalPointer());
|
||||||
|
|
||||||
|
delete node->primitives();
|
||||||
|
|
||||||
|
m_model->deleteNode(m_rootPrimIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadRootPrimitiveCommand::redo()
|
||||||
|
{
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
|
||||||
|
NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives();
|
||||||
|
|
||||||
|
// set the primitive context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = primitives;
|
||||||
|
|
||||||
|
NLLIGO::loadXmlPrimitiveFile(*primitives, m_fileName.toStdString(), *Utils::ligoConfig());
|
||||||
|
|
||||||
|
// unset the context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize default values
|
||||||
|
Utils::recursiveUpdateDefaultValues(primitives->RootNode);
|
||||||
|
|
||||||
|
// Check property types
|
||||||
|
if (Utils::recursiveUpdateDefaultValues(primitives->RootNode))
|
||||||
|
{
|
||||||
|
nlwarning("In file (%s) : Some primitives have been modified to initialise their default values\nor to change their properties type.", m_fileName.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rootPrimIndex = m_model->createRootPrimitiveNode(m_fileName, primitives);
|
||||||
|
|
||||||
|
addNewGraphicsItems(m_model->pathToIndex(m_rootPrimIndex), m_model, m_scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UnloadRootPrimitiveCommand::UnloadRootPrimitiveCommand(const QModelIndex &index, WorldEditorScene *scene,
|
||||||
|
PrimitivesTreeModel *model, QTreeView *view, QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_scene(scene),
|
||||||
|
m_model(model),
|
||||||
|
m_view(view)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Unload primitive file"));
|
||||||
|
m_path = m_model->pathFromIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnloadRootPrimitiveCommand::~UnloadRootPrimitiveCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadRootPrimitiveCommand::undo()
|
||||||
|
{
|
||||||
|
// Disable edit points mode
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
|
||||||
|
m_path = m_model->createRootPrimitiveNode(m_fileName, m_primitives, m_path.back().first);
|
||||||
|
|
||||||
|
addNewGraphicsItems(m_model->pathToIndex(m_path), m_model, m_scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadRootPrimitiveCommand::redo()
|
||||||
|
{
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
|
||||||
|
m_view->selectionModel()->clearSelection();
|
||||||
|
QModelIndex index = m_model->pathToIndex(m_path);
|
||||||
|
RootPrimitiveNode *node = static_cast<RootPrimitiveNode *>(index.internalPointer());
|
||||||
|
m_fileName = node->fileName();
|
||||||
|
m_primitives = node->primitives();
|
||||||
|
|
||||||
|
removeGraphicsItems(index, m_model, m_scene);
|
||||||
|
|
||||||
|
m_model->deleteNode(m_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddPrimitiveByClassCommand::AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex,
|
||||||
|
WorldEditorScene *scene, PrimitivesTreeModel *model, QTreeView *view, QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_className(className),
|
||||||
|
m_parentIndex(parentIndex),
|
||||||
|
m_scene(scene),
|
||||||
|
m_model(model),
|
||||||
|
m_view(view)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Add %1").arg(m_className));
|
||||||
|
|
||||||
|
QGraphicsView *graphicsView = m_scene->views().first();
|
||||||
|
|
||||||
|
// TODO: returns incorrect position when zoom in
|
||||||
|
QRectF visibleArea = graphicsView->mapToScene(view->rect()).boundingRect();
|
||||||
|
m_delta = visibleArea.height() / 10.0;
|
||||||
|
m_initPos = visibleArea.center();
|
||||||
|
}
|
||||||
|
|
||||||
|
AddPrimitiveByClassCommand::~AddPrimitiveByClassCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddPrimitiveByClassCommand::undo()
|
||||||
|
{
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
|
||||||
|
m_view->selectionModel()->clearSelection();
|
||||||
|
|
||||||
|
QModelIndex index = m_model->pathToIndex(m_newPrimIndex);
|
||||||
|
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
|
||||||
|
|
||||||
|
// set the primitive context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = node->rootPrimitiveNode()->primitives();
|
||||||
|
|
||||||
|
removeGraphicsItems(index, m_model, m_scene);
|
||||||
|
|
||||||
|
Utils::deletePrimitive(node->primitive());
|
||||||
|
|
||||||
|
// unset the context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
|
||||||
|
|
||||||
|
m_model->deleteNode(m_newPrimIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddPrimitiveByClassCommand::redo()
|
||||||
|
{
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
|
||||||
|
QModelIndex parentIndex = m_model->pathToIndex(m_parentIndex);
|
||||||
|
PrimitiveNode *parentNode = static_cast<PrimitiveNode *>(parentIndex.internalPointer());
|
||||||
|
const NLLIGO::CPrimitiveClass *primClass = parentNode->primitiveClass();
|
||||||
|
|
||||||
|
int id = 0;
|
||||||
|
while (primClass->DynamicChildren[id].ClassName != m_className.toStdString())
|
||||||
|
++id;
|
||||||
|
|
||||||
|
// set the primitive context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = parentNode->rootPrimitiveNode()->primitives();
|
||||||
|
|
||||||
|
QString namePrimititve = QString("%1_%2").arg(m_className).arg(parentNode->childCount());
|
||||||
|
NLLIGO::IPrimitive *newPrimitive = Utils::createPrimitive(m_className.toStdString().c_str(), namePrimititve.toStdString().c_str(),
|
||||||
|
NLMISC::CVector(m_initPos.x(), -m_initPos.y(), 0.0), m_delta, primClass->DynamicChildren[id].Parameters, parentNode->primitive());
|
||||||
|
|
||||||
|
// unset the context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
|
||||||
|
|
||||||
|
m_newPrimIndex = m_model->createPrimitiveNode(newPrimitive, m_parentIndex);
|
||||||
|
|
||||||
|
addNewGraphicsItems(m_model->pathToIndex(m_newPrimIndex), m_model, m_scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeletePrimitiveCommand::DeletePrimitiveCommand(const QModelIndex &index, PrimitivesTreeModel *model,
|
||||||
|
WorldEditorScene *scene, QTreeView *view, QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_scene(scene),
|
||||||
|
m_model(model),
|
||||||
|
m_view(view)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Delete primitive"));
|
||||||
|
|
||||||
|
// Save path to primitive
|
||||||
|
m_path = m_model->pathFromIndex(index);
|
||||||
|
m_parentPath = m_model->pathFromIndex(index.parent());
|
||||||
|
|
||||||
|
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
|
||||||
|
|
||||||
|
NLLIGO::IPrimitive *primitive = node->primitive();
|
||||||
|
|
||||||
|
// Backup primitive
|
||||||
|
m_oldPrimitive = primitive->copy();
|
||||||
|
|
||||||
|
// Backup position primitive
|
||||||
|
primitive->getParent()->getChildId(m_posPrimitive, primitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeletePrimitiveCommand::~DeletePrimitiveCommand()
|
||||||
|
{
|
||||||
|
delete m_oldPrimitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeletePrimitiveCommand::undo()
|
||||||
|
{
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
m_view->selectionModel()->clearSelection();
|
||||||
|
|
||||||
|
QModelIndex parentIndex = m_model->pathToIndex(m_parentPath);
|
||||||
|
PrimitiveNode *parentNode = static_cast<PrimitiveNode *>(parentIndex.internalPointer());
|
||||||
|
|
||||||
|
// set the primitive context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = parentNode->rootPrimitiveNode()->primitives();
|
||||||
|
|
||||||
|
NLLIGO::IPrimitive *newPrimitive = m_oldPrimitive->copy();
|
||||||
|
if (!parentNode->primitive()->insertChild(newPrimitive, m_posPrimitive))
|
||||||
|
nlerror("Primitive can't insert, m_posPrimitive is not a valid.");
|
||||||
|
|
||||||
|
// Insert primitive node in tree model
|
||||||
|
Path newPath = m_model->createPrimitiveNode(newPrimitive, m_parentPath, m_path.back().first);
|
||||||
|
|
||||||
|
// Scan graphics model
|
||||||
|
addNewGraphicsItems(m_model->pathToIndex(newPath), m_model, m_scene);
|
||||||
|
|
||||||
|
// unset the context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeletePrimitiveCommand::redo()
|
||||||
|
{
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
m_view->selectionModel()->clearSelection();
|
||||||
|
|
||||||
|
QModelIndex index = m_model->pathToIndex(m_path);
|
||||||
|
PrimitiveNode *node = static_cast<PrimitiveNode *>(index.internalPointer());
|
||||||
|
NLLIGO::IPrimitive *primitive = node->primitive();
|
||||||
|
|
||||||
|
// Removes all graphics items
|
||||||
|
removeGraphicsItems(index, m_model, m_scene);
|
||||||
|
|
||||||
|
// set the primitive context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = node->rootPrimitiveNode()->primitives();
|
||||||
|
|
||||||
|
// Delete primitive
|
||||||
|
Utils::deletePrimitive(primitive);
|
||||||
|
|
||||||
|
// unset the context
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
|
||||||
|
|
||||||
|
// Remove primitive from tree model
|
||||||
|
m_model->deleteNode(m_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractWorldItemCommand::AbstractWorldItemCommand(const QList<QGraphicsItem *> &items,
|
||||||
|
WorldEditorScene *scene,
|
||||||
|
PrimitivesTreeModel *model,
|
||||||
|
QUndoCommand *parent)
|
||||||
|
: QUndoCommand(parent),
|
||||||
|
m_listPaths(graphicsItemsToPaths(items, model)),
|
||||||
|
m_model(model),
|
||||||
|
m_scene(scene),
|
||||||
|
m_firstRun(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractWorldItemCommand::~AbstractWorldItemCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractWorldItemCommand::undo()
|
||||||
|
{
|
||||||
|
bool pointsMode = m_scene->isEnabledEditPoints();
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
for (int i = 0; i < m_listPaths.count(); ++i)
|
||||||
|
{
|
||||||
|
Node *node = m_model->pathToNode(m_listPaths.at(i));
|
||||||
|
AbstractWorldItem *item = qvariant_cast<AbstractWorldItem *>(node->data(Constants::GRAPHICS_DATA_QT4_2D));
|
||||||
|
undoChangeItem(i, item);
|
||||||
|
updatePrimitiveData(item);
|
||||||
|
}
|
||||||
|
m_scene->setEnabledEditPoints(pointsMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractWorldItemCommand::redo()
|
||||||
|
{
|
||||||
|
if (!m_firstRun)
|
||||||
|
{
|
||||||
|
bool pointsMode = m_scene->isEnabledEditPoints();
|
||||||
|
m_scene->setEnabledEditPoints(false);
|
||||||
|
for (int i = 0; i < m_listPaths.count(); ++i)
|
||||||
|
{
|
||||||
|
Node *node = m_model->pathToNode(m_listPaths.at(i));
|
||||||
|
AbstractWorldItem *item = qvariant_cast<AbstractWorldItem *>(node->data(Constants::GRAPHICS_DATA_QT4_2D));
|
||||||
|
redoChangeItem(i, item);
|
||||||
|
updatePrimitiveData(item);
|
||||||
|
}
|
||||||
|
m_scene->setEnabledEditPoints(pointsMode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_listPaths.count(); ++i)
|
||||||
|
{
|
||||||
|
Node *node = m_model->pathToNode(m_listPaths.at(i));
|
||||||
|
AbstractWorldItem *item = qvariant_cast<AbstractWorldItem *>(node->data(Constants::GRAPHICS_DATA_QT4_2D));
|
||||||
|
updatePrimitiveData(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_firstRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractWorldItemCommand::updatePrimitiveData(AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
float cellSize = Utils::ligoConfig()->CellSize;
|
||||||
|
Node *node = qvariant_cast<Node *>(item->data(Constants::WORLD_EDITOR_NODE));
|
||||||
|
PrimitiveNode *primitiveNode = static_cast<PrimitiveNode *>(node);
|
||||||
|
if (primitiveNode != 0)
|
||||||
|
{
|
||||||
|
NLLIGO::IPrimitive *primitive = primitiveNode->primitive();
|
||||||
|
|
||||||
|
std::vector<NLLIGO::CPrimVector> vPoints;
|
||||||
|
QPolygonF polygon = item->polygon();
|
||||||
|
polygon.translate(item->pos());
|
||||||
|
|
||||||
|
for (int i = 0; i < polygon.size(); ++i)
|
||||||
|
{
|
||||||
|
NLMISC::CVector vec(polygon.at(i).x(), cellSize - polygon.at(i).y(), 0.0);
|
||||||
|
vPoints.push_back(NLLIGO::CPrimVector(vec));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (primitiveNode->primitiveClass()->Type)
|
||||||
|
{
|
||||||
|
case NLLIGO::CPrimitiveClass::Point:
|
||||||
|
{
|
||||||
|
qreal angle = static_cast<WorldItemPoint *>(item)->angle();
|
||||||
|
angle = 2 * NLMISC::Pi - (angle * NLMISC::Pi / 180.0);
|
||||||
|
NLLIGO::CPrimPoint *point = static_cast<NLLIGO::CPrimPoint *>(primitive);
|
||||||
|
point->Point = vPoints.front();
|
||||||
|
point->Angle = angle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NLLIGO::CPrimitiveClass::Path:
|
||||||
|
{
|
||||||
|
NLLIGO::CPrimPath *path = static_cast<NLLIGO::CPrimPath *>(primitive);
|
||||||
|
path->VPoints = vPoints;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NLLIGO::CPrimitiveClass::Zone:
|
||||||
|
{
|
||||||
|
NLLIGO::CPrimZone *zone = static_cast<NLLIGO::CPrimZone *>(primitive);
|
||||||
|
zone->VPoints = vPoints;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Path> AbstractWorldItemCommand::graphicsItemsToPaths(const QList<QGraphicsItem *> &items, PrimitivesTreeModel *model)
|
||||||
|
{
|
||||||
|
QList<Path> result;
|
||||||
|
Q_FOREACH(QGraphicsItem *item, items)
|
||||||
|
{
|
||||||
|
Node *node = qvariant_cast<Node *>(item->data(Constants::WORLD_EDITOR_NODE));
|
||||||
|
result.push_back(model->pathFromNode(node));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveWorldItemsCommand::MoveWorldItemsCommand(const QList<QGraphicsItem *> &items, const QPointF &offset,
|
||||||
|
WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent)
|
||||||
|
: AbstractWorldItemCommand(items, scene, model, parent),
|
||||||
|
m_offset(offset)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Move item(s)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveWorldItemsCommand::~MoveWorldItemsCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
item->moveBy(-m_offset.x(), -m_offset.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
item->moveBy(m_offset.x(), m_offset.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
RotateWorldItemsCommand::RotateWorldItemsCommand(const QList<QGraphicsItem *> &items, const qreal angle,
|
||||||
|
const QPointF &pivot, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent)
|
||||||
|
: AbstractWorldItemCommand(items, scene, model, parent),
|
||||||
|
m_angle(angle),
|
||||||
|
m_pivot(pivot)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Rotate item(s)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
RotateWorldItemsCommand::~RotateWorldItemsCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotateWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
item->rotateOn(m_pivot, -m_angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RotateWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
item->rotateOn(m_pivot, m_angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScaleWorldItemsCommand::ScaleWorldItemsCommand(const QList<QGraphicsItem *> &items, const QPointF &factor,
|
||||||
|
const QPointF &pivot, WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent)
|
||||||
|
: AbstractWorldItemCommand(items, scene, model, parent),
|
||||||
|
m_factor(factor),
|
||||||
|
m_pivot(pivot)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Scale item(s)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ScaleWorldItemsCommand::~ScaleWorldItemsCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
QPointF m_invertFactor(1 / m_factor.x(), 1 / m_factor.y());
|
||||||
|
item->scaleOn(m_pivot, m_invertFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
item->scaleOn(m_pivot, m_factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
TurnWorldItemsCommand::TurnWorldItemsCommand(const QList<QGraphicsItem *> &items, const qreal angle,
|
||||||
|
WorldEditorScene *scene, PrimitivesTreeModel *model, QUndoCommand *parent)
|
||||||
|
: AbstractWorldItemCommand(items, scene, model, parent),
|
||||||
|
m_angle(angle)
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Turn item(s)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TurnWorldItemsCommand::~TurnWorldItemsCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TurnWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
item->turnOn(-m_angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TurnWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
item->turnOn(m_angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeWorldItemsCommand::ShapeWorldItemsCommand(const QList<QGraphicsItem *> &items, const QList<QPolygonF> &polygons,
|
||||||
|
WorldEditorScene *scene, PrimitivesTreeModel *model,
|
||||||
|
QUndoCommand *parent)
|
||||||
|
: AbstractWorldItemCommand(items, scene, model, parent),
|
||||||
|
m_redoPolygons(polygons),
|
||||||
|
m_undoPolygons(polygonsFromItems(items))
|
||||||
|
{
|
||||||
|
setText(QObject::tr("Change shape"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeWorldItemsCommand::~ShapeWorldItemsCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShapeWorldItemsCommand::undoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
item->setPolygon(m_redoPolygons.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShapeWorldItemsCommand::redoChangeItem(int i, AbstractWorldItem *item)
|
||||||
|
{
|
||||||
|
item->setPolygon(m_undoPolygons.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,388 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef WORLD_EDITOR_ACTIONS_H
|
||||||
|
#define WORLD_EDITOR_ACTIONS_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "primitives_model.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QUndoCommand>
|
||||||
|
#include <QtGui/QGraphicsScene>
|
||||||
|
#include <QtGui/QTreeView>
|
||||||
|
#include <QtGui/QGraphicsItem>
|
||||||
|
#include <QPersistentModelIndex>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
class ZoneBuilderBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
class WorldEditorScene;
|
||||||
|
class AbstractWorldItem;
|
||||||
|
|
||||||
|
// Auxiliary operations
|
||||||
|
|
||||||
|
// Return QGraphicsItem if node contains it
|
||||||
|
QGraphicsItem *getGraphicsItem(Node *node);
|
||||||
|
|
||||||
|
// Scan primitives model for create/add necessary QGraphicsItems
|
||||||
|
void addNewGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene);
|
||||||
|
|
||||||
|
// Recursive scan primitives model for delete Graphics Items
|
||||||
|
void removeGraphicsItems(const QModelIndex &primIndex, PrimitivesTreeModel *model, WorldEditorScene *scene);
|
||||||
|
|
||||||
|
QList<QPolygonF> polygonsFromItems(const QList<QGraphicsItem *> &items);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class CreateWorldCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class CreateWorldCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CreateWorldCommand(const QString &fileName, PrimitivesTreeModel *model, QUndoCommand *parent = 0);
|
||||||
|
virtual ~CreateWorldCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
private:
|
||||||
|
|
||||||
|
const QString m_fileName;
|
||||||
|
PrimitivesTreeModel *const m_model;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class LoadLandscapeCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class LoadLandscapeCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LoadLandscapeCommand(const QString &fileName, PrimitivesTreeModel *model,
|
||||||
|
LandscapeEditor::ZoneBuilderBase *zoneBuilder, QUndoCommand *parent = 0);
|
||||||
|
virtual ~LoadLandscapeCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
private:
|
||||||
|
|
||||||
|
Path landIndex;
|
||||||
|
int m_id;
|
||||||
|
const QString m_fileName;
|
||||||
|
PrimitivesTreeModel *const m_model;
|
||||||
|
LandscapeEditor::ZoneBuilderBase *const m_zoneBuilder;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class UnloadLandscapeCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class UnloadLandscapeCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UnloadLandscapeCommand(const QModelIndex &index, PrimitivesTreeModel *model,
|
||||||
|
LandscapeEditor::ZoneBuilderBase *zoneBuilder, QUndoCommand *parent = 0);
|
||||||
|
virtual ~UnloadLandscapeCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
private:
|
||||||
|
|
||||||
|
Path m_path;
|
||||||
|
int m_id;
|
||||||
|
QString m_fileName;
|
||||||
|
PrimitivesTreeModel *const m_model;
|
||||||
|
LandscapeEditor::ZoneBuilderBase *const m_zoneBuilder;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class CreateRootPrimitiveCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class CreateRootPrimitiveCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CreateRootPrimitiveCommand(const QString &fileName, PrimitivesTreeModel *model,
|
||||||
|
QUndoCommand *parent = 0);
|
||||||
|
virtual ~CreateRootPrimitiveCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
private:
|
||||||
|
|
||||||
|
const QString m_fileName;
|
||||||
|
Path m_rootPrimIndex;
|
||||||
|
PrimitivesTreeModel *const m_model;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class LoadRootPrimitiveCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class LoadRootPrimitiveCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LoadRootPrimitiveCommand(const QString &fileName, WorldEditorScene *scene,
|
||||||
|
PrimitivesTreeModel *model, QTreeView *view,
|
||||||
|
QUndoCommand *parent = 0);
|
||||||
|
virtual ~LoadRootPrimitiveCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
private:
|
||||||
|
|
||||||
|
Path m_rootPrimIndex;
|
||||||
|
const QString m_fileName;
|
||||||
|
WorldEditorScene *const m_scene;
|
||||||
|
PrimitivesTreeModel *const m_model;
|
||||||
|
QTreeView *m_view;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class UnloadRootPrimitiveCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class UnloadRootPrimitiveCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UnloadRootPrimitiveCommand(const QModelIndex &index, WorldEditorScene *scene,
|
||||||
|
PrimitivesTreeModel *model, QTreeView *view,
|
||||||
|
QUndoCommand *parent = 0);
|
||||||
|
virtual ~UnloadRootPrimitiveCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
private:
|
||||||
|
|
||||||
|
Path m_path;
|
||||||
|
QString m_fileName;
|
||||||
|
NLLIGO::CPrimitives *m_primitives;
|
||||||
|
WorldEditorScene *const m_scene;
|
||||||
|
PrimitivesTreeModel *const m_model;
|
||||||
|
QTreeView *m_view;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class AddPrimitiveByClassCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class AddPrimitiveByClassCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AddPrimitiveByClassCommand(const QString &className, const Path &parentIndex,
|
||||||
|
WorldEditorScene *scene, PrimitivesTreeModel *model,
|
||||||
|
QTreeView *view, QUndoCommand *parent = 0);
|
||||||
|
virtual ~AddPrimitiveByClassCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
private:
|
||||||
|
|
||||||
|
QPointF m_initPos;
|
||||||
|
float m_delta;
|
||||||
|
const QString m_className;
|
||||||
|
Path m_parentIndex, m_newPrimIndex;
|
||||||
|
WorldEditorScene *const m_scene;
|
||||||
|
PrimitivesTreeModel *const m_model;
|
||||||
|
QTreeView *const m_view;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class DeletePrimitiveCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class DeletePrimitiveCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DeletePrimitiveCommand(const QModelIndex &index, PrimitivesTreeModel *model,
|
||||||
|
WorldEditorScene *scene, QTreeView *view, QUndoCommand *parent = 0);
|
||||||
|
virtual ~DeletePrimitiveCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
private:
|
||||||
|
|
||||||
|
Path m_path, m_parentPath;
|
||||||
|
uint m_posPrimitive;
|
||||||
|
NLLIGO::IPrimitive *m_oldPrimitive;
|
||||||
|
WorldEditorScene *const m_scene;
|
||||||
|
PrimitivesTreeModel *const m_model;
|
||||||
|
QTreeView *const m_view;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class AbstractWorldItemCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class AbstractWorldItemCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AbstractWorldItemCommand(const QList<QGraphicsItem *> &items, WorldEditorScene *scene,
|
||||||
|
PrimitivesTreeModel *model, QUndoCommand *parent = 0);
|
||||||
|
virtual ~AbstractWorldItemCommand();
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void undoChangeItem(int i, AbstractWorldItem *item) = 0;
|
||||||
|
virtual void redoChangeItem(int i, AbstractWorldItem *item) = 0;
|
||||||
|
void updatePrimitiveData(AbstractWorldItem *item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<Path> graphicsItemsToPaths(const QList<QGraphicsItem *> &items, PrimitivesTreeModel *model);
|
||||||
|
|
||||||
|
const QList<Path> m_listPaths;
|
||||||
|
PrimitivesTreeModel *const m_model;
|
||||||
|
WorldEditorScene *const m_scene;
|
||||||
|
bool m_firstRun;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class MoveWorldItemsCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class MoveWorldItemsCommand: public AbstractWorldItemCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MoveWorldItemsCommand(const QList<QGraphicsItem *> &items, const QPointF &offset,
|
||||||
|
WorldEditorScene *scene, PrimitivesTreeModel *model,
|
||||||
|
QUndoCommand *parent = 0);
|
||||||
|
virtual ~MoveWorldItemsCommand();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void undoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
virtual void redoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const QPointF m_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class RotateWorldItemsCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class RotateWorldItemsCommand: public AbstractWorldItemCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RotateWorldItemsCommand(const QList<QGraphicsItem *> &items, const qreal angle,
|
||||||
|
const QPointF &pivot, WorldEditorScene *scene,
|
||||||
|
PrimitivesTreeModel *model, QUndoCommand *parent = 0);
|
||||||
|
virtual ~RotateWorldItemsCommand();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void undoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
virtual void redoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const qreal m_angle;
|
||||||
|
const QPointF m_pivot;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class ScaleWorldItemsCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class ScaleWorldItemsCommand: public AbstractWorldItemCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScaleWorldItemsCommand(const QList<QGraphicsItem *> &items, const QPointF &factor,
|
||||||
|
const QPointF &pivot, WorldEditorScene *scene,
|
||||||
|
PrimitivesTreeModel *model, QUndoCommand *parent = 0);
|
||||||
|
virtual ~ScaleWorldItemsCommand();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void undoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
virtual void redoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const QPointF m_factor;
|
||||||
|
const QPointF m_pivot;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class TurnWorldItemsCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class TurnWorldItemsCommand: public AbstractWorldItemCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TurnWorldItemsCommand(const QList<QGraphicsItem *> &items, const qreal angle,
|
||||||
|
WorldEditorScene *scene, PrimitivesTreeModel *model,
|
||||||
|
QUndoCommand *parent = 0);
|
||||||
|
virtual ~TurnWorldItemsCommand();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void undoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
virtual void redoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const qreal m_angle;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class TurnWorldItemsCommand
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class ShapeWorldItemsCommand: public AbstractWorldItemCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShapeWorldItemsCommand(const QList<QGraphicsItem *> &items, const QList<QPolygonF> &polygons,
|
||||||
|
WorldEditorScene *scene, PrimitivesTreeModel *model,
|
||||||
|
QUndoCommand *parent = 0);
|
||||||
|
virtual ~ShapeWorldItemsCommand();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void undoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
virtual void redoChangeItem(int i, AbstractWorldItem *item);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const QList<QPolygonF> m_redoPolygons;
|
||||||
|
const QList<QPolygonF> m_undoPolygons;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
// Enable the use of QVariant with this class.
|
||||||
|
Q_DECLARE_METATYPE(QPersistentModelIndex *)
|
||||||
|
|
||||||
|
#endif // WORLD_EDITOR_ACTIONS_H
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef WORLD_EDITOR_CONSTANTS_H
|
||||||
|
#define WORLD_EDITOR_CONSTANTS_H
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
namespace Constants
|
||||||
|
{
|
||||||
|
const char *const WORLD_EDITOR_PLUGIN = "WorldEditor";
|
||||||
|
|
||||||
|
const int USER_TYPE = 65536;
|
||||||
|
const int NODE_PERISTENT_INDEX = USER_TYPE + 1;
|
||||||
|
const int WORLD_EDITOR_NODE = USER_TYPE + 2;
|
||||||
|
const int GRAPHICS_DATA_QT4_2D = USER_TYPE + 3;
|
||||||
|
const int GRAPHICS_DATA_NEL3D = USER_TYPE + 4;
|
||||||
|
const int PRIMITIVE_IS_MODIFIED = USER_TYPE + 5;
|
||||||
|
const int PRIMITIVE_FILE_IS_CREATED = USER_TYPE + 6;
|
||||||
|
const int PRIMITIVE_IS_VISIBLE = USER_TYPE + 7;
|
||||||
|
const int PRIMITIVE_IS_ENABLD = USER_TYPE + 8;
|
||||||
|
const int PRIMITIVE_FILE_NAME = USER_TYPE + 9;
|
||||||
|
const int PRIMITIVE_NON_REMOVABLE = USER_TYPE + 10;
|
||||||
|
const int ROOT_PRIMITIVE_CONTEXT = USER_TYPE + 20;
|
||||||
|
const int ROOT_PRIMITIVE_DATA_DIRECTORY = USER_TYPE + 21;
|
||||||
|
|
||||||
|
//properties editor
|
||||||
|
const char *const DIFFERENT_VALUE_STRING = "<different values>";
|
||||||
|
const char *const DIFFERENT_VALUE_MULTI_STRING = "<diff>";
|
||||||
|
|
||||||
|
//settings
|
||||||
|
const char *const WORLD_EDITOR_SECTION = "WorldEditor";
|
||||||
|
const char *const WORLD_WINDOW_STATE = "WorldWindowState";
|
||||||
|
const char *const WORLD_WINDOW_GEOMETRY = "WorldWindowGeometry";
|
||||||
|
const char *const WORLD_EDITOR_CELL_SIZE = "WorldEditorCellSize";
|
||||||
|
const char *const WORLD_EDITOR_SNAP = "WorldEditorSnap";
|
||||||
|
const char *const WORLD_EDITOR_USE_OPENGL = "WorldEditorUseOpenGL";
|
||||||
|
const char *const ZONE_SNAPSHOT_RES = "WorldEditorZoneSnapshotRes";
|
||||||
|
const char *const PRIMITIVE_CLASS_FILENAME = "WorldEditorPrimitiveClassFilename";
|
||||||
|
|
||||||
|
//resources
|
||||||
|
const char *const ICON_WORLD_EDITOR = ":/icons/ic_nel_world_editor.png";
|
||||||
|
const char *const ICON_ROOT_PRIMITIVE = "./old_ico/root.ico";
|
||||||
|
const char *const ICON_PROPERTY = "./old_ico/property.ico";
|
||||||
|
const char *const ICON_FOLDER = "./old_ico/folder_h.ico";
|
||||||
|
const char *const PATH_TO_OLD_ICONS = "./old_ico";
|
||||||
|
|
||||||
|
} // namespace Constants
|
||||||
|
} // namespace WorldEditor
|
||||||
|
|
||||||
|
#endif // WORLD_EDITOR_CONSTANTS_H
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
// Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef WORLD_EDITOR_GLOBAL_H
|
||||||
|
#define WORLD_EDITOR_GLOBAL_H
|
||||||
|
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
|
#if defined(WORLD_EDITOR_LIBRARY)
|
||||||
|
# define WORLD_EDITOR_EXPORT Q_DECL_EXPORT
|
||||||
|
#else
|
||||||
|
# define WORLD_EDITOR_EXPORT Q_DECL_IMPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // WORLD_EDITOR_GLOBAL_H
|
|
@ -0,0 +1,666 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_misc.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
#include <nel/misc/path.h>
|
||||||
|
#include <nel/misc/file.h>
|
||||||
|
#include <nel/misc/i_xml.h>
|
||||||
|
#include <nel/misc/o_xml.h>
|
||||||
|
#include <nel/ligo/primitive_utils.h>
|
||||||
|
#include <nel/ligo/ligo_config.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
namespace Utils
|
||||||
|
{
|
||||||
|
|
||||||
|
void syntaxError(const char *filename, xmlNodePtr xmlNode, const char *format, ...)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
|
||||||
|
if (format)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start( args, format );
|
||||||
|
sint ret = vsnprintf( buffer, 1024, format, args );
|
||||||
|
va_end( args );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(buffer, "Unknown error");
|
||||||
|
}
|
||||||
|
|
||||||
|
nlerror("(%s), node (%s), line (%s) :\n%s", filename, xmlNode->name, xmlNode->content, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getPropertyString(std::string &result, const char *filename, xmlNodePtr xmlNode, const char *propName)
|
||||||
|
{
|
||||||
|
// Call the CIXml version
|
||||||
|
if (!NLMISC::CIXml::getPropertyString(result, xmlNode, propName))
|
||||||
|
{
|
||||||
|
// Output a formated error
|
||||||
|
syntaxError(filename, xmlNode, "Missing XML node property (%s)", propName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 getUniqueId()
|
||||||
|
{
|
||||||
|
// Wait 1 ms
|
||||||
|
sint64 time = NLMISC::CTime::getLocalTime ();
|
||||||
|
sint64 time2;
|
||||||
|
while ((time2 = NLMISC::CTime::getLocalTime ()) == time)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32)time2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
// Load the document
|
||||||
|
NLMISC::CIFile file;
|
||||||
|
if (file.open(fileName))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Load the document in XML
|
||||||
|
NLMISC::CIXml xml;
|
||||||
|
xml.init(file);
|
||||||
|
|
||||||
|
// Get root node
|
||||||
|
xmlNodePtr rootNode = xml.getRootNode();
|
||||||
|
if (rootNode)
|
||||||
|
{
|
||||||
|
// Good header ?
|
||||||
|
if (strcmp((const char *)(rootNode->name), "NEL_WORLD_EDITOR_PROJECT") == 0)
|
||||||
|
{
|
||||||
|
int version = -1;
|
||||||
|
|
||||||
|
// Read the parameters
|
||||||
|
xmlNodePtr node = NLMISC::CIXml::getFirstChildNode(rootNode, "VERSION");
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
std::string versionString;
|
||||||
|
if (NLMISC::CIXml::getContentString (versionString, node))
|
||||||
|
version = atoi(versionString.c_str ());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version == -1)
|
||||||
|
syntaxError(fileName.c_str(), rootNode, "No version node");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Old format,
|
||||||
|
if (version <= 1)
|
||||||
|
{
|
||||||
|
syntaxError(fileName.c_str(), rootNode, "Old version node");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Read it
|
||||||
|
if (version > WORLD_EDITOR_FILE_VERSION)
|
||||||
|
{
|
||||||
|
syntaxError(fileName.c_str(), node, "Unknown file version");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Read data directory
|
||||||
|
node = NLMISC::CIXml::getFirstChildNode(rootNode, "DATA_DIRECTORY");
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
std::string dataDir;
|
||||||
|
NLMISC::CIXml::getPropertyString(dataDir, node, "VALUE");
|
||||||
|
worldEditList.push_back(WorldEditItem(DataDirectoryType, dataDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read data directory
|
||||||
|
node = NLMISC::CIXml::getFirstChildNode(rootNode, "CONTEXT");
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
std::string context;
|
||||||
|
NLMISC::CIXml::getPropertyString(context, node, "VALUE");
|
||||||
|
worldEditList.push_back(WorldEditItem(ContextType, context));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the database element
|
||||||
|
node = NLMISC::CIXml::getFirstChildNode(rootNode, "DATABASE_ELEMENT");
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Get the type
|
||||||
|
std::string type;
|
||||||
|
if (getPropertyString(type, fileName.c_str(), node, "TYPE"))
|
||||||
|
{
|
||||||
|
// Read the filename
|
||||||
|
std::string filenameChild;
|
||||||
|
if (getPropertyString(filenameChild, fileName.c_str(), node, "FILENAME"))
|
||||||
|
{
|
||||||
|
// Is it a landscape ?
|
||||||
|
if (type == "landscape")
|
||||||
|
{
|
||||||
|
worldEditList.push_back(WorldEditItem(LandscapeType, filenameChild));
|
||||||
|
|
||||||
|
// Get the primitives
|
||||||
|
xmlNodePtr primitives = NLMISC::CIXml::getFirstChildNode(node, "PRIMITIVES");
|
||||||
|
if (primitives)
|
||||||
|
{
|
||||||
|
NLLIGO::CPrimitives ligoPrimitives;
|
||||||
|
|
||||||
|
// Read it
|
||||||
|
ligoPrimitives.read(primitives, fileName.c_str(), *ligoConfig());
|
||||||
|
//_DataHierarchy.back ().Primitives.read (primitives, filename, theApp.Config);
|
||||||
|
|
||||||
|
// Set the filename
|
||||||
|
//_DataHierarchy.back ().Filename = filenameChild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
worldEditList.push_back(WorldEditItem(PrimitiveType, filenameChild));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (node = NLMISC::CIXml::getNextChildNode(node, "DATABASE_ELEMENT"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Error
|
||||||
|
syntaxError(fileName.c_str(), rootNode, "Unknown file header : %s", rootNode->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NLMISC::Exception &e)
|
||||||
|
{
|
||||||
|
nlerror("Error reading file %s : %s", fileName.c_str(), e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nlerror("Can't open the file %s for reading.", fileName.c_str());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NLLIGO::IPrimitive *getRootPrimitive(NLLIGO::IPrimitive *primitive)
|
||||||
|
{
|
||||||
|
nlassert(primitive);
|
||||||
|
|
||||||
|
if (primitive->getParent() == NULL)
|
||||||
|
return primitive;
|
||||||
|
else
|
||||||
|
return getRootPrimitive(primitive->getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
void initPrimitiveParameters(const NLLIGO::CPrimitiveClass &primClass, NLLIGO::IPrimitive &primitive,
|
||||||
|
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters)
|
||||||
|
{
|
||||||
|
// Other parameters
|
||||||
|
for (uint p = 0; p < initParameters.size(); ++p)
|
||||||
|
{
|
||||||
|
// The property
|
||||||
|
const NLLIGO::CPrimitiveClass::CInitParameters ¶meter = initParameters[p];
|
||||||
|
|
||||||
|
// Look for it in the class
|
||||||
|
uint cp;
|
||||||
|
for (cp = 0; cp < primClass.Parameters.size(); ++cp)
|
||||||
|
{
|
||||||
|
// Good one ?
|
||||||
|
if (primClass.Parameters[cp].Name == initParameters[p].Name)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The primitive type
|
||||||
|
NLLIGO::CPrimitiveClass::CParameter::TType type;
|
||||||
|
|
||||||
|
// Found ?
|
||||||
|
if (cp < primClass.Parameters.size())
|
||||||
|
type = primClass.Parameters[cp].Type;
|
||||||
|
|
||||||
|
if (initParameters[p].Name == "name")
|
||||||
|
type = NLLIGO::CPrimitiveClass::CParameter::String;
|
||||||
|
|
||||||
|
if (cp < primClass.Parameters.size () || (initParameters[p].Name == "name"))
|
||||||
|
{
|
||||||
|
// Default value ?
|
||||||
|
if (!parameter.DefaultValue.empty())
|
||||||
|
{
|
||||||
|
// Type of property
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case NLLIGO::CPrimitiveClass::CParameter::Boolean:
|
||||||
|
case NLLIGO::CPrimitiveClass::CParameter::ConstString:
|
||||||
|
case NLLIGO::CPrimitiveClass::CParameter::String:
|
||||||
|
{
|
||||||
|
// Some feedback
|
||||||
|
if (parameter.DefaultValue.size() > 1)
|
||||||
|
nlerror("Warning: parameter (%s) in class name (%s) has more than 1 default value (%d).",
|
||||||
|
parameter.Name.c_str(), primClass.Name.c_str(), parameter.DefaultValue.size());
|
||||||
|
|
||||||
|
if ((cp < primClass.Parameters.size() && !primClass.Parameters[cp].Visible)
|
||||||
|
|| parameter.DefaultValue[0].GenID)
|
||||||
|
{
|
||||||
|
// Remove this property
|
||||||
|
primitive.removePropertyByName(parameter.Name.c_str());
|
||||||
|
|
||||||
|
// Add this property
|
||||||
|
primitive.addPropertyByName(parameter.Name.c_str(),
|
||||||
|
new NLLIGO::CPropertyString((parameter.DefaultValue[0].GenID ? NLMISC::toString(getUniqueId()) : "").c_str ()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NLLIGO::CPrimitiveClass::CParameter::ConstStringArray:
|
||||||
|
case NLLIGO::CPrimitiveClass::CParameter::StringArray:
|
||||||
|
{
|
||||||
|
bool Visible = false;
|
||||||
|
if (cp < primClass.Parameters.size() && !primClass.Parameters[cp].Visible)
|
||||||
|
Visible = true;
|
||||||
|
for (size_t i = 0; i < parameter.DefaultValue.size(); ++i)
|
||||||
|
{
|
||||||
|
// Generate a unique id ?
|
||||||
|
if (parameter.DefaultValue[i].GenID)
|
||||||
|
Visible = true;
|
||||||
|
}
|
||||||
|
if (Visible)
|
||||||
|
{
|
||||||
|
// Remove this property
|
||||||
|
primitive.removePropertyByName (parameter.Name.c_str());
|
||||||
|
|
||||||
|
// Add this property
|
||||||
|
NLLIGO::CPropertyStringArray *str = new NLLIGO::CPropertyStringArray();
|
||||||
|
str->StringArray.resize (parameter.DefaultValue.size());
|
||||||
|
for (size_t i = 0; i < parameter.DefaultValue.size(); ++i)
|
||||||
|
{
|
||||||
|
// Generate a unique id ?
|
||||||
|
if (parameter.DefaultValue[i].GenID)
|
||||||
|
str->StringArray[i] = NLMISC::toString(getUniqueId());
|
||||||
|
else
|
||||||
|
str->StringArray[i] = "";
|
||||||
|
}
|
||||||
|
primitive.addPropertyByName(parameter.Name.c_str(), str);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Some feedback
|
||||||
|
nlerror("Warning: parameter (%s) doesn't exist in class (%s).",
|
||||||
|
initParameters[p].Name.c_str(), primClass.Name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName,
|
||||||
|
const NLMISC::CVector &initPos, float deltaPos,
|
||||||
|
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters,
|
||||||
|
NLLIGO::IPrimitive *parent)
|
||||||
|
{
|
||||||
|
// Get the prim class
|
||||||
|
const NLLIGO::CPrimitiveClass *primClass = ligoConfig()->getPrimitiveClass(className);
|
||||||
|
if (primClass)
|
||||||
|
{
|
||||||
|
// Create the base primitive
|
||||||
|
NLLIGO::IPrimitive *primitive = NULL;
|
||||||
|
switch (primClass->Type)
|
||||||
|
{
|
||||||
|
case NLLIGO::CPrimitiveClass::Node:
|
||||||
|
primitive = new NLLIGO::CPrimNode;
|
||||||
|
break;
|
||||||
|
case NLLIGO::CPrimitiveClass::Point:
|
||||||
|
{
|
||||||
|
NLLIGO::CPrimPoint *point = new NLLIGO::CPrimPoint;
|
||||||
|
primitive = point;
|
||||||
|
point->Point.CVector::operator = (initPos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NLLIGO::CPrimitiveClass::Path:
|
||||||
|
{
|
||||||
|
NLLIGO::CPrimPath *path = new NLLIGO::CPrimPath;
|
||||||
|
primitive = path;
|
||||||
|
path->VPoints.push_back(NLLIGO::CPrimVector(initPos));
|
||||||
|
NLMISC::CVector secondPos = NLMISC::CVector(initPos.x + deltaPos, initPos.y, 0.0);
|
||||||
|
path->VPoints.push_back(NLLIGO::CPrimVector(secondPos));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NLLIGO::CPrimitiveClass::Zone:
|
||||||
|
{
|
||||||
|
NLLIGO::CPrimZone *zone = new NLLIGO::CPrimZone;
|
||||||
|
primitive = zone;
|
||||||
|
zone->VPoints.push_back(NLLIGO::CPrimVector(initPos));
|
||||||
|
NLMISC::CVector secondPos = NLMISC::CVector(initPos.x + deltaPos, initPos.y, 0.0);
|
||||||
|
zone->VPoints.push_back(NLLIGO::CPrimVector(secondPos));
|
||||||
|
secondPos.y = initPos.y + deltaPos;
|
||||||
|
zone->VPoints.push_back(NLLIGO::CPrimVector(secondPos));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NLLIGO::CPrimitiveClass::Alias:
|
||||||
|
primitive = new NLLIGO::CPrimAlias;
|
||||||
|
break;
|
||||||
|
case NLLIGO::CPrimitiveClass::Bitmap:
|
||||||
|
primitive = new NLLIGO::CPrimNode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nlassert(primitive);
|
||||||
|
|
||||||
|
// Add properties
|
||||||
|
primitive->addPropertyByName("class", new NLLIGO::CPropertyString(className));
|
||||||
|
primitive->addPropertyByName("name", new NLLIGO::CPropertyString(primName, primName[0] == 0));
|
||||||
|
|
||||||
|
// Init with default parameters
|
||||||
|
std::vector<NLLIGO::CPrimitiveClass::CInitParameters> tempParam;
|
||||||
|
tempParam.reserve(primClass->Parameters.size());
|
||||||
|
for (size_t i = 0; i < primClass->Parameters.size(); i++)
|
||||||
|
tempParam.push_back (primClass->Parameters[i]);
|
||||||
|
initPrimitiveParameters (*primClass, *primitive, tempParam);
|
||||||
|
|
||||||
|
// Init with option parameters
|
||||||
|
initPrimitiveParameters(*primClass, *primitive, initParameters);
|
||||||
|
|
||||||
|
parent->insertChild(primitive);
|
||||||
|
/*
|
||||||
|
// Insert the primitive
|
||||||
|
insertPrimitive (locator, primitive);
|
||||||
|
*/
|
||||||
|
// The new pos
|
||||||
|
NLMISC::CVector newPos = initPos;
|
||||||
|
newPos.x += deltaPos;
|
||||||
|
|
||||||
|
// Create static children
|
||||||
|
uint c;
|
||||||
|
for (c = 0; c < primClass->StaticChildren.size(); c++)
|
||||||
|
{
|
||||||
|
// The child ref
|
||||||
|
const NLLIGO::CPrimitiveClass::CChild &child = primClass->StaticChildren[c];
|
||||||
|
|
||||||
|
// Create the child
|
||||||
|
const NLLIGO::IPrimitive *childPrim = createPrimitive(child.ClassName.c_str(), child.Name.c_str(),
|
||||||
|
newPos, deltaPos, primClass->StaticChildren[c].Parameters, primitive);
|
||||||
|
|
||||||
|
// The new pos
|
||||||
|
newPos.y += deltaPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Canceled ?
|
||||||
|
if (c < primClass->StaticChildren.size())
|
||||||
|
{
|
||||||
|
deletePrimitive(primitive);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (primitive)
|
||||||
|
{
|
||||||
|
if (!primClass->AutoInit)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eval the default name property
|
||||||
|
std::string name;
|
||||||
|
if (!primitive->getPropertyByName ("name", name) || name.empty())
|
||||||
|
{
|
||||||
|
const NLLIGO::CPrimitiveClass *primClass = ligoConfig()->getPrimitiveClass(*primitive);
|
||||||
|
if (primClass)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < primClass->Parameters.size(); ++i)
|
||||||
|
{
|
||||||
|
if (primClass->Parameters[i].Name == "name")
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
primClass->Parameters[i].getDefaultValue(result, *primitive, *primClass, NULL);
|
||||||
|
if (!result.empty())
|
||||||
|
{
|
||||||
|
primitive->removePropertyByName("name");
|
||||||
|
primitive->addPropertyByName("name", new NLLIGO::CPropertyString(result.c_str(), true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
primitive->initDefaultValues(*ligoConfig());
|
||||||
|
}
|
||||||
|
return primitive;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nlerror("Unknown primitive class name : %s", className);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deletePrimitive(NLLIGO::IPrimitive *primitive)
|
||||||
|
{
|
||||||
|
// Get the parent
|
||||||
|
NLLIGO::IPrimitive *parent = primitive->getParent();
|
||||||
|
nlassert(parent);
|
||||||
|
|
||||||
|
// Get the child id
|
||||||
|
uint childId;
|
||||||
|
nlverify(parent->getChildId(childId, primitive));
|
||||||
|
|
||||||
|
// Delete the child
|
||||||
|
nlverify(parent->removeChild(childId));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool updateDefaultValues(NLLIGO::IPrimitive *primitive)
|
||||||
|
{
|
||||||
|
bool modified = false;
|
||||||
|
|
||||||
|
// Get the prim class
|
||||||
|
const NLLIGO::CPrimitiveClass *primClass = ligoConfig()->getPrimitiveClass(*primitive);
|
||||||
|
nlassert(primClass);
|
||||||
|
|
||||||
|
if (primClass)
|
||||||
|
{
|
||||||
|
// For each parameters
|
||||||
|
for (uint i = 0; i < primClass->Parameters.size(); i++)
|
||||||
|
{
|
||||||
|
// First check the primitive property has to good type
|
||||||
|
NLLIGO::IProperty *prop;
|
||||||
|
if (primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), prop))
|
||||||
|
{
|
||||||
|
// String to array ?
|
||||||
|
NLLIGO::CPropertyString *propString = dynamic_cast<NLLIGO::CPropertyString *>(prop);
|
||||||
|
const bool classStringArray = primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::StringArray ||
|
||||||
|
primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::ConstStringArray;
|
||||||
|
if (propString && classStringArray)
|
||||||
|
{
|
||||||
|
// Build an array string
|
||||||
|
std::vector<std::string> strings;
|
||||||
|
if (!propString->String.empty())
|
||||||
|
strings.push_back(propString->String);
|
||||||
|
prop = new NLLIGO::CPropertyStringArray(strings);
|
||||||
|
primitive->removePropertyByName(primClass->Parameters[i].Name.c_str());
|
||||||
|
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), prop);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array to string ?
|
||||||
|
NLLIGO::CPropertyStringArray *propStringArray = dynamic_cast<NLLIGO::CPropertyStringArray *>(prop);
|
||||||
|
if (propStringArray && !classStringArray)
|
||||||
|
{
|
||||||
|
// Build an array string
|
||||||
|
std::string str;
|
||||||
|
if (!propStringArray->StringArray.empty())
|
||||||
|
str = propStringArray->StringArray[0];
|
||||||
|
prop = new NLLIGO::CPropertyString(str);
|
||||||
|
primitive->removePropertyByName(primClass->Parameters[i].Name.c_str());
|
||||||
|
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), prop);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String or string array ?
|
||||||
|
if (primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::String)
|
||||||
|
{
|
||||||
|
// Default value available ?
|
||||||
|
if (!primClass->Parameters[i].DefaultValue.empty ())
|
||||||
|
{
|
||||||
|
// Unique Id ?
|
||||||
|
if (primClass->Parameters[i].DefaultValue[0].GenID)
|
||||||
|
{
|
||||||
|
// The doesn't exist ?
|
||||||
|
std::string result;
|
||||||
|
if (!primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), result))
|
||||||
|
{
|
||||||
|
// Add it !
|
||||||
|
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), new NLLIGO::CPropertyString(NLMISC::toString(getUniqueId()).c_str()));
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Hidden ?
|
||||||
|
else if (!primClass->Parameters[i].Visible)
|
||||||
|
{
|
||||||
|
// The doesn't exist ?
|
||||||
|
std::string result;
|
||||||
|
if (!primitive->getPropertyByName (primClass->Parameters[i].Name.c_str (), result))
|
||||||
|
{
|
||||||
|
// Add it !
|
||||||
|
primitive->addPropertyByName (primClass->Parameters[i].Name.c_str (), new NLLIGO::CPropertyString (""));
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::StringArray) ||
|
||||||
|
(primClass->Parameters[i].Type == NLLIGO::CPrimitiveClass::CParameter::ConstStringArray))
|
||||||
|
{
|
||||||
|
for (uint j = 0; j < primClass->Parameters[i].DefaultValue.size(); j++)
|
||||||
|
{
|
||||||
|
// Unique Id ?
|
||||||
|
if (primClass->Parameters[i].DefaultValue[j].GenID)
|
||||||
|
{
|
||||||
|
// The doesn't exist ?
|
||||||
|
std::vector<std::string> result;
|
||||||
|
std::vector<std::string> *resultPtr = NULL;
|
||||||
|
if (!primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), resultPtr) ||
|
||||||
|
(resultPtr->size() <= j))
|
||||||
|
{
|
||||||
|
// Copy
|
||||||
|
if (resultPtr)
|
||||||
|
result = *resultPtr;
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
if (result.size() <= j)
|
||||||
|
result.resize(j + 1);
|
||||||
|
|
||||||
|
// Resize to it
|
||||||
|
primitive->removePropertyByName(primClass->Parameters[i].Name.c_str());
|
||||||
|
|
||||||
|
// Set the value
|
||||||
|
result[j] = NLMISC::toString(getUniqueId());
|
||||||
|
|
||||||
|
// Add the new property array
|
||||||
|
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), new NLLIGO::CPropertyStringArray(result));
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Hidden ?
|
||||||
|
else if (!primClass->Parameters[i].Visible)
|
||||||
|
{
|
||||||
|
// The doesn't exist ?
|
||||||
|
std::vector<std::string> result;
|
||||||
|
std::vector<std::string> *resultPtr = NULL;
|
||||||
|
if (!primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), resultPtr) || (resultPtr->size () <= j))
|
||||||
|
{
|
||||||
|
// Copy
|
||||||
|
if (resultPtr)
|
||||||
|
result = *resultPtr;
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
if (result.size() <= j)
|
||||||
|
result.resize(j + 1);
|
||||||
|
|
||||||
|
// Resize to it
|
||||||
|
primitive->removePropertyByName(primClass->Parameters[i].Name.c_str());
|
||||||
|
|
||||||
|
// Set the value
|
||||||
|
result[j] = "";
|
||||||
|
|
||||||
|
// Add the new property array
|
||||||
|
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), new NLLIGO::CPropertyStringArray(result));
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Default value available ?
|
||||||
|
if (!primClass->Parameters[i].DefaultValue.empty ())
|
||||||
|
{
|
||||||
|
// Hidden ?
|
||||||
|
if (!primClass->Parameters[i].Visible)
|
||||||
|
{
|
||||||
|
// The doesn't exist ?
|
||||||
|
std::string result;
|
||||||
|
if (!primitive->getPropertyByName(primClass->Parameters[i].Name.c_str(), result))
|
||||||
|
{
|
||||||
|
// Add it !
|
||||||
|
primitive->addPropertyByName(primClass->Parameters[i].Name.c_str(), new NLLIGO::CPropertyString(""));
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool recursiveUpdateDefaultValues(NLLIGO::IPrimitive *primitive)
|
||||||
|
{
|
||||||
|
bool modified = updateDefaultValues(primitive);
|
||||||
|
|
||||||
|
const uint count = primitive->getNumChildren();
|
||||||
|
for (uint i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
// Get the child
|
||||||
|
NLLIGO::IPrimitive *child;
|
||||||
|
nlverify(primitive->getChild(child, i));
|
||||||
|
modified |= recursiveUpdateDefaultValues(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
NLLIGO::CLigoConfig *ligoConfig()
|
||||||
|
{
|
||||||
|
return NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace Utils */
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,78 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef WORLD_EDITOR_MISC_H
|
||||||
|
#define WORLD_EDITOR_MISC_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/vector.h>
|
||||||
|
#include <nel/ligo/primitive.h>
|
||||||
|
#include <nel/ligo/primitive_class.h>
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define WORLD_EDITOR_FILE_VERSION 2
|
||||||
|
#define WORLD_EDITOR_DATABASE_SIZE 100
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
namespace Utils
|
||||||
|
{
|
||||||
|
enum ItemType
|
||||||
|
{
|
||||||
|
DataDirectoryType = 0,
|
||||||
|
ContextType,
|
||||||
|
LandscapeType,
|
||||||
|
PrimitiveType
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::pair<ItemType, std::string> WorldEditItem;
|
||||||
|
typedef std::vector<WorldEditItem> WorldEditList;
|
||||||
|
|
||||||
|
// Generate unique identificator
|
||||||
|
uint32 getUniqueId();
|
||||||
|
|
||||||
|
// Load *.worldedit file and return list primitives and landscapes.
|
||||||
|
bool loadWorldEditFile(const std::string &fileName, WorldEditList &worldEditList);
|
||||||
|
|
||||||
|
// Get root primitive
|
||||||
|
NLLIGO::IPrimitive *getRootPrimitive(NLLIGO::IPrimitive *primitive);
|
||||||
|
|
||||||
|
// Init a primitive parameters
|
||||||
|
void initPrimitiveParameters(const NLLIGO::CPrimitiveClass &primClass, NLLIGO::IPrimitive &primitive,
|
||||||
|
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters);
|
||||||
|
|
||||||
|
NLLIGO::IPrimitive *createPrimitive(const char *className, const char *primName,
|
||||||
|
const NLMISC::CVector &initPos, float deltaPos,
|
||||||
|
const std::vector<NLLIGO::CPrimitiveClass::CInitParameters> &initParameters,
|
||||||
|
NLLIGO::IPrimitive *parent);
|
||||||
|
|
||||||
|
void deletePrimitive(NLLIGO::IPrimitive *primitive);
|
||||||
|
|
||||||
|
bool updateDefaultValues(NLLIGO::IPrimitive *primitive);
|
||||||
|
|
||||||
|
bool recursiveUpdateDefaultValues(NLLIGO::IPrimitive *primitive);
|
||||||
|
|
||||||
|
NLLIGO::CLigoConfig *ligoConfig();
|
||||||
|
|
||||||
|
} /* namespace Utils */
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
#endif // WORLD_EDITOR_MISC_H
|
|
@ -0,0 +1,136 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_plugin.h"
|
||||||
|
#include "world_editor_window.h"
|
||||||
|
#include "world_editor_settings_page.h"
|
||||||
|
|
||||||
|
#include "../core/icore.h"
|
||||||
|
#include "../core/core_constants.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include "nel/misc/debug.h"
|
||||||
|
#include <nel/misc/path.h>
|
||||||
|
#include <nel/ligo/primitive_utils.h>
|
||||||
|
#include <nel/ligo/primitive.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
WorldEditorPlugin::~WorldEditorPlugin()
|
||||||
|
{
|
||||||
|
Q_FOREACH(QObject *obj, m_autoReleaseObjects)
|
||||||
|
{
|
||||||
|
m_plugMan->removeObject(obj);
|
||||||
|
}
|
||||||
|
qDeleteAll(m_autoReleaseObjects);
|
||||||
|
m_autoReleaseObjects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WorldEditorPlugin::initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString)
|
||||||
|
{
|
||||||
|
m_plugMan = pluginManager;
|
||||||
|
|
||||||
|
WorldEditorSettingsPage *weSettings = new WorldEditorSettingsPage(this);
|
||||||
|
addAutoReleasedObject(weSettings);
|
||||||
|
|
||||||
|
QSettings *settings = Core::ICore::instance()->settings();
|
||||||
|
settings->beginGroup(Constants::WORLD_EDITOR_SECTION);
|
||||||
|
m_ligoConfig.CellSize = settings->value(Constants::WORLD_EDITOR_CELL_SIZE, "160").toFloat();
|
||||||
|
m_ligoConfig.Snap = settings->value(Constants::WORLD_EDITOR_SNAP, "1").toFloat();
|
||||||
|
m_ligoConfig.ZoneSnapShotRes = settings->value(Constants::ZONE_SNAPSHOT_RES, "128").toUInt();
|
||||||
|
QString fileName = settings->value(Constants::PRIMITIVE_CLASS_FILENAME, "world_editor_classes.xml").toString();
|
||||||
|
settings->endGroup();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Search path of file world_editor_classes.xml
|
||||||
|
std::string ligoPath = NLMISC::CPath::lookup(fileName.toStdString());
|
||||||
|
// Init LIGO
|
||||||
|
m_ligoConfig.readPrimitiveClass(ligoPath.c_str(), true);
|
||||||
|
NLLIGO::Register();
|
||||||
|
NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig = &m_ligoConfig;
|
||||||
|
}
|
||||||
|
catch (NLMISC::Exception &e)
|
||||||
|
{
|
||||||
|
*errorString = tr("(%1)").arg(e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
m_ligoConfig.resetPrimitiveConfiguration ();
|
||||||
|
|
||||||
|
// TODO: get file names! from settings
|
||||||
|
m_ligoConfig.readPrimitiveClass("world_editor_primitive_configuration.xml", true);
|
||||||
|
|
||||||
|
|
||||||
|
addAutoReleasedObject(new WorldEditorContext(this));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorPlugin::extensionsInitialized()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorPlugin::shutdown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorPlugin::setNelContext(NLMISC::INelContext *nelContext)
|
||||||
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
// Ensure that a context doesn't exist yet.
|
||||||
|
// This only applies to platforms without PIC, e.g. Windows.
|
||||||
|
nlassert(!NLMISC::INelContext::isContextInitialised());
|
||||||
|
#endif // NL_OS_WINDOWS
|
||||||
|
m_libContext = new NLMISC::CLibraryContext(*nelContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorPlugin::addAutoReleasedObject(QObject *obj)
|
||||||
|
{
|
||||||
|
m_plugMan->addObject(obj);
|
||||||
|
m_autoReleaseObjects.prepend(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldEditorContext::WorldEditorContext(QObject *parent)
|
||||||
|
: IContext(parent),
|
||||||
|
m_worldEditorWindow(0)
|
||||||
|
{
|
||||||
|
m_worldEditorWindow = new WorldEditorWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
QUndoStack *WorldEditorContext::undoStack()
|
||||||
|
{
|
||||||
|
return m_worldEditorWindow->undoStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorContext::open()
|
||||||
|
{
|
||||||
|
m_worldEditorWindow->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *WorldEditorContext::widget()
|
||||||
|
{
|
||||||
|
return m_worldEditorWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EXPORT_PLUGIN(WorldEditor::WorldEditorPlugin)
|
|
@ -0,0 +1,98 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2010 Winch Gate Property Limited
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef WORLD_EDITOR_PLUGIN_H
|
||||||
|
#define WORLD_EDITOR_PLUGIN_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_constants.h"
|
||||||
|
#include "../../extension_system/iplugin.h"
|
||||||
|
#include "../core/icontext.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include "nel/misc/app_context.h"
|
||||||
|
#include <nel/ligo/ligo_config.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtGui/QIcon>
|
||||||
|
|
||||||
|
namespace NLMISC
|
||||||
|
{
|
||||||
|
class CLibraryContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
class WorldEditorWindow;
|
||||||
|
|
||||||
|
class WorldEditorPlugin : public QObject, public ExtensionSystem::IPlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_INTERFACES(ExtensionSystem::IPlugin)
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~WorldEditorPlugin();
|
||||||
|
|
||||||
|
bool initialize(ExtensionSystem::IPluginManager *pluginManager, QString *errorString);
|
||||||
|
void extensionsInitialized();
|
||||||
|
void shutdown();
|
||||||
|
void setNelContext(NLMISC::INelContext *nelContext);
|
||||||
|
|
||||||
|
void addAutoReleasedObject(QObject *obj);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NLMISC::CLibraryContext *m_libContext;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NLLIGO::CLigoConfig m_ligoConfig;
|
||||||
|
ExtensionSystem::IPluginManager *m_plugMan;
|
||||||
|
QList<QObject *> m_autoReleaseObjects;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorldEditorContext: public Core::IContext
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WorldEditorContext(QObject *parent = 0);
|
||||||
|
virtual ~WorldEditorContext() {}
|
||||||
|
|
||||||
|
virtual QString id() const
|
||||||
|
{
|
||||||
|
return QLatin1String("WorldEditorContext");
|
||||||
|
}
|
||||||
|
virtual QString trName() const
|
||||||
|
{
|
||||||
|
return tr("World Editor");
|
||||||
|
}
|
||||||
|
virtual QIcon icon() const
|
||||||
|
{
|
||||||
|
return QIcon(Constants::ICON_WORLD_EDITOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void open();
|
||||||
|
|
||||||
|
virtual QUndoStack *undoStack();
|
||||||
|
|
||||||
|
virtual QWidget *widget();
|
||||||
|
|
||||||
|
WorldEditorWindow *m_worldEditorWindow;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace WorldEditor
|
||||||
|
|
||||||
|
#endif // WORLD_EDITOR_PLUGIN_H
|
|
@ -0,0 +1,604 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_scene.h"
|
||||||
|
#include "world_editor_scene_item.h"
|
||||||
|
#include "world_editor_actions.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QPainter>
|
||||||
|
#include <QtGui/QGraphicsPixmapItem>
|
||||||
|
#include <QtGui/QGraphicsSimpleTextItem>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
WorldEditorScene::WorldEditorScene(int sizeCell, PrimitivesTreeModel *model, QUndoStack *undoStack, QObject *parent)
|
||||||
|
: LandscapeEditor::LandscapeSceneBase(sizeCell, parent),
|
||||||
|
m_editedSelectedItems(false),
|
||||||
|
m_lastPickedPrimitive(0),
|
||||||
|
m_mode(SelectMode),
|
||||||
|
m_pointsMode(false),
|
||||||
|
m_undoStack(undoStack),
|
||||||
|
m_model(model)
|
||||||
|
{
|
||||||
|
setItemIndexMethod(NoIndex);
|
||||||
|
|
||||||
|
// TODO: get params from settings
|
||||||
|
setSceneRect(QRectF(-20 * 160, -20 * 160, 256 * 160, 256 * 160));
|
||||||
|
|
||||||
|
m_greenPen.setColor(QColor(50, 255, 155));
|
||||||
|
m_greenPen.setWidth(0);
|
||||||
|
m_greenBrush.setColor(QColor(50, 255, 155, 80));
|
||||||
|
m_greenBrush.setStyle(Qt::SolidPattern);
|
||||||
|
|
||||||
|
m_purplePen.setColor(QColor(100, 0, 255));
|
||||||
|
m_purplePen.setWidth(0);
|
||||||
|
m_purpleBrush.setColor(QColor(100, 0, 255, 80));
|
||||||
|
m_purpleBrush.setStyle(Qt::SolidPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldEditorScene::~WorldEditorScene()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractWorldItem *WorldEditorScene::addWorldItemPoint(const QPointF &point, const qreal angle,
|
||||||
|
const qreal radius, bool showArrow)
|
||||||
|
{
|
||||||
|
WorldItemPoint *item = new WorldItemPoint(point, angle, radius, showArrow);
|
||||||
|
addItem(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractWorldItem *WorldEditorScene::addWorldItemPath(const QPolygonF &polyline, bool showArrow)
|
||||||
|
{
|
||||||
|
WorldItemPath *item = new WorldItemPath(polyline);
|
||||||
|
addItem(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractWorldItem *WorldEditorScene::addWorldItemZone(const QPolygonF &polygon)
|
||||||
|
{
|
||||||
|
WorldItemZone *item = new WorldItemZone(polygon);
|
||||||
|
addItem(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::removeWorldItem(QGraphicsItem *item)
|
||||||
|
{
|
||||||
|
updateSelectedWorldItems(true);
|
||||||
|
m_selectedItems.clear();
|
||||||
|
m_editedSelectedItems = false;
|
||||||
|
m_firstSelection = false;
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::setModeEdit(WorldEditorScene::ModeEdit mode)
|
||||||
|
{
|
||||||
|
if (mode == WorldEditorScene::SelectMode)
|
||||||
|
m_editedSelectedItems = false;
|
||||||
|
|
||||||
|
m_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldEditorScene::ModeEdit WorldEditorScene::editMode() const
|
||||||
|
{
|
||||||
|
return m_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WorldEditorScene::isEnabledEditPoints() const
|
||||||
|
{
|
||||||
|
return m_pointsMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::setEnabledEditPoints(bool enabled)
|
||||||
|
{
|
||||||
|
if (m_pointsMode == enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_pointsMode = enabled;
|
||||||
|
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedItems)
|
||||||
|
{
|
||||||
|
AbstractWorldItem *worldItem = qgraphicsitem_cast<AbstractWorldItem *>(item);
|
||||||
|
if (worldItem != 0)
|
||||||
|
worldItem->setEnabledSubPoints(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_selectedPoints.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateSelection(const QList<QGraphicsItem *> &selected, const QList<QGraphicsItem *> &deselected)
|
||||||
|
{
|
||||||
|
// Deselect and remove from list graphics items.
|
||||||
|
Q_FOREACH(QGraphicsItem *item, deselected)
|
||||||
|
{
|
||||||
|
// Item is selected?
|
||||||
|
int i = m_selectedItems.indexOf(item);
|
||||||
|
if (i != -1)
|
||||||
|
{
|
||||||
|
updateSelectedWorldItem(item, false);
|
||||||
|
m_selectedItems.takeAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select and add from list graphics items.
|
||||||
|
Q_FOREACH(QGraphicsItem *item, selected)
|
||||||
|
{
|
||||||
|
// Item is selected?
|
||||||
|
int i = m_selectedItems.indexOf(item);
|
||||||
|
if (i == -1)
|
||||||
|
{
|
||||||
|
updateSelectedWorldItem(item, true);
|
||||||
|
m_selectedItems.push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
m_firstSelection = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::drawForeground(QPainter *painter, const QRectF &rect)
|
||||||
|
{
|
||||||
|
QGraphicsScene::drawForeground(painter, rect);
|
||||||
|
|
||||||
|
if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0))
|
||||||
|
{
|
||||||
|
// Draw selection area
|
||||||
|
if (m_selectionArea.left() < m_selectionArea.right())
|
||||||
|
{
|
||||||
|
painter->setPen(m_greenPen);
|
||||||
|
painter->setBrush(m_greenBrush);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
painter->setPen(m_purplePen);
|
||||||
|
painter->setBrush(m_purpleBrush);
|
||||||
|
}
|
||||||
|
painter->drawRect(m_selectionArea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
m_firstPick = mouseEvent->scenePos();
|
||||||
|
|
||||||
|
if (isEnabledEditPoints())
|
||||||
|
{
|
||||||
|
m_polygons = polygonsFromItems(m_selectedItems);
|
||||||
|
|
||||||
|
if (mouseEvent->button() == Qt::LeftButton)
|
||||||
|
{
|
||||||
|
// Create new sub-points
|
||||||
|
// Call method mousePressEvent for sub-point located under mouse
|
||||||
|
LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent);
|
||||||
|
|
||||||
|
if ((!m_editedSelectedItems && m_selectedPoints.isEmpty()) ||
|
||||||
|
(!calcBoundingRect(m_selectedPoints).contains(mouseEvent->scenePos())))
|
||||||
|
{
|
||||||
|
updatePickSelectionPoints(mouseEvent->scenePos());
|
||||||
|
m_firstSelection = true;
|
||||||
|
}
|
||||||
|
m_pivot = calcBoundingRect(m_selectedPoints).center();
|
||||||
|
}
|
||||||
|
else if (mouseEvent->button() == Qt::RightButton)
|
||||||
|
{
|
||||||
|
updateSelectedPointItems(false);
|
||||||
|
m_selectedPoints.clear();
|
||||||
|
|
||||||
|
// Delete sub-points if it located under mouse
|
||||||
|
// Call method mousePressEvent for sub-point located under mouse
|
||||||
|
LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LandscapeEditor::LandscapeSceneBase::mousePressEvent(mouseEvent);
|
||||||
|
|
||||||
|
if (mouseEvent->button() != Qt::LeftButton)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((!m_editedSelectedItems && m_selectedItems.isEmpty()) ||
|
||||||
|
(!calcBoundingRect(m_selectedItems).contains(mouseEvent->scenePos())))
|
||||||
|
{
|
||||||
|
updatePickSelection(mouseEvent->scenePos());
|
||||||
|
m_firstSelection = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pivot = calcBoundingRect(m_selectedItems).center();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_editedSelectedItems = false;
|
||||||
|
m_offset = QPointF(0, 0);
|
||||||
|
m_angle = 0;
|
||||||
|
m_scaleFactor = QPointF(1.0, 1.0);
|
||||||
|
|
||||||
|
if (m_mode == WorldEditorScene::SelectMode)
|
||||||
|
m_selectionArea.setTopLeft(mouseEvent->scenePos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
if (QApplication::mouseButtons() == Qt::LeftButton)
|
||||||
|
{
|
||||||
|
m_selectionArea.setBottomRight(mouseEvent->scenePos());
|
||||||
|
switch (m_mode)
|
||||||
|
{
|
||||||
|
case WorldEditorScene::SelectMode:
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::MoveMode:
|
||||||
|
updateWorldItemsMove(mouseEvent);
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::RotateMode:
|
||||||
|
updateWorldItemsRotate(mouseEvent);
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::ScaleMode:
|
||||||
|
updateWorldItemsScale(mouseEvent);
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::TurnMode:
|
||||||
|
updateWorldItemsTurn(mouseEvent);
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::RadiusMode:
|
||||||
|
updateWorldItemsRadius(mouseEvent);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isEnabledEditPoints())
|
||||||
|
{
|
||||||
|
if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedPoints.isEmpty()))
|
||||||
|
m_editedSelectedItems = true;
|
||||||
|
else
|
||||||
|
m_editedSelectedItems = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((editMode() != WorldEditorScene::SelectMode) && (!m_selectedItems.isEmpty()))
|
||||||
|
m_editedSelectedItems = true;
|
||||||
|
else
|
||||||
|
m_editedSelectedItems = false;
|
||||||
|
}
|
||||||
|
// Update render (drawing selection area when enabled multiple selection mode)
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
LandscapeEditor::LandscapeSceneBase::mouseMoveEvent(mouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
if (mouseEvent->button() == Qt::MidButton)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mouseEvent->button() == Qt::LeftButton)
|
||||||
|
{
|
||||||
|
checkUndo();
|
||||||
|
|
||||||
|
// Update selection
|
||||||
|
if ((m_selectionArea.left() != 0) && (m_selectionArea.right() != 0))
|
||||||
|
{
|
||||||
|
QList<QGraphicsItem *> listItems;
|
||||||
|
|
||||||
|
// Clear selection
|
||||||
|
updateSelectedPointItems(false);
|
||||||
|
m_selectedPoints.clear();
|
||||||
|
|
||||||
|
// Return list of selected items
|
||||||
|
if (m_selectionArea.left() < m_selectionArea.right())
|
||||||
|
listItems = items(m_selectionArea, Qt::IntersectsItemShape, Qt::AscendingOrder);
|
||||||
|
else
|
||||||
|
listItems = items(m_selectionArea, Qt::ContainsItemShape, Qt::AscendingOrder);
|
||||||
|
|
||||||
|
if (isEnabledEditPoints())
|
||||||
|
{
|
||||||
|
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||||
|
{
|
||||||
|
if (qgraphicsitem_cast<WorldItemSubPoint *>(item) == 0)
|
||||||
|
continue;
|
||||||
|
m_selectedPoints.push_back(item);
|
||||||
|
}
|
||||||
|
updateSelectedPointItems(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||||
|
{
|
||||||
|
if (qgraphicsitem_cast<AbstractWorldItem *>(item) == 0)
|
||||||
|
continue;
|
||||||
|
m_selectedItems.push_back(item);
|
||||||
|
}
|
||||||
|
Q_EMIT updateSelectedItems(m_selectedItems);
|
||||||
|
updateSelectedWorldItems(true);
|
||||||
|
}
|
||||||
|
m_selectionArea = QRectF();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((!m_editedSelectedItems) && (!m_firstSelection))
|
||||||
|
{
|
||||||
|
if (isEnabledEditPoints())
|
||||||
|
updatePickSelectionPoints(mouseEvent->scenePos());
|
||||||
|
else
|
||||||
|
updatePickSelection(mouseEvent->scenePos());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_firstSelection = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEnabledEditPoints())
|
||||||
|
checkUndoPointsMode();
|
||||||
|
}
|
||||||
|
m_selectionArea = QRectF();
|
||||||
|
LandscapeEditor::LandscapeSceneBase::mouseReleaseEvent(mouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF WorldEditorScene::calcBoundingRect(const QList<QGraphicsItem *> &listItems)
|
||||||
|
{
|
||||||
|
QRectF rect;
|
||||||
|
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||||
|
{
|
||||||
|
QRectF itemRect = item->boundingRect();
|
||||||
|
rect = rect.united(itemRect.translated(item->scenePos()));
|
||||||
|
}
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath WorldEditorScene::calcBoundingShape(const QList<QGraphicsItem *> &listItems)
|
||||||
|
{
|
||||||
|
QPainterPath painterPath;
|
||||||
|
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||||
|
{
|
||||||
|
QPainterPath itemPath = item->shape();
|
||||||
|
painterPath = painterPath.united(itemPath.translated(item->scenePos()));
|
||||||
|
}
|
||||||
|
return painterPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateSelectedWorldItems(bool value)
|
||||||
|
{
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedItems)
|
||||||
|
{
|
||||||
|
updateSelectedWorldItem(item, value);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateSelectedWorldItem(QGraphicsItem *item, bool value)
|
||||||
|
{
|
||||||
|
AbstractWorldItem *worldItem = qgraphicsitem_cast<AbstractWorldItem *>(item);
|
||||||
|
if (worldItem != 0)
|
||||||
|
worldItem->setActived(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateSelectedPointItems(bool value)
|
||||||
|
{
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedPoints)
|
||||||
|
{
|
||||||
|
updateSelectedPointItem(item, value);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateSelectedPointItem(QGraphicsItem *item, bool value)
|
||||||
|
{
|
||||||
|
WorldItemSubPoint *worldItem = qgraphicsitem_cast<WorldItemSubPoint *>(item);
|
||||||
|
if (worldItem != 0)
|
||||||
|
worldItem->setActived(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updatePickSelection(const QPointF &point)
|
||||||
|
{
|
||||||
|
updateSelectedWorldItems(false);
|
||||||
|
m_selectedItems.clear();
|
||||||
|
|
||||||
|
QList<QGraphicsItem *> listItems = items(point, Qt::ContainsItemShape,
|
||||||
|
Qt::AscendingOrder);
|
||||||
|
|
||||||
|
QList<AbstractWorldItem *> worldItemsItems;
|
||||||
|
|
||||||
|
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||||
|
{
|
||||||
|
AbstractWorldItem *worldItem = qgraphicsitem_cast<AbstractWorldItem *>(item);
|
||||||
|
if (worldItem != 0)
|
||||||
|
worldItemsItems.push_back(worldItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!worldItemsItems.isEmpty())
|
||||||
|
{
|
||||||
|
// Next primitives
|
||||||
|
m_lastPickedPrimitive++;
|
||||||
|
m_lastPickedPrimitive %= worldItemsItems.size();
|
||||||
|
|
||||||
|
m_selectedItems.push_back(worldItemsItems.at(m_lastPickedPrimitive));
|
||||||
|
updateSelectedWorldItems(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT updateSelectedItems(m_selectedItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updatePickSelectionPoints(const QPointF &point)
|
||||||
|
{
|
||||||
|
updateSelectedPointItems(false);
|
||||||
|
m_selectedPoints.clear();
|
||||||
|
|
||||||
|
QList<QGraphicsItem *> listItems = items(point, Qt::IntersectsItemBoundingRect,
|
||||||
|
Qt::AscendingOrder);
|
||||||
|
|
||||||
|
QList<WorldItemSubPoint *> subPointsItems;
|
||||||
|
|
||||||
|
Q_FOREACH(QGraphicsItem *item, listItems)
|
||||||
|
{
|
||||||
|
WorldItemSubPoint *subPointItem = qgraphicsitem_cast<WorldItemSubPoint *>(item);
|
||||||
|
if (subPointItem != 0)
|
||||||
|
{
|
||||||
|
if (subPointItem->subPointType() == WorldItemSubPoint::EdgeType)
|
||||||
|
subPointsItems.push_back(subPointItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!subPointsItems.isEmpty())
|
||||||
|
{
|
||||||
|
// Next primitives
|
||||||
|
m_lastPickedPrimitive++;
|
||||||
|
m_lastPickedPrimitive %= subPointsItems.size();
|
||||||
|
|
||||||
|
m_selectedPoints.push_back(subPointsItems.at(m_lastPickedPrimitive));
|
||||||
|
updateSelectedPointItems(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::checkUndo()
|
||||||
|
{
|
||||||
|
if (m_editedSelectedItems && (!isEnabledEditPoints()))
|
||||||
|
{
|
||||||
|
switch (m_mode)
|
||||||
|
{
|
||||||
|
case WorldEditorScene::SelectMode:
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::MoveMode:
|
||||||
|
m_undoStack->push(new MoveWorldItemsCommand(m_selectedItems, m_offset, this, m_model));
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::RotateMode:
|
||||||
|
m_undoStack->push(new RotateWorldItemsCommand(m_selectedItems, m_angle, m_pivot, this, m_model));
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::ScaleMode:
|
||||||
|
m_undoStack->push(new ScaleWorldItemsCommand(m_selectedItems, m_scaleFactor, m_pivot, this, m_model));
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::TurnMode:
|
||||||
|
m_undoStack->push(new TurnWorldItemsCommand(m_selectedItems, m_angle, this, m_model));
|
||||||
|
break;
|
||||||
|
case WorldEditorScene::RadiusMode:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::checkUndoPointsMode()
|
||||||
|
{
|
||||||
|
if (m_pointsMode)
|
||||||
|
{
|
||||||
|
QList<QGraphicsItem *> items;
|
||||||
|
QList<QPolygonF> polygons;
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedItems)
|
||||||
|
{
|
||||||
|
AbstractWorldItem *worldItem = qgraphicsitem_cast<AbstractWorldItem *>(item);
|
||||||
|
if (worldItem->isShapeChanged())
|
||||||
|
{
|
||||||
|
items.push_back(item);
|
||||||
|
polygons.push_back(m_polygons.at(m_selectedItems.indexOf(item)));
|
||||||
|
worldItem->setShapeChanged(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!items.isEmpty())
|
||||||
|
{
|
||||||
|
m_undoStack->push(new ShapeWorldItemsCommand(items, polygons, this, m_model));
|
||||||
|
m_polygons.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateWorldItemsMove(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
QPointF offset = mouseEvent->scenePos() - mouseEvent->lastScenePos();
|
||||||
|
m_offset += offset;
|
||||||
|
if (m_pointsMode)
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedPoints)
|
||||||
|
{
|
||||||
|
item->moveBy(offset.x(), offset.y());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedItems)
|
||||||
|
{
|
||||||
|
item->moveBy(offset.x(), offset.y());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateWorldItemsScale(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
QPointF offset(mouseEvent->scenePos() - mouseEvent->lastScenePos());
|
||||||
|
|
||||||
|
qreal scaleRatio = 5000;
|
||||||
|
|
||||||
|
// Calculate scale factor
|
||||||
|
if (offset.x() > 0)
|
||||||
|
offset.setX(1.0 + (offset.x() / scaleRatio));
|
||||||
|
else
|
||||||
|
offset.setX(1.0 / (1.0 + (-offset.x() / scaleRatio)));
|
||||||
|
|
||||||
|
if (offset.y() < 0)
|
||||||
|
offset.setY(1.0 - (offset.y() / scaleRatio));
|
||||||
|
else
|
||||||
|
offset.setY(1.0 / (1.0 + (offset.y() / scaleRatio)));
|
||||||
|
|
||||||
|
m_scaleFactor.setX(offset.x() * m_scaleFactor.x());
|
||||||
|
m_scaleFactor.setY(offset.y() * m_scaleFactor.y());
|
||||||
|
|
||||||
|
if (m_pointsMode)
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedPoints)
|
||||||
|
{
|
||||||
|
qgraphicsitem_cast<WorldItemSubPoint *>(item)->scaleOn(m_pivot, offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedItems)
|
||||||
|
{
|
||||||
|
qgraphicsitem_cast<AbstractWorldItem *>(item)->scaleOn(m_pivot, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateWorldItemsRotate(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
// Caluculate angle between two line
|
||||||
|
QLineF firstLine(m_pivot, mouseEvent->lastScenePos());
|
||||||
|
QLineF secondLine(m_pivot, mouseEvent->scenePos());
|
||||||
|
qreal angle = secondLine.angleTo(firstLine);
|
||||||
|
m_angle += angle;
|
||||||
|
|
||||||
|
if (m_pointsMode)
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedPoints)
|
||||||
|
{
|
||||||
|
qgraphicsitem_cast<WorldItemSubPoint *>(item)->rotateOn(m_pivot, angle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedItems)
|
||||||
|
{
|
||||||
|
qgraphicsitem_cast<AbstractWorldItem *>(item)->rotateOn(m_pivot, angle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateWorldItemsTurn(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
// Caluculate angle between two line
|
||||||
|
QLineF firstLine(m_pivot, mouseEvent->lastScenePos());
|
||||||
|
QLineF secondLine(m_pivot, mouseEvent->scenePos());
|
||||||
|
qreal angle = secondLine.angleTo(firstLine);
|
||||||
|
m_angle += angle;
|
||||||
|
|
||||||
|
Q_FOREACH(QGraphicsItem *item, m_selectedItems)
|
||||||
|
{
|
||||||
|
qgraphicsitem_cast<AbstractWorldItem *>(item)->turnOn(angle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorScene::updateWorldItemsRadius(QGraphicsSceneMouseEvent *mouseEvent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,142 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef WORLD_EDITOR_SCENE_H
|
||||||
|
#define WORLD_EDITOR_SCENE_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_global.h"
|
||||||
|
|
||||||
|
#include "../landscape_editor/landscape_scene_base.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QUndoStack>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
class PrimitivesTreeModel;
|
||||||
|
class AbstractWorldItem;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class WorldEditorScene
|
||||||
|
@brief The WorldEditorScene provides a surface for managing a large number of 2D world items(point/path/zone).
|
||||||
|
@details WorldEditorScene also provides 'selections model' functionality, which differs from standart selection model.
|
||||||
|
*/
|
||||||
|
class WORLD_EDITOR_EXPORT WorldEditorScene : public LandscapeEditor::LandscapeSceneBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ModeEdit
|
||||||
|
{
|
||||||
|
SelectMode = 0,
|
||||||
|
MoveMode,
|
||||||
|
RotateMode,
|
||||||
|
ScaleMode,
|
||||||
|
TurnMode,
|
||||||
|
RadiusMode
|
||||||
|
};
|
||||||
|
|
||||||
|
WorldEditorScene(int sizeCell, PrimitivesTreeModel *model,
|
||||||
|
QUndoStack *undoStack, QObject *parent = 0);
|
||||||
|
virtual ~WorldEditorScene();
|
||||||
|
|
||||||
|
/// Create WorldItemPoint and add in scene.
|
||||||
|
AbstractWorldItem *addWorldItemPoint(const QPointF &point, const qreal angle,
|
||||||
|
const qreal radius, bool showArrow);
|
||||||
|
|
||||||
|
/// Create WorldItemPath and add in scene.
|
||||||
|
AbstractWorldItem *addWorldItemPath(const QPolygonF &polyline, bool showArrow);
|
||||||
|
|
||||||
|
/// Create WorldItemZone and add in scene.
|
||||||
|
AbstractWorldItem *addWorldItemZone(const QPolygonF &polygon);
|
||||||
|
|
||||||
|
/// Remove a world item from the scene.
|
||||||
|
void removeWorldItem(QGraphicsItem *item);
|
||||||
|
|
||||||
|
/// Set current mode editing(select/move/rotate/scale/turn), above world items.
|
||||||
|
void setModeEdit(WorldEditorScene::ModeEdit mode);
|
||||||
|
|
||||||
|
WorldEditorScene::ModeEdit editMode() const;
|
||||||
|
|
||||||
|
/// @return true if edit points mode is enabled, else false.
|
||||||
|
bool isEnabledEditPoints() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
/// This signal is emitted by WorldEditorScene when the selections changes.
|
||||||
|
/// The @selected value contains a list of all selected items.
|
||||||
|
void updateSelectedItems(const QList<QGraphicsItem *> &selected);
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
/// Enable/disable edit points mode (user can change shape of WorldItemZone and WorldItemPath)
|
||||||
|
///
|
||||||
|
void setEnabledEditPoints(bool enabled);
|
||||||
|
|
||||||
|
/// Update of selections
|
||||||
|
void updateSelection(const QList<QGraphicsItem *> &selected, const QList<QGraphicsItem *> &deselected);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void drawForeground(QPainter *painter, const QRectF &rect);
|
||||||
|
|
||||||
|
virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QRectF calcBoundingRect(const QList<QGraphicsItem *> &listItems);
|
||||||
|
QPainterPath calcBoundingShape(const QList<QGraphicsItem *> &listItems);
|
||||||
|
|
||||||
|
void updateSelectedWorldItems(bool value);
|
||||||
|
void updateSelectedWorldItem(QGraphicsItem *item, bool value);
|
||||||
|
void updateSelectedPointItems(bool value);
|
||||||
|
void updateSelectedPointItem(QGraphicsItem *item, bool value);
|
||||||
|
|
||||||
|
void updatePickSelection(const QPointF &point);
|
||||||
|
void updatePickSelectionPoints(const QPointF &point);
|
||||||
|
|
||||||
|
void checkUndo();
|
||||||
|
void checkUndoPointsMode();
|
||||||
|
|
||||||
|
void updateWorldItemsMove(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
void updateWorldItemsScale(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
void updateWorldItemsRotate(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
void updateWorldItemsTurn(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
void updateWorldItemsRadius(QGraphicsSceneMouseEvent *mouseEvent);
|
||||||
|
|
||||||
|
QPen m_greenPen, m_purplePen;
|
||||||
|
QBrush m_greenBrush, m_purpleBrush;
|
||||||
|
|
||||||
|
QPointF m_firstPick, m_scaleFactor, m_pivot, m_offset;
|
||||||
|
QRectF m_selectionArea;
|
||||||
|
qreal m_firstPickX, m_firstPickY, m_angle;
|
||||||
|
|
||||||
|
QList<QGraphicsItem *> m_selectedItems;
|
||||||
|
QList<QGraphicsItem *> m_selectedPoints;
|
||||||
|
QList<QPolygonF> m_polygons;
|
||||||
|
|
||||||
|
bool m_editedSelectedItems, m_firstSelection;
|
||||||
|
uint m_lastPickedPrimitive;
|
||||||
|
ModeEdit m_mode;
|
||||||
|
bool m_pointsMode;
|
||||||
|
QUndoStack *m_undoStack;
|
||||||
|
PrimitivesTreeModel *m_model;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
#endif // WORLD_EDITOR_SCENE_H
|
|
@ -0,0 +1,741 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_scene_item.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
#include <nel/misc/debug.h>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QPainter>
|
||||||
|
#include <QtCore/QRectF>
|
||||||
|
#include <QPolygonF>
|
||||||
|
#include <QTransform>
|
||||||
|
#include <QStyleOptionGraphicsItem>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
|
||||||
|
{
|
||||||
|
// We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
|
||||||
|
// if we pass a value of 0.0 to QPainterPathStroker::setWidth()
|
||||||
|
const qreal penWidthZero = qreal(0.00000001);
|
||||||
|
|
||||||
|
if (path == QPainterPath())
|
||||||
|
return path;
|
||||||
|
QPainterPathStroker ps;
|
||||||
|
ps.setCapStyle(pen.capStyle());
|
||||||
|
if (pen.widthF() <= 0.0)
|
||||||
|
ps.setWidth(penWidthZero);
|
||||||
|
else
|
||||||
|
ps.setWidth(pen.widthF());
|
||||||
|
ps.setJoinStyle(pen.joinStyle());
|
||||||
|
ps.setMiterLimit(pen.miterLimit());
|
||||||
|
QPainterPath p = ps.createStroke(path);
|
||||||
|
p.addPath(path);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractWorldItem::AbstractWorldItem(QGraphicsItem *parent)
|
||||||
|
: QGraphicsItem(parent),
|
||||||
|
m_active(false),
|
||||||
|
m_shapeChanged(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractWorldItem::~AbstractWorldItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int AbstractWorldItem::type() const
|
||||||
|
{
|
||||||
|
return Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractWorldItem::setActived(bool actived)
|
||||||
|
{
|
||||||
|
m_active = actived;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AbstractWorldItem::isActived() const
|
||||||
|
{
|
||||||
|
return m_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractWorldItem::setShapeChanged(bool value)
|
||||||
|
{
|
||||||
|
m_shapeChanged = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AbstractWorldItem::isShapeChanged() const
|
||||||
|
{
|
||||||
|
return m_shapeChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldItemPoint::WorldItemPoint(const QPointF &point, const qreal angle, const qreal radius,
|
||||||
|
bool showArrow, QGraphicsItem *parent)
|
||||||
|
: AbstractWorldItem(parent),
|
||||||
|
m_angle(angle),
|
||||||
|
m_radius(radius),
|
||||||
|
m_showArrow(showArrow)
|
||||||
|
{
|
||||||
|
setZValue(WORLD_POINT_LAYER);
|
||||||
|
|
||||||
|
//setFlag(ItemIgnoresTransformations);
|
||||||
|
|
||||||
|
setPos(point);
|
||||||
|
|
||||||
|
m_rect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT);
|
||||||
|
|
||||||
|
m_pen.setColor(QColor(255, 100, 10));
|
||||||
|
//m_pen.setWidth(0);
|
||||||
|
|
||||||
|
m_selectedPen.setColor(Qt::white);
|
||||||
|
//m_selectedPen.setWidth(0);
|
||||||
|
|
||||||
|
m_brush.setColor(QColor(255, 100, 10));
|
||||||
|
m_brush.setStyle(Qt::SolidPattern);
|
||||||
|
|
||||||
|
m_selectedBrush.setColor(Qt::white);
|
||||||
|
m_selectedBrush.setStyle(Qt::SolidPattern);
|
||||||
|
|
||||||
|
createCircle();
|
||||||
|
|
||||||
|
// Create arrow
|
||||||
|
if (showArrow)
|
||||||
|
{
|
||||||
|
m_arrow.push_back(QLine(0, 0, SIZE_ARROW, 0));
|
||||||
|
m_arrow.push_back(QLine(SIZE_ARROW - 2, -2, SIZE_ARROW, 0));
|
||||||
|
m_arrow.push_back(QLine(SIZE_ARROW - 2, 2, SIZE_ARROW, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
updateBoundingRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldItemPoint::~WorldItemPoint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal WorldItemPoint::angle() const
|
||||||
|
{
|
||||||
|
return m_angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
QPolygonF rotatedPolygon(m_rect);
|
||||||
|
|
||||||
|
rotatedPolygon.translate(pos() - pivot);
|
||||||
|
|
||||||
|
QTransform trans;
|
||||||
|
trans = trans.rotate(deltaAngle);
|
||||||
|
rotatedPolygon = trans.map(rotatedPolygon);
|
||||||
|
rotatedPolygon.translate(pivot);
|
||||||
|
|
||||||
|
setPos(rotatedPolygon.boundingRect().center());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPoint::scaleOn(const QPointF &pivot, const QPointF &factor)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
QPolygonF scaledPolygon(m_rect);
|
||||||
|
|
||||||
|
scaledPolygon.translate(pos() - pivot);
|
||||||
|
|
||||||
|
QTransform trans;
|
||||||
|
trans = trans.scale(factor.x(), factor.y());
|
||||||
|
scaledPolygon = trans.map(scaledPolygon);
|
||||||
|
scaledPolygon.translate(pivot);
|
||||||
|
|
||||||
|
setPos(scaledPolygon.boundingRect().center());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPoint::turnOn(const qreal angle)
|
||||||
|
{
|
||||||
|
m_angle += angle;
|
||||||
|
m_angle -= floor(m_angle / 360) * 360;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPoint::radiusOn(const qreal radius)
|
||||||
|
{
|
||||||
|
if (m_radius == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPoint::setColor(const QColor &color)
|
||||||
|
{
|
||||||
|
m_pen.setColor(color);
|
||||||
|
m_brush.setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPoint::setPolygon(const QPolygonF &polygon)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QPolygonF WorldItemPoint::polygon() const
|
||||||
|
{
|
||||||
|
QPolygonF polygon;
|
||||||
|
polygon << QPointF(0, 0);
|
||||||
|
return polygon;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPoint::createCircle()
|
||||||
|
{
|
||||||
|
if (m_radius != 0)
|
||||||
|
{
|
||||||
|
// Create circle
|
||||||
|
int segmentCount = 20;
|
||||||
|
QPointF circlePoint(m_radius, 0);
|
||||||
|
m_circle << circlePoint;
|
||||||
|
for (int i = 1; i < segmentCount + 1; ++i)
|
||||||
|
{
|
||||||
|
qreal angle = i * (2 * NLMISC::Pi / segmentCount);
|
||||||
|
circlePoint.setX(cos(angle) * m_radius);
|
||||||
|
circlePoint.setY(sin(angle) * m_radius);
|
||||||
|
m_circle << circlePoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPoint::updateBoundingRect()
|
||||||
|
{
|
||||||
|
m_boundingRect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT);
|
||||||
|
QRectF circleBoundingRect;
|
||||||
|
circleBoundingRect.setCoords(-m_radius, -m_radius, m_radius, m_radius);
|
||||||
|
m_boundingRect = m_boundingRect.united(circleBoundingRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath WorldItemPoint::shape() const
|
||||||
|
{
|
||||||
|
QPainterPath path;
|
||||||
|
|
||||||
|
path.addRect(m_boundingRect);
|
||||||
|
return qt_graphicsItem_shapeFromPath(path, m_pen);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF WorldItemPoint::boundingRect() const
|
||||||
|
{
|
||||||
|
return m_boundingRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
|
||||||
|
{
|
||||||
|
painter->setPen(m_pen);
|
||||||
|
|
||||||
|
// Draw circle
|
||||||
|
// Draws artefacts with using opengl painter
|
||||||
|
// painter->drawEllipse(-m_radius / 2, -m_radius / 2, m_radius, m_radius);
|
||||||
|
painter->drawPolygon(m_circle);
|
||||||
|
|
||||||
|
painter->rotate(m_angle);
|
||||||
|
|
||||||
|
// Draw arrow
|
||||||
|
painter->drawLines(m_arrow);
|
||||||
|
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
if (isActived())
|
||||||
|
painter->setBrush(m_selectedBrush);
|
||||||
|
else
|
||||||
|
painter->setBrush(m_brush);
|
||||||
|
|
||||||
|
// Draw point
|
||||||
|
painter->drawRect(m_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseWorldItemPolyline::BaseWorldItemPolyline(const QPolygonF &polygon, QGraphicsItem *parent)
|
||||||
|
: AbstractWorldItem(parent),
|
||||||
|
m_polyline(polygon),
|
||||||
|
m_pointEdit(false)
|
||||||
|
{
|
||||||
|
//setFlag(ItemIsSelectable);
|
||||||
|
QPointF center = m_polyline.boundingRect().center();
|
||||||
|
m_polyline.translate(-center);
|
||||||
|
setPos(center);
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseWorldItemPolyline::~BaseWorldItemPolyline()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorldItemPolyline::rotateOn(const QPointF &pivot, const qreal deltaAngle)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
QPolygonF rotatedPolygon(m_polyline);
|
||||||
|
rotatedPolygon.translate(pos() - pivot);
|
||||||
|
|
||||||
|
QTransform trans;
|
||||||
|
trans = trans.rotate(deltaAngle);
|
||||||
|
m_polyline = trans.map(rotatedPolygon);
|
||||||
|
|
||||||
|
m_polyline.translate(pivot - pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorldItemPolyline::scaleOn(const QPointF &pivot, const QPointF &factor)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
QPolygonF scaledPolygon(m_polyline);
|
||||||
|
scaledPolygon.translate(pos() - pivot);
|
||||||
|
|
||||||
|
QTransform trans;
|
||||||
|
trans = trans.scale(factor.x(), factor.y());
|
||||||
|
m_polyline = trans.map(scaledPolygon);
|
||||||
|
|
||||||
|
m_polyline.translate(pivot - pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorldItemPolyline::setEnabledSubPoints(bool enabled)
|
||||||
|
{
|
||||||
|
m_pointEdit = enabled;
|
||||||
|
if (m_pointEdit)
|
||||||
|
createSubPoints();
|
||||||
|
else
|
||||||
|
removeSubPoints();
|
||||||
|
|
||||||
|
setShapeChanged(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorldItemPolyline::moveSubPoint(WorldItemSubPoint *subPoint)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
QPolygonF polygon;
|
||||||
|
|
||||||
|
// Update polygon
|
||||||
|
Q_FOREACH(WorldItemSubPoint *node, m_listItems)
|
||||||
|
{
|
||||||
|
polygon << node->pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update middle points
|
||||||
|
for (int i = 0; i < m_listLines.size(); ++i)
|
||||||
|
m_listLines.at(i).itemPoint->setPos((m_listLines.at(i).lineItem.first->pos() + m_listLines.at(i).lineItem.second->pos()) / 2);
|
||||||
|
|
||||||
|
m_polyline = polygon;
|
||||||
|
setShapeChanged(true);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorldItemPolyline::addSubPoint(WorldItemSubPoint *subPoint)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
for (int i = 0; i < m_listLines.size(); ++i)
|
||||||
|
{
|
||||||
|
if (subPoint == m_listLines.at(i).itemPoint)
|
||||||
|
{
|
||||||
|
LineStruct oldLineItem = m_listLines[i];
|
||||||
|
|
||||||
|
// Create the first middle sub-point
|
||||||
|
WorldItemSubPoint *firstItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this);
|
||||||
|
firstItem->setPos((oldLineItem.lineItem.first->pos() + subPoint->pos()) / 2);
|
||||||
|
|
||||||
|
// Create the second middle sub-point
|
||||||
|
WorldItemSubPoint *secondItem = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this);
|
||||||
|
secondItem->setPos((oldLineItem.lineItem.second->pos() + subPoint->pos()) / 2);
|
||||||
|
|
||||||
|
// Add first line in the list
|
||||||
|
LineStruct firstNewLineItem;
|
||||||
|
firstNewLineItem.itemPoint = firstItem;
|
||||||
|
firstNewLineItem.lineItem = LineItem(oldLineItem.lineItem.first, subPoint);
|
||||||
|
m_listLines.push_back(firstNewLineItem);
|
||||||
|
|
||||||
|
// Add second line in the list
|
||||||
|
LineStruct secondNewLineItem;
|
||||||
|
secondNewLineItem.itemPoint = secondItem;
|
||||||
|
secondNewLineItem.lineItem = LineItem(subPoint, oldLineItem.lineItem.second);
|
||||||
|
m_listLines.push_back(secondNewLineItem);
|
||||||
|
|
||||||
|
m_listLines.removeAt(i);
|
||||||
|
|
||||||
|
int pos = m_listItems.indexOf(oldLineItem.lineItem.second);
|
||||||
|
m_listItems.insert(pos, subPoint);
|
||||||
|
subPoint->setFlag(ItemSendsScenePositionChanges);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setShapeChanged(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseWorldItemPolyline::removeSubPoint(WorldItemSubPoint *subPoint)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
int pos = m_listItems.indexOf(subPoint);
|
||||||
|
m_listItems.takeAt(pos);
|
||||||
|
LineStruct newLineItem;
|
||||||
|
newLineItem.itemPoint = subPoint;
|
||||||
|
|
||||||
|
// Delete first line
|
||||||
|
for (int i = 0; i < m_listLines.size(); ++i)
|
||||||
|
{
|
||||||
|
if (subPoint == m_listLines.at(i).lineItem.first)
|
||||||
|
{
|
||||||
|
// Saving second point for new line
|
||||||
|
newLineItem.lineItem.second = m_listLines.at(i).lineItem.second;
|
||||||
|
delete m_listLines.at(i).itemPoint;
|
||||||
|
m_listLines.removeAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete second line
|
||||||
|
for (int i = 0; i < m_listLines.size(); ++i)
|
||||||
|
{
|
||||||
|
if (subPoint == m_listLines.at(i).lineItem.second)
|
||||||
|
{
|
||||||
|
// Saving first point for new line
|
||||||
|
newLineItem.lineItem.first = m_listLines.at(i).lineItem.first;
|
||||||
|
delete m_listLines.at(i).itemPoint;
|
||||||
|
m_listLines.removeAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subPoint->setPos((newLineItem.lineItem.first->pos() + newLineItem.lineItem.second->pos()) / 2);
|
||||||
|
m_listLines.push_back(newLineItem);
|
||||||
|
subPoint->setFlag(ItemSendsScenePositionChanges, false);
|
||||||
|
setShapeChanged(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorldItemPolyline::setPolygon(const QPolygonF &polygon)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
m_polyline = polygon;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPolygonF BaseWorldItemPolyline::polygon() const
|
||||||
|
{
|
||||||
|
return m_polyline;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF BaseWorldItemPolyline::boundingRect() const
|
||||||
|
{
|
||||||
|
return m_polyline.boundingRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorldItemPolyline::createSubPoints()
|
||||||
|
{
|
||||||
|
WorldItemSubPoint *firstPoint;
|
||||||
|
firstPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this);
|
||||||
|
firstPoint->setPos(m_polyline.front());
|
||||||
|
firstPoint->setFlag(ItemSendsScenePositionChanges);
|
||||||
|
m_listItems.push_back(firstPoint);
|
||||||
|
|
||||||
|
for (int i = 1; i < m_polyline.count(); ++i)
|
||||||
|
{
|
||||||
|
WorldItemSubPoint *secondPoint = new WorldItemSubPoint(WorldItemSubPoint::EdgeType, this);
|
||||||
|
secondPoint->setPos(m_polyline.at(i));
|
||||||
|
secondPoint->setFlag(ItemSendsScenePositionChanges);
|
||||||
|
|
||||||
|
WorldItemSubPoint *middlePoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this);
|
||||||
|
middlePoint->setPos((firstPoint->pos() + secondPoint->pos()) / 2);
|
||||||
|
|
||||||
|
LineStruct newLineItem;
|
||||||
|
newLineItem.itemPoint = middlePoint;
|
||||||
|
newLineItem.lineItem = LineItem(firstPoint, secondPoint);
|
||||||
|
m_listLines.push_back(newLineItem);
|
||||||
|
|
||||||
|
firstPoint = secondPoint;
|
||||||
|
m_listItems.push_back(firstPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseWorldItemPolyline::removeSubPoints()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_listLines.count(); ++i)
|
||||||
|
delete m_listLines.at(i).itemPoint;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_listItems.count(); ++i)
|
||||||
|
delete m_listItems.at(i);
|
||||||
|
|
||||||
|
m_listItems.clear();
|
||||||
|
m_listLines.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldItemPath::WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent)
|
||||||
|
: BaseWorldItemPolyline(polygon, parent)
|
||||||
|
{
|
||||||
|
setZValue(WORLD_PATH_LAYER);
|
||||||
|
|
||||||
|
m_pen.setColor(Qt::black);
|
||||||
|
m_pen.setWidth(3);
|
||||||
|
m_pen.setJoinStyle(Qt::MiterJoin);
|
||||||
|
|
||||||
|
m_selectedPen.setColor(Qt::white);
|
||||||
|
m_selectedPen.setWidth(3);
|
||||||
|
m_selectedPen.setJoinStyle(Qt::MiterJoin);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldItemPath::~WorldItemPath()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPath::setColor(const QColor &color)
|
||||||
|
{
|
||||||
|
m_pen.setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WorldItemPath::removeSubPoint(WorldItemSubPoint *subPoint)
|
||||||
|
{
|
||||||
|
int pos = m_listItems.indexOf(subPoint);
|
||||||
|
|
||||||
|
// First and second points can not be removed
|
||||||
|
if ((pos == 0) || (pos == m_listItems.size() - 1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return BaseWorldItemPolyline::removeSubPoint(subPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath WorldItemPath::shape() const
|
||||||
|
{
|
||||||
|
QPainterPath path;
|
||||||
|
|
||||||
|
path.moveTo(m_polyline.first());
|
||||||
|
for (int i = 1; i < m_polyline.count(); ++i)
|
||||||
|
path.lineTo(m_polyline.at(i));
|
||||||
|
|
||||||
|
return qt_graphicsItem_shapeFromPath(path, m_pen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemPath::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
|
||||||
|
{
|
||||||
|
if (isActived())
|
||||||
|
painter->setPen(m_selectedPen);
|
||||||
|
else
|
||||||
|
painter->setPen(m_pen);
|
||||||
|
|
||||||
|
painter->drawPolyline(m_polyline);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WorldItemZone::WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent)
|
||||||
|
: BaseWorldItemPolyline(polygon, parent)
|
||||||
|
{
|
||||||
|
setZValue(WORLD_ZONE_LAYER);
|
||||||
|
|
||||||
|
m_pen.setColor(QColor(20, 100, 255));
|
||||||
|
m_pen.setWidth(0);
|
||||||
|
m_selectedPen.setColor(Qt::white);
|
||||||
|
m_selectedPen.setWidth(0);
|
||||||
|
m_brush.setColor(QColor(20, 100, 255, TRANSPARENCY));
|
||||||
|
m_brush.setStyle(Qt::SolidPattern);
|
||||||
|
m_selectedBrush.setColor(QColor(255, 255, 255, 100));
|
||||||
|
m_selectedBrush.setStyle(Qt::SolidPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldItemZone::~WorldItemZone()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemZone::setColor(const QColor &color)
|
||||||
|
{
|
||||||
|
m_pen.setColor(color);
|
||||||
|
QColor brushColor(color);
|
||||||
|
brushColor.setAlpha(TRANSPARENCY);
|
||||||
|
m_brush.setColor(brushColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WorldItemZone::removeSubPoint(WorldItemSubPoint *subPoint)
|
||||||
|
{
|
||||||
|
if (m_listItems.size() < 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return BaseWorldItemPolyline::removeSubPoint(subPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath WorldItemZone::shape() const
|
||||||
|
{
|
||||||
|
QPainterPath path;
|
||||||
|
path.addPolygon(m_polyline);
|
||||||
|
return qt_graphicsItem_shapeFromPath(path, m_pen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemZone::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
|
||||||
|
{
|
||||||
|
if (isActived())
|
||||||
|
{
|
||||||
|
painter->setPen(m_selectedPen);
|
||||||
|
painter->setBrush(m_selectedBrush);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
painter->setPen(m_pen);
|
||||||
|
painter->setBrush(m_brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->drawPolygon(m_polyline);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemZone::createSubPoints()
|
||||||
|
{
|
||||||
|
BaseWorldItemPolyline::createSubPoints();
|
||||||
|
|
||||||
|
LineStruct endLineItem;
|
||||||
|
endLineItem.itemPoint = new WorldItemSubPoint(WorldItemSubPoint::MiddleType, this);
|
||||||
|
endLineItem.itemPoint->setPos((m_listItems.first()->pos() + m_listItems.last()->pos()) / 2);
|
||||||
|
endLineItem.lineItem = LineItem(m_listItems.last(), m_listItems.first());
|
||||||
|
m_listLines.push_back(endLineItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*******************************************
|
||||||
|
|
||||||
|
WorldItemSubPoint::WorldItemSubPoint(SubPointType pointType, AbstractWorldItem *parent)
|
||||||
|
: QGraphicsObject(parent),
|
||||||
|
m_type(pointType),
|
||||||
|
m_active(false),
|
||||||
|
m_parent(parent)
|
||||||
|
{
|
||||||
|
setZValue(WORLD_POINT_LAYER);
|
||||||
|
|
||||||
|
m_brush.setColor(QColor(20, 100, 255));
|
||||||
|
m_brush.setStyle(Qt::SolidPattern);
|
||||||
|
|
||||||
|
m_brushMiddle.setColor(QColor(255, 25, 100));
|
||||||
|
m_brushMiddle.setStyle(Qt::SolidPattern);
|
||||||
|
|
||||||
|
m_selectedBrush.setColor(QColor(255, 255, 255, 100));
|
||||||
|
m_selectedBrush.setStyle(Qt::SolidPattern);
|
||||||
|
|
||||||
|
m_rect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT);
|
||||||
|
updateBoundingRect();
|
||||||
|
|
||||||
|
//setFlag(ItemIgnoresTransformations);
|
||||||
|
//setFlag(ItemSendsScenePositionChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldItemSubPoint::~WorldItemSubPoint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemSubPoint::setSubPointType(SubPointType nodeType)
|
||||||
|
{
|
||||||
|
m_type = nodeType;
|
||||||
|
setFlag(ItemSendsScenePositionChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldItemSubPoint::SubPointType WorldItemSubPoint::subPointType() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemSubPoint::rotateOn(const QPointF &pivot, const qreal deltaAngle)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
QPolygonF rotatedPolygon(m_rect);
|
||||||
|
rotatedPolygon.translate(scenePos() - pivot);
|
||||||
|
|
||||||
|
QTransform trans;
|
||||||
|
trans = trans.rotate(deltaAngle);
|
||||||
|
rotatedPolygon = trans.map(rotatedPolygon);
|
||||||
|
rotatedPolygon.translate(pivot);
|
||||||
|
|
||||||
|
setPos(m_parent->mapFromParent(rotatedPolygon.boundingRect().center()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemSubPoint::scaleOn(const QPointF &pivot, const QPointF &factor)
|
||||||
|
{
|
||||||
|
prepareGeometryChange();
|
||||||
|
|
||||||
|
QPolygonF scaledPolygon(m_rect);
|
||||||
|
scaledPolygon.translate(scenePos() - pivot);
|
||||||
|
|
||||||
|
QTransform trans;
|
||||||
|
trans = trans.scale(factor.x(), factor.y());
|
||||||
|
scaledPolygon = trans.map(scaledPolygon);
|
||||||
|
scaledPolygon.translate(pivot);
|
||||||
|
|
||||||
|
setPos(m_parent->mapFromParent(scaledPolygon.boundingRect().center()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF WorldItemSubPoint::boundingRect() const
|
||||||
|
{
|
||||||
|
return m_boundingRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemSubPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||||
|
{
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
if (m_type == WorldItemSubPoint::EdgeType)
|
||||||
|
{
|
||||||
|
if (isActived())
|
||||||
|
painter->setBrush(m_selectedBrush);
|
||||||
|
else
|
||||||
|
painter->setBrush(m_brush);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
painter->setBrush(m_brushMiddle);
|
||||||
|
|
||||||
|
// Draw point
|
||||||
|
painter->drawRect(m_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WorldItemSubPoint::type() const
|
||||||
|
{
|
||||||
|
return Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemSubPoint::setActived(bool actived)
|
||||||
|
{
|
||||||
|
m_active = actived;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WorldItemSubPoint::isActived() const
|
||||||
|
{
|
||||||
|
return m_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant WorldItemSubPoint::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||||
|
{
|
||||||
|
if (change == ItemPositionHasChanged)
|
||||||
|
m_parent->moveSubPoint(this);
|
||||||
|
return QGraphicsItem::itemChange(change, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemSubPoint::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
|
{
|
||||||
|
if ((m_type == MiddleType) && (event->button() == Qt::LeftButton))
|
||||||
|
{
|
||||||
|
m_parent->addSubPoint(this);
|
||||||
|
setSubPointType(EdgeType);
|
||||||
|
}
|
||||||
|
else if ((m_type == EdgeType) && (event->button() == Qt::RightButton))
|
||||||
|
{
|
||||||
|
if (m_parent->removeSubPoint(this))
|
||||||
|
setSubPointType(MiddleType);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldItemSubPoint::updateBoundingRect()
|
||||||
|
{
|
||||||
|
m_boundingRect.setCoords(-SIZE_POINT, -SIZE_POINT, SIZE_POINT, SIZE_POINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,298 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef WORLD_EDITOR_SCENE_ITEM_H
|
||||||
|
#define WORLD_EDITOR_SCENE_ITEM_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_global.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QPair>
|
||||||
|
#include <QtGui/QGraphicsObject>
|
||||||
|
#include <QtGui/QGraphicsScene>
|
||||||
|
#include <QtGui/QGraphicsPolygonItem>
|
||||||
|
#include <QtGui/QGraphicsRectItem>
|
||||||
|
#include <QtGui/QGraphicsSceneMouseEvent>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
class WorldItemSubPoint;
|
||||||
|
|
||||||
|
typedef QPair<WorldItemSubPoint *, WorldItemSubPoint *> LineItem;
|
||||||
|
|
||||||
|
struct LineStruct
|
||||||
|
{
|
||||||
|
WorldItemSubPoint *itemPoint;
|
||||||
|
LineItem lineItem;
|
||||||
|
};
|
||||||
|
|
||||||
|
const int SELECTED_LAYER = 200;
|
||||||
|
const int UNSELECTED_LAYER = 100;
|
||||||
|
const int WORLD_ZONE_LAYER = 100;
|
||||||
|
const int WORLD_POINT_LAYER = 200;
|
||||||
|
const int WORLD_PATH_LAYER = 200;
|
||||||
|
const int MIDDLE_POINT_LAYER = 201;
|
||||||
|
const int EDGE_POINT_LAYER = 201;
|
||||||
|
|
||||||
|
const int SIZE_ARROW = 20;
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class AbstractWorldItem
|
||||||
|
@brief Abstract class for graphics item
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class AbstractWorldItem: public QGraphicsItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AbstractWorldItem(QGraphicsItem *parent = 0);
|
||||||
|
virtual ~AbstractWorldItem();
|
||||||
|
|
||||||
|
enum { Type = QGraphicsItem::UserType + 1 };
|
||||||
|
|
||||||
|
/// Rotate item around @pivot point on &deltaAngle (deg).
|
||||||
|
virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle) {}
|
||||||
|
|
||||||
|
/// Scales item relatively @pivot point
|
||||||
|
// TODO: add modes: IgnoreAspectRatio, KeepAspectRatio
|
||||||
|
virtual void scaleOn(const QPointF &pivot, const QPointF &factor) {}
|
||||||
|
|
||||||
|
/// Rotate arrow on angle (deg). (only for WorldItemPoint)
|
||||||
|
virtual void turnOn(const qreal angle) {}
|
||||||
|
virtual void radiusOn(const qreal radius) {}
|
||||||
|
|
||||||
|
/// Change color
|
||||||
|
virtual void setColor(const QColor &color) {}
|
||||||
|
|
||||||
|
/// Enable/disable the mode edit shape (only for WorldItemPath and WorldItemPath)
|
||||||
|
virtual void setEnabledSubPoints(bool enabled) {}
|
||||||
|
|
||||||
|
virtual void moveSubPoint(WorldItemSubPoint *subPoint) {}
|
||||||
|
virtual void addSubPoint(WorldItemSubPoint *subPoint) {}
|
||||||
|
virtual bool removeSubPoint(WorldItemSubPoint *subPoint)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setPolygon(const QPolygonF &polygon) {}
|
||||||
|
virtual QPolygonF polygon() const
|
||||||
|
{
|
||||||
|
return QPolygonF();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setActived(bool actived);
|
||||||
|
bool isActived() const;
|
||||||
|
|
||||||
|
void setShapeChanged(bool value);
|
||||||
|
bool isShapeChanged() const;
|
||||||
|
|
||||||
|
// Enable the use of qgraphicsitem_cast with this item.
|
||||||
|
int type() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool m_active, m_shapeChanged;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class WorldItemPoint
|
||||||
|
@brief WorldItemPoint class provides a dot item with arrow and circle(@radius)
|
||||||
|
that you can add to a WorldEditorScene.
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class WorldItemPoint: public AbstractWorldItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WorldItemPoint(const QPointF &point, const qreal angle, const qreal radius,
|
||||||
|
bool showArrow, QGraphicsItem *parent = 0);
|
||||||
|
virtual ~WorldItemPoint();
|
||||||
|
|
||||||
|
qreal angle() const;
|
||||||
|
|
||||||
|
virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle);
|
||||||
|
virtual void scaleOn(const QPointF &pivot, const QPointF &factor);
|
||||||
|
virtual void turnOn(const qreal angle);
|
||||||
|
virtual void radiusOn(const qreal radius);
|
||||||
|
|
||||||
|
virtual void setColor(const QColor &color);
|
||||||
|
virtual void setEnabledSubPoints(bool enabled) {}
|
||||||
|
|
||||||
|
virtual void setPolygon(const QPolygonF &polygon);
|
||||||
|
virtual QPolygonF polygon() const;
|
||||||
|
|
||||||
|
virtual QRectF boundingRect() const;
|
||||||
|
virtual QPainterPath shape() const;
|
||||||
|
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createCircle();
|
||||||
|
void updateBoundingRect();
|
||||||
|
|
||||||
|
static const int SIZE_POINT = 2;
|
||||||
|
|
||||||
|
QPen m_pen, m_selectedPen;
|
||||||
|
QBrush m_brush, m_selectedBrush;
|
||||||
|
|
||||||
|
QPolygonF m_circle;
|
||||||
|
QVector<QLine> m_arrow;
|
||||||
|
QRectF m_rect, m_boundingRect;
|
||||||
|
qreal m_angle, m_radius;
|
||||||
|
bool m_showArrow;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class BaseWorldItemPolyline
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class BaseWorldItemPolyline: public AbstractWorldItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseWorldItemPolyline(const QPolygonF &polygon, QGraphicsItem *parent = 0);
|
||||||
|
virtual ~BaseWorldItemPolyline();
|
||||||
|
|
||||||
|
virtual void rotateOn(const QPointF &pivot, const qreal deltaAngle);
|
||||||
|
virtual void scaleOn(const QPointF &pivot, const QPointF &factor);
|
||||||
|
|
||||||
|
virtual void setEnabledSubPoints(bool enabled);
|
||||||
|
virtual void moveSubPoint(WorldItemSubPoint *subPoint);
|
||||||
|
virtual void addSubPoint(WorldItemSubPoint *subPoint);
|
||||||
|
virtual bool removeSubPoint(WorldItemSubPoint *subPoint);
|
||||||
|
|
||||||
|
virtual void setPolygon(const QPolygonF &polygon);
|
||||||
|
virtual QPolygonF polygon() const;
|
||||||
|
|
||||||
|
virtual QRectF boundingRect() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void createSubPoints();
|
||||||
|
virtual void removeSubPoints();
|
||||||
|
|
||||||
|
bool m_pointEdit;
|
||||||
|
QPolygonF m_polyline;
|
||||||
|
QPen m_pen, m_selectedPen;
|
||||||
|
|
||||||
|
QList<WorldItemSubPoint *> m_listItems;
|
||||||
|
QList<LineStruct> m_listLines;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class WorldItemPath
|
||||||
|
@brief WorldItemPath class provides a polyline item that you can add to a WorldEditorScene.
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class WorldItemPath: public BaseWorldItemPolyline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WorldItemPath(const QPolygonF &polygon, QGraphicsItem *parent = 0);
|
||||||
|
virtual ~WorldItemPath();
|
||||||
|
|
||||||
|
virtual void setColor(const QColor &color);
|
||||||
|
virtual bool removeSubPoint(WorldItemSubPoint *subPoint);
|
||||||
|
virtual QPainterPath shape() const;
|
||||||
|
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QPen m_pen, m_selectedPen;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class WorldItemZone
|
||||||
|
@brief The WorldItemZone class provides a polygon item that you can add to a WorldEditorScene.
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class WorldItemZone: public BaseWorldItemPolyline
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WorldItemZone(const QPolygonF &polygon, QGraphicsItem *parent = 0);
|
||||||
|
virtual ~WorldItemZone();
|
||||||
|
|
||||||
|
virtual void setColor(const QColor &color);
|
||||||
|
virtual bool removeSubPoint(WorldItemSubPoint *subPoint);
|
||||||
|
virtual QPainterPath shape() const;
|
||||||
|
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void createSubPoints();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const int TRANSPARENCY = 38;
|
||||||
|
|
||||||
|
QPen m_pen, m_selectedPen;
|
||||||
|
QBrush m_brush, m_selectedBrush;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
@class WorldItemSubPoint
|
||||||
|
@brief
|
||||||
|
@details
|
||||||
|
*/
|
||||||
|
class WorldItemSubPoint: public QGraphicsObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum SubPointType
|
||||||
|
{
|
||||||
|
EdgeType = 0,
|
||||||
|
MiddleType
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { Type = QGraphicsItem::UserType + 2 };
|
||||||
|
|
||||||
|
WorldItemSubPoint(SubPointType pointType, AbstractWorldItem *parent = 0);
|
||||||
|
virtual ~WorldItemSubPoint();
|
||||||
|
|
||||||
|
void setSubPointType(SubPointType nodeType);
|
||||||
|
SubPointType subPointType() const;
|
||||||
|
|
||||||
|
void rotateOn(const QPointF &pivot, const qreal deltaAngle);
|
||||||
|
void scaleOn(const QPointF &pivot, const QPointF &factor);
|
||||||
|
|
||||||
|
virtual QRectF boundingRect() const;
|
||||||
|
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||||
|
|
||||||
|
void setActived(bool actived);
|
||||||
|
bool isActived() const;
|
||||||
|
|
||||||
|
// Enable the use of qgraphicsitem_cast with this item.
|
||||||
|
int type() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||||
|
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateBoundingRect();
|
||||||
|
|
||||||
|
static const int SIZE_POINT = 6;
|
||||||
|
|
||||||
|
QBrush m_brush, m_brushMiddle, m_selectedBrush;
|
||||||
|
|
||||||
|
QRectF m_rect, m_boundingRect;
|
||||||
|
SubPointType m_type;
|
||||||
|
bool m_active;
|
||||||
|
AbstractWorldItem *m_parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
// Enable the use of QVariant with this class.
|
||||||
|
Q_DECLARE_METATYPE(WorldEditor::AbstractWorldItem *)
|
||||||
|
|
||||||
|
#endif // WORLD_EDITOR_SCENE_ITEM_H
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_settings_page.h"
|
||||||
|
#include "world_editor_constants.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QWidget>
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
WorldEditorSettingsPage::WorldEditorSettingsPage(QObject *parent)
|
||||||
|
: IOptionsPage(parent),
|
||||||
|
m_currentPage(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WorldEditorSettingsPage::id() const
|
||||||
|
{
|
||||||
|
return QLatin1String(Constants::WORLD_EDITOR_PLUGIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WorldEditorSettingsPage::trName() const
|
||||||
|
{
|
||||||
|
return tr("General");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WorldEditorSettingsPage::category() const
|
||||||
|
{
|
||||||
|
return QLatin1String(Constants::WORLD_EDITOR_PLUGIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString WorldEditorSettingsPage::trCategory() const
|
||||||
|
{
|
||||||
|
return tr("World Editor");
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon WorldEditorSettingsPage::categoryIcon() const
|
||||||
|
{
|
||||||
|
return QIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *WorldEditorSettingsPage::createPage(QWidget *parent)
|
||||||
|
{
|
||||||
|
m_currentPage = new QWidget(parent);
|
||||||
|
m_ui.setupUi(m_currentPage);
|
||||||
|
return m_currentPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorSettingsPage::apply()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WORLD_EDITOR_SETTINGS_PAGE_H
|
||||||
|
#define WORLD_EDITOR_SETTINGS_PAGE_H
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
#include "../core/ioptions_page.h"
|
||||||
|
|
||||||
|
#include "ui_world_editor_settings_page.h"
|
||||||
|
|
||||||
|
class QWidget;
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class WorldEditorSettingsPage
|
||||||
|
*/
|
||||||
|
class WorldEditorSettingsPage : public Core::IOptionsPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit WorldEditorSettingsPage(QObject *parent = 0);
|
||||||
|
virtual ~WorldEditorSettingsPage() {}
|
||||||
|
|
||||||
|
virtual QString id() const;
|
||||||
|
virtual QString trName() const;
|
||||||
|
virtual QString category() const;
|
||||||
|
virtual QString trCategory() const;
|
||||||
|
QIcon categoryIcon() const;
|
||||||
|
virtual QWidget *createPage(QWidget *parent);
|
||||||
|
|
||||||
|
virtual void apply();
|
||||||
|
virtual void finish() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget *m_currentPage;
|
||||||
|
Ui::WorldEditorSettingsPage m_ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace WorldEditor
|
||||||
|
|
||||||
|
#endif // WORLD_EDITOR_SETTINGS_PAGE_H
|
|
@ -0,0 +1,137 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>WorldEditorSettingsPage</class>
|
||||||
|
<widget class="QWidget" name="WorldEditorSettingsPage">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>329</width>
|
||||||
|
<height>239</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<property name="margin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Workspace</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Top Left</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="spinBox_3"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QSpinBox" name="spinBox_4"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Bottom Right</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="spinBox_5"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QSpinBox" name="spinBox_6"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="3">
|
||||||
|
<widget class="QCheckBox" name="checkBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use OpenGL</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Ligoscape</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cell size</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QSpinBox" name="spinBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Snap</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="spinBox_2"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ligo class</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="toolButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="world_editor.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -0,0 +1,422 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "world_editor_window.h"
|
||||||
|
#include "world_editor_constants.h"
|
||||||
|
#include "primitives_model.h"
|
||||||
|
#include "world_editor_scene.h"
|
||||||
|
#include "world_editor_misc.h"
|
||||||
|
#include "world_editor_actions.h"
|
||||||
|
#include "world_editor_scene_item.h"
|
||||||
|
#include "project_settings_dialog.h"
|
||||||
|
|
||||||
|
// Core
|
||||||
|
#include "../core/icore.h"
|
||||||
|
#include "../core/menu_manager.h"
|
||||||
|
#include "../core/core_constants.h"
|
||||||
|
|
||||||
|
// Lanscape Editor plugin
|
||||||
|
#include "../landscape_editor/builder_zone_base.h"
|
||||||
|
|
||||||
|
// NeL includes
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtCore/QSettings>
|
||||||
|
#include <QtGui/QFileDialog>
|
||||||
|
#include <QtGui/QStatusBar>
|
||||||
|
#include <QtGui/QMessageBox>
|
||||||
|
#include <QPersistentModelIndex>
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
|
||||||
|
WorldEditorWindow::WorldEditorWindow(QWidget *parent)
|
||||||
|
: QMainWindow(parent),
|
||||||
|
m_primitivesModel(0),
|
||||||
|
m_undoStack(0),
|
||||||
|
m_oglWidget(0)
|
||||||
|
{
|
||||||
|
m_ui.setupUi(this);
|
||||||
|
m_undoStack = new QUndoStack(this);
|
||||||
|
|
||||||
|
m_primitivesModel = new PrimitivesTreeModel(this);
|
||||||
|
|
||||||
|
m_worldEditorScene = new WorldEditorScene(Utils::ligoConfig()->CellSize, m_primitivesModel, m_undoStack, this);
|
||||||
|
m_zoneBuilderBase = new LandscapeEditor::ZoneBuilderBase(m_worldEditorScene);
|
||||||
|
|
||||||
|
m_worldEditorScene->setZoneBuilder(m_zoneBuilderBase);
|
||||||
|
m_ui.graphicsView->setScene(m_worldEditorScene);
|
||||||
|
m_ui.graphicsView->setVisibleText(false);
|
||||||
|
|
||||||
|
m_ui.treePrimitivesView->setModel(m_primitivesModel);
|
||||||
|
m_ui.treePrimitivesView->setUndoStack(m_undoStack);
|
||||||
|
m_ui.treePrimitivesView->setZoneBuilder(m_zoneBuilderBase);
|
||||||
|
m_ui.treePrimitivesView->setWorldScene(m_worldEditorScene);
|
||||||
|
|
||||||
|
QActionGroup *sceneModeGroup = new QActionGroup(this);
|
||||||
|
sceneModeGroup->addAction(m_ui.selectAction);
|
||||||
|
sceneModeGroup->addAction(m_ui.moveAction);
|
||||||
|
sceneModeGroup->addAction(m_ui.rotateAction);
|
||||||
|
sceneModeGroup->addAction(m_ui.scaleAction);
|
||||||
|
sceneModeGroup->addAction(m_ui.turnAction);
|
||||||
|
m_ui.selectAction->setChecked(true);
|
||||||
|
|
||||||
|
m_ui.newWorldEditAction->setIcon(QIcon(Core::Constants::ICON_NEW));
|
||||||
|
m_ui.saveWorldEditAction->setIcon(QIcon(Core::Constants::ICON_SAVE));
|
||||||
|
|
||||||
|
createMenus();
|
||||||
|
createToolBars();
|
||||||
|
readSettings();
|
||||||
|
|
||||||
|
QSignalMapper *m_modeMapper = new QSignalMapper(this);
|
||||||
|
connect(m_ui.selectAction, SIGNAL(triggered()), m_modeMapper, SLOT(map()));
|
||||||
|
m_modeMapper->setMapping(m_ui.selectAction, 0);
|
||||||
|
connect(m_ui.moveAction, SIGNAL(triggered()), m_modeMapper, SLOT(map()));
|
||||||
|
m_modeMapper->setMapping(m_ui.moveAction, 1);
|
||||||
|
connect(m_ui.rotateAction, SIGNAL(triggered()), m_modeMapper, SLOT(map()));
|
||||||
|
m_modeMapper->setMapping(m_ui.rotateAction, 2);
|
||||||
|
connect(m_ui.scaleAction, SIGNAL(triggered()), m_modeMapper, SLOT(map()));
|
||||||
|
m_modeMapper->setMapping(m_ui.scaleAction, 3);
|
||||||
|
connect(m_ui.turnAction, SIGNAL(triggered()), m_modeMapper, SLOT(map()));
|
||||||
|
m_modeMapper->setMapping(m_ui.turnAction, 4);
|
||||||
|
|
||||||
|
connect(m_modeMapper, SIGNAL(mapped(int)), this, SLOT(setMode(int)));
|
||||||
|
connect(m_ui.pointsAction, SIGNAL(triggered(bool)), m_worldEditorScene, SLOT(setEnabledEditPoints(bool)));
|
||||||
|
|
||||||
|
connect(m_ui.settingsAction, SIGNAL(triggered()), this, SLOT(openProjectSettings()));
|
||||||
|
connect(m_ui.newWorldEditAction, SIGNAL(triggered()), this, SLOT(newWorldEditFile()));
|
||||||
|
connect(m_ui.saveWorldEditAction, SIGNAL(triggered()), this, SLOT(saveWorldEditFile()));
|
||||||
|
connect(m_ui.visibleGridAction, SIGNAL(toggled(bool)), m_ui.graphicsView, SLOT(setVisibleGrid(bool)));
|
||||||
|
|
||||||
|
connect(m_ui.treePrimitivesView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||||
|
this, SLOT(updateSelection(QItemSelection, QItemSelection)));
|
||||||
|
|
||||||
|
connect(m_worldEditorScene, SIGNAL(updateSelectedItems(QList<QGraphicsItem *>)),
|
||||||
|
this, SLOT(selectedItemsInScene(QList<QGraphicsItem *>)));
|
||||||
|
|
||||||
|
m_statusBarTimer = new QTimer(this);
|
||||||
|
connect(m_statusBarTimer, SIGNAL(timeout()), this, SLOT(updateStatusBar()));
|
||||||
|
|
||||||
|
m_statusInfo = new QLabel(this);
|
||||||
|
m_statusInfo->hide();
|
||||||
|
Core::ICore::instance()->mainWindow()->statusBar()->addPermanentWidget(m_statusInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldEditorWindow::~WorldEditorWindow()
|
||||||
|
{
|
||||||
|
writeSettings();
|
||||||
|
|
||||||
|
delete m_zoneBuilderBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUndoStack *WorldEditorWindow::undoStack() const
|
||||||
|
{
|
||||||
|
return m_undoStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::maybeSave()
|
||||||
|
{
|
||||||
|
QMessageBox *messageBox = new QMessageBox(tr("World Editor"),
|
||||||
|
tr("The data has been modified.\n"
|
||||||
|
"Do you want to save your changes?"),
|
||||||
|
QMessageBox::Warning,
|
||||||
|
QMessageBox::Yes | QMessageBox::Default,
|
||||||
|
QMessageBox::No,
|
||||||
|
QMessageBox::Cancel | QMessageBox::Escape,
|
||||||
|
this, Qt::Sheet);
|
||||||
|
|
||||||
|
messageBox->setButtonText(QMessageBox::Yes,
|
||||||
|
tr("Save"));
|
||||||
|
|
||||||
|
messageBox->setButtonText(QMessageBox::No, tr("Don't Save"));
|
||||||
|
|
||||||
|
messageBox->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::open()
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getOpenFileName(this,
|
||||||
|
tr("Open NeL World Edit file"), m_lastDir,
|
||||||
|
tr("All NeL World Editor file (*.worldedit)"));
|
||||||
|
|
||||||
|
setCursor(Qt::WaitCursor);
|
||||||
|
if (!fileName.isEmpty())
|
||||||
|
{
|
||||||
|
m_lastDir = QFileInfo(fileName).absolutePath();
|
||||||
|
loadWorldEditFile(fileName);
|
||||||
|
}
|
||||||
|
setCursor(Qt::ArrowCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::loadWorldEditFile(const QString &fileName)
|
||||||
|
{
|
||||||
|
if (m_primitivesModel->isWorldEditNodeLoaded())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Utils::WorldEditList worldEditList;
|
||||||
|
if (!Utils::loadWorldEditFile(fileName.toStdString(), worldEditList))
|
||||||
|
{
|
||||||
|
// TODO: add the message box
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_undoStack->beginMacro(tr("Load %1").arg(fileName));
|
||||||
|
|
||||||
|
checkCurrentWorld();
|
||||||
|
|
||||||
|
m_undoStack->push(new CreateWorldCommand(fileName, m_primitivesModel));
|
||||||
|
for (size_t i = 0; i < worldEditList.size(); ++i)
|
||||||
|
{
|
||||||
|
switch (worldEditList[i].first)
|
||||||
|
{
|
||||||
|
case Utils::DataDirectoryType:
|
||||||
|
m_zoneBuilderBase->init(QString(worldEditList[i].second.c_str()), true);
|
||||||
|
break;
|
||||||
|
case Utils::ContextType:
|
||||||
|
break;
|
||||||
|
case Utils::LandscapeType:
|
||||||
|
m_undoStack->push(new LoadLandscapeCommand(QString(worldEditList[i].second.c_str()), m_primitivesModel, m_zoneBuilderBase));
|
||||||
|
break;
|
||||||
|
case Utils::PrimitiveType:
|
||||||
|
m_undoStack->push(new LoadRootPrimitiveCommand(QString(worldEditList[i].second.c_str()),
|
||||||
|
m_worldEditorScene, m_primitivesModel, m_ui.treePrimitivesView));
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
m_undoStack->endMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::checkCurrentWorld()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::newWorldEditFile()
|
||||||
|
{
|
||||||
|
checkCurrentWorld();
|
||||||
|
m_undoStack->push(new CreateWorldCommand("NewWorldEdit", m_primitivesModel));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::saveWorldEditFile()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::openProjectSettings()
|
||||||
|
{
|
||||||
|
ProjectSettingsDialog *dialog = new ProjectSettingsDialog(m_zoneBuilderBase->dataPath(), this);
|
||||||
|
dialog->show();
|
||||||
|
int ok = dialog->exec();
|
||||||
|
if (ok == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
m_zoneBuilderBase->init(dialog->dataPath(), true);
|
||||||
|
}
|
||||||
|
delete dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::setMode(int value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
m_worldEditorScene->setModeEdit(WorldEditorScene::SelectMode);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
m_worldEditorScene->setModeEdit(WorldEditorScene::MoveMode);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
m_worldEditorScene->setModeEdit(WorldEditorScene::RotateMode);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
m_worldEditorScene->setModeEdit(WorldEditorScene::ScaleMode);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
m_worldEditorScene->setModeEdit(WorldEditorScene::TurnMode);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
m_worldEditorScene->setModeEdit(WorldEditorScene::RadiusMode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::updateStatusBar()
|
||||||
|
{
|
||||||
|
m_statusInfo->setText(m_worldEditorScene->zoneNameFromMousePos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::updateSelection(const QItemSelection &selected, const QItemSelection &deselected)
|
||||||
|
{
|
||||||
|
m_ui.pointsAction->setChecked(false);
|
||||||
|
m_worldEditorScene->setEnabledEditPoints(false);
|
||||||
|
|
||||||
|
NodeList nodesSelected;
|
||||||
|
Q_FOREACH(QModelIndex modelIndex, selected.indexes())
|
||||||
|
{
|
||||||
|
Node *node = static_cast<Node *>(modelIndex.internalPointer());
|
||||||
|
nodesSelected.push_back(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeList nodesDeselected;
|
||||||
|
Q_FOREACH(QModelIndex modelIndex, deselected.indexes())
|
||||||
|
{
|
||||||
|
Node *node = static_cast<Node *>(modelIndex.internalPointer());
|
||||||
|
nodesDeselected.push_back(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update property editor
|
||||||
|
if (nodesSelected.size() > 0)
|
||||||
|
{
|
||||||
|
// only single selection
|
||||||
|
m_ui.propertyEditWidget->updateSelection(nodesSelected.at(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ui.propertyEditWidget->clearProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QGraphicsItem *> itemSelected;
|
||||||
|
Q_FOREACH(Node *node, nodesSelected)
|
||||||
|
{
|
||||||
|
QGraphicsItem *item = getGraphicsItem(node);
|
||||||
|
if (item != 0)
|
||||||
|
itemSelected.push_back(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QGraphicsItem *> itemDeselected;
|
||||||
|
Q_FOREACH(Node *node, nodesDeselected)
|
||||||
|
{
|
||||||
|
QGraphicsItem *item = getGraphicsItem(node);
|
||||||
|
if (item != 0)
|
||||||
|
itemDeselected.push_back(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update world editor scene
|
||||||
|
m_worldEditorScene->updateSelection(itemSelected, itemDeselected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::selectedItemsInScene(const QList<QGraphicsItem *> &selected)
|
||||||
|
{
|
||||||
|
QItemSelectionModel *selectionModel = m_ui.treePrimitivesView->selectionModel();
|
||||||
|
disconnect(m_ui.treePrimitivesView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||||
|
this, SLOT(updateSelection(QItemSelection, QItemSelection)));
|
||||||
|
|
||||||
|
selectionModel->clear();
|
||||||
|
QItemSelection itemSelection;
|
||||||
|
Q_FOREACH(QGraphicsItem *item, selected)
|
||||||
|
{
|
||||||
|
QPersistentModelIndex *index = qvariant_cast<QPersistentModelIndex *>(item->data(Constants::NODE_PERISTENT_INDEX));
|
||||||
|
if (index->isValid())
|
||||||
|
{
|
||||||
|
QModelIndex modelIndex = index->operator const QModelIndex &();
|
||||||
|
QItemSelection mergeItemSelection(modelIndex, modelIndex);
|
||||||
|
itemSelection.merge(mergeItemSelection, QItemSelectionModel::Select);
|
||||||
|
}
|
||||||
|
QApplication::processEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
selectionModel->select(itemSelection, QItemSelectionModel::Select);
|
||||||
|
|
||||||
|
// update property editor
|
||||||
|
if (!selected.isEmpty())
|
||||||
|
{
|
||||||
|
// only single selection
|
||||||
|
Node *node = qvariant_cast<Node *>(selected.at(0)->data(Constants::WORLD_EDITOR_NODE));
|
||||||
|
m_ui.propertyEditWidget->updateSelection(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ui.propertyEditWidget->clearProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(m_ui.treePrimitivesView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
|
||||||
|
this, SLOT(updateSelection(QItemSelection, QItemSelection)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::showEvent(QShowEvent *showEvent)
|
||||||
|
{
|
||||||
|
QMainWindow::showEvent(showEvent);
|
||||||
|
if (m_oglWidget != 0)
|
||||||
|
m_oglWidget->makeCurrent();
|
||||||
|
m_statusInfo->show();
|
||||||
|
m_statusBarTimer->start(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::hideEvent(QHideEvent *hideEvent)
|
||||||
|
{
|
||||||
|
QMainWindow::hideEvent(hideEvent);
|
||||||
|
m_statusInfo->hide();
|
||||||
|
m_statusBarTimer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::createMenus()
|
||||||
|
{
|
||||||
|
//Core::MenuManager *menuManager = Core::ICore::instance()->menuManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::createToolBars()
|
||||||
|
{
|
||||||
|
Core::MenuManager *menuManager = Core::ICore::instance()->menuManager();
|
||||||
|
//QAction *action = menuManager->action(Core::Constants::NEW);
|
||||||
|
//m_ui.fileToolBar->addAction(action);
|
||||||
|
|
||||||
|
m_ui.fileToolBar->addAction(m_ui.newWorldEditAction);
|
||||||
|
QAction *action = menuManager->action(Core::Constants::OPEN);
|
||||||
|
m_ui.fileToolBar->addAction(action);
|
||||||
|
m_ui.fileToolBar->addAction(m_ui.saveWorldEditAction);
|
||||||
|
m_ui.fileToolBar->addSeparator();
|
||||||
|
|
||||||
|
action = menuManager->action(Core::Constants::UNDO);
|
||||||
|
if (action != 0)
|
||||||
|
m_ui.fileToolBar->addAction(action);
|
||||||
|
|
||||||
|
action = menuManager->action(Core::Constants::REDO);
|
||||||
|
if (action != 0)
|
||||||
|
m_ui.fileToolBar->addAction(action);
|
||||||
|
|
||||||
|
//action = menuManager->action(Core::Constants::SAVE);
|
||||||
|
//m_ui.fileToolBar->addAction(action);
|
||||||
|
//action = menuManager->action(Core::Constants::SAVE_AS);
|
||||||
|
//m_ui.fileToolBar->addAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::readSettings()
|
||||||
|
{
|
||||||
|
QSettings *settings = Core::ICore::instance()->settings();
|
||||||
|
settings->beginGroup(Constants::WORLD_EDITOR_SECTION);
|
||||||
|
restoreState(settings->value(Constants::WORLD_WINDOW_STATE).toByteArray());
|
||||||
|
restoreGeometry(settings->value(Constants::WORLD_WINDOW_GEOMETRY).toByteArray());
|
||||||
|
|
||||||
|
// Use OpenGL graphics system instead raster graphics system
|
||||||
|
if (settings->value(Constants::WORLD_EDITOR_USE_OPENGL, true).toBool())
|
||||||
|
{
|
||||||
|
m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer));
|
||||||
|
//m_oglWidget = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::SampleBuffers));
|
||||||
|
m_ui.graphicsView->setViewport(m_oglWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
settings->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditorWindow::writeSettings()
|
||||||
|
{
|
||||||
|
QSettings *settings = Core::ICore::instance()->settings();
|
||||||
|
settings->beginGroup(Constants::WORLD_EDITOR_SECTION);
|
||||||
|
settings->setValue(Constants::WORLD_WINDOW_STATE, saveState());
|
||||||
|
settings->setValue(Constants::WORLD_WINDOW_GEOMETRY, saveGeometry());
|
||||||
|
settings->endGroup();
|
||||||
|
settings->sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace LandscapeEditor */
|
|
@ -0,0 +1,95 @@
|
||||||
|
// Object Viewer Qt - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
||||||
|
// Copyright (C) 2011 Dzmitry Kamiahin <dnk-88@tut.by>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as
|
||||||
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef WORLD_EDITOR_WINDOW_H
|
||||||
|
#define WORLD_EDITOR_WINDOW_H
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "ui_world_editor_window.h"
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QtGui/QUndoStack>
|
||||||
|
#include <QtGui/QLabel>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
#include <QtCore/QSignalMapper>
|
||||||
|
#include <QtOpenGL/QGLWidget>
|
||||||
|
|
||||||
|
namespace LandscapeEditor
|
||||||
|
{
|
||||||
|
class ZoneBuilderBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WorldEditor
|
||||||
|
{
|
||||||
|
class PrimitivesTreeModel;
|
||||||
|
class WorldEditorScene;
|
||||||
|
|
||||||
|
class WorldEditorWindow: public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit WorldEditorWindow(QWidget *parent = 0);
|
||||||
|
~WorldEditorWindow();
|
||||||
|
|
||||||
|
QUndoStack *undoStack() const;
|
||||||
|
void maybeSave();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
public Q_SLOTS:
|
||||||
|
void open();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void newWorldEditFile();
|
||||||
|
void saveWorldEditFile();
|
||||||
|
void openProjectSettings();
|
||||||
|
|
||||||
|
void setMode(int value);
|
||||||
|
void updateStatusBar();
|
||||||
|
|
||||||
|
void updateSelection(const QItemSelection &selected, const QItemSelection &deselected);
|
||||||
|
void selectedItemsInScene(const QList<QGraphicsItem *> &selected);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void showEvent(QShowEvent *showEvent);
|
||||||
|
virtual void hideEvent(QHideEvent *hideEvent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createMenus();
|
||||||
|
void createToolBars();
|
||||||
|
void readSettings();
|
||||||
|
void writeSettings();
|
||||||
|
|
||||||
|
void loadWorldEditFile(const QString &fileName);
|
||||||
|
void checkCurrentWorld();
|
||||||
|
|
||||||
|
QString m_lastDir;
|
||||||
|
|
||||||
|
QLabel *m_statusInfo;
|
||||||
|
QTimer *m_statusBarTimer;
|
||||||
|
|
||||||
|
PrimitivesTreeModel *m_primitivesModel;
|
||||||
|
QUndoStack *m_undoStack;
|
||||||
|
WorldEditorScene *m_worldEditorScene;
|
||||||
|
LandscapeEditor::ZoneBuilderBase *m_zoneBuilderBase;
|
||||||
|
QSignalMapper m_modeMapper;
|
||||||
|
QGLWidget *m_oglWidget;
|
||||||
|
Ui::WorldEditorWindow m_ui;
|
||||||
|
}; /* class WorldEditorWindow */
|
||||||
|
|
||||||
|
} /* namespace WorldEditor */
|
||||||
|
|
||||||
|
#endif // WORLD_EDITOR_WINDOW_H
|
|
@ -0,0 +1,379 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>WorldEditorWindow</class>
|
||||||
|
<widget class="QMainWindow" name="WorldEditorWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>819</width>
|
||||||
|
<height>600</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="world_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_world_editor.png</normaloff>:/icons/ic_nel_world_editor.png</iconset>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="LandscapeEditor::LandscapeView" name="graphicsView">
|
||||||
|
<property name="interactive">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<property name="renderHints">
|
||||||
|
<set>QPainter::SmoothPixmapTransform</set>
|
||||||
|
</property>
|
||||||
|
<property name="dragMode">
|
||||||
|
<enum>QGraphicsView::NoDrag</enum>
|
||||||
|
</property>
|
||||||
|
<property name="transformationAnchor">
|
||||||
|
<enum>QGraphicsView::AnchorUnderMouse</enum>
|
||||||
|
</property>
|
||||||
|
<property name="resizeAnchor">
|
||||||
|
<enum>QGraphicsView::AnchorUnderMouse</enum>
|
||||||
|
</property>
|
||||||
|
<property name="viewportUpdateMode">
|
||||||
|
<enum>QGraphicsView::FullViewportUpdate</enum>
|
||||||
|
</property>
|
||||||
|
<property name="optimizationFlags">
|
||||||
|
<set>QGraphicsView::DontAdjustForAntialiasing|QGraphicsView::DontClipPainter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="fileToolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="worldEditToolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="selectAction"/>
|
||||||
|
<addaction name="moveAction"/>
|
||||||
|
<addaction name="rotateAction"/>
|
||||||
|
<addaction name="scaleAction"/>
|
||||||
|
<addaction name="turnAction"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="pointsAction"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QDockWidget" name="treePrimitivesDockWidget">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Primitives</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="dockWidgetArea">
|
||||||
|
<number>2</number>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QWidget" name="dockWidgetContents">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<property name="margin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="WorldEditor::PrimitivesView" name="treePrimitivesView">
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<attribute name="headerCascadingSectionResizes">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="headerDefaultSectionSize">
|
||||||
|
<number>250</number>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QToolBar" name="shToolBar">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>toolBar</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="toolBarArea">
|
||||||
|
<enum>TopToolBarArea</enum>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolBarBreak">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<addaction name="visibleLandAction"/>
|
||||||
|
<addaction name="visibleZonePrimitivesAction"/>
|
||||||
|
<addaction name="visiblePathPrimitivesAction"/>
|
||||||
|
<addaction name="vidiblePointPrimitives"/>
|
||||||
|
<addaction name="visibleDetailsAction"/>
|
||||||
|
<addaction name="visibleGridAction"/>
|
||||||
|
<addaction name="visibleGridPointsAction"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="settingsAction"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QDockWidget" name="propertyEditDockWidget">
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Property Editor</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="dockWidgetArea">
|
||||||
|
<number>2</number>
|
||||||
|
</attribute>
|
||||||
|
<widget class="WorldEditor::PropertyEditorWidget" name="propertyEditWidget"/>
|
||||||
|
</widget>
|
||||||
|
<action name="loadPrimitiveAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>loadPrimitive</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="newPrimitiveAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>newPrimitive</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="loadLandAction">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../landscape_editor/landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_zonel.png</normaloff>:/icons/ic_nel_zonel.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>loadLand</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="settingsAction">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../landscape_editor/landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Settings</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="visibleLandAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>S/H Land</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="visibleZonePrimitivesAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>S/H Zone primitives</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>S/H Zone Primitives</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="visiblePathPrimitivesAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>S/H Path primitives</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="visibleDetailsAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>S/H Details</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="visibleGridAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../landscape_editor/landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_grid.png</normaloff>:/icons/ic_grid.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>S/H Grid</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="visibleGridPointsAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>S/H Grid points</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="newWorldEditAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>New World Edit file</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="saveWorldEditAction">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save World Edit file</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="selectAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="world_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_select.png</normaloff>:/icons/ic_nel_select.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Select</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="moveAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="world_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_move.png</normaloff>:/icons/ic_nel_move.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Move</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="rotateAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="world_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_rotate.png</normaloff>:/icons/ic_nel_rotate.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Rotate</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="scaleAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="world_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_scale.png</normaloff>:/icons/ic_nel_scale.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Scale</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="turnAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="world_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_turn.png</normaloff>:/icons/ic_nel_turn.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Turn</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="pointsAction">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Edit points</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="projectSettingsAction">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../landscape_editor/landscape_editor.qrc">
|
||||||
|
<normaloff>:/icons/ic_nel_landscape_settings.png</normaloff>:/icons/ic_nel_landscape_settings.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Project settings</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="vidiblePointPrimitives">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>S/H Points primitives</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>S/H Points primitives</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>LandscapeEditor::LandscapeView</class>
|
||||||
|
<extends>QGraphicsView</extends>
|
||||||
|
<header>../landscape_editor/landscape_view.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>WorldEditor::PrimitivesView</class>
|
||||||
|
<extends>QTreeView</extends>
|
||||||
|
<header>primitives_view.h</header>
|
||||||
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>WorldEditor::PropertyEditorWidget</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>property_editor_widget.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources>
|
||||||
|
<include location="world_editor.qrc"/>
|
||||||
|
<include location="../landscape_editor/landscape_editor.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|