Changed: #1302 Added operations creating and deleting primitives without undo/redo.

--HG--
branch : gsoc2011-worldeditorqt
This commit is contained in:
dnk-88 2011-07-27 19:04:46 +03:00
parent 0c1a463b97
commit b74413dd55
12 changed files with 1051 additions and 39 deletions

View file

@ -12,6 +12,7 @@ SET(OVQT_EXT_SYS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../extension_system/iplugin.
SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h SET(OVQT_PLUGIN_WORLD_EDITOR_HDR world_editor_plugin.h
world_editor_window.h world_editor_window.h
primitives_model.h primitives_model.h
primitives_view.h
) )
SET(OVQT_PLUGIN_WORLD_EDITOR_UIS world_editor_window.ui SET(OVQT_PLUGIN_WORLD_EDITOR_UIS world_editor_window.ui

View file

@ -16,9 +16,14 @@
// Project includes // Project includes
#include "primitive_item.h" #include "primitive_item.h"
#include "world_editor_misc.h"
// NeL includes
#include <nel/ligo/ligo_config.h>
// Qt includes // Qt includes
#include <QStringList> #include <QtCore/QStringList>
#include <QtCore/QFile>
namespace WorldEditor namespace WorldEditor
{ {
@ -45,6 +50,11 @@ void BaseTreeItem::appendChild(BaseTreeItem *item)
m_childItems.append(item); m_childItems.append(item);
} }
void BaseTreeItem::deleteChild(int row)
{
delete m_childItems.takeAt(row);
}
BaseTreeItem *BaseTreeItem::child(int row) BaseTreeItem *BaseTreeItem::child(int row)
{ {
return m_childItems.value(row); return m_childItems.value(row);
@ -104,12 +114,13 @@ PrimitiveItem::PrimitiveItem(NLLIGO::IPrimitive *primitive, BaseTreeItem *parent
m_primitive->getPropertyByName("class", className); m_primitive->getPropertyByName("class", className);
// Set Icon // Set Icon
QIcon icon(QString("./old_ico/%1.ico").arg(className.c_str())); QString nameIcon = QString("./old_ico/%1.ico").arg(className.c_str());
if (primitive->getParent() == NULL) QIcon icon(nameIcon);
icon = QIcon("./old_ico/root.ico"); if (!QFile::exists(nameIcon))
if (icon.isNull())
{ {
if (primitive->getNumChildren() == 0) if (primitive->getParent() == NULL)
icon = QIcon("./old_ico/root.ico");
else if (primitive->getNumChildren() == 0)
icon = QIcon("./old_ico/property.ico"); icon = QIcon("./old_ico/property.ico");
else else
icon = QIcon("./old_ico/folder_h.ico"); icon = QIcon("./old_ico/folder_h.ico");
@ -127,18 +138,29 @@ PrimitiveItem::~PrimitiveItem()
{ {
} }
PrimitivesItem::PrimitivesItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent) NLLIGO::IPrimitive *PrimitiveItem::primitive() const
{
return m_primitive;
}
const NLLIGO::CPrimitiveClass *PrimitiveItem::primitiveClass() const
{
return NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*m_primitive);
}
RootPrimitiveItem::RootPrimitiveItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent)
: PrimitiveItem(primitives->RootNode, parent), : PrimitiveItem(primitives->RootNode, parent),
m_primitives(primitives) m_primitives(primitives)
{ {
setData(1, name); setData(1, name);
} }
/* /*
PrimitivesItem::PrimitivesItem(const PrimitiveItem &other) RootPrimitiveItem::RootPrimitiveItem(const RootPrimitiveItem &other)
{ {
} }
*/ */
PrimitivesItem::~PrimitivesItem() RootPrimitiveItem::~RootPrimitiveItem()
{ {
} }

View file

@ -21,6 +21,7 @@
// NeL includes // NeL includes
#include <nel/ligo/primitive.h> #include <nel/ligo/primitive.h>
#include <nel/ligo/primitive_class.h>
// Qt includes // Qt includes
#include <QList> #include <QList>
@ -43,6 +44,7 @@ public:
virtual ~BaseTreeItem(); virtual ~BaseTreeItem();
void appendChild(BaseTreeItem *child); void appendChild(BaseTreeItem *child);
void deleteChild(int row);
BaseTreeItem *child(int row); BaseTreeItem *child(int row);
int childCount() const; int childCount() const;
@ -74,6 +76,9 @@ public:
PrimitiveItem(const PrimitiveItem &other); PrimitiveItem(const PrimitiveItem &other);
virtual ~PrimitiveItem(); virtual ~PrimitiveItem();
NLLIGO::IPrimitive *primitive() const;
const NLLIGO::CPrimitiveClass *primitiveClass() const;
private: private:
NLLIGO::IPrimitive *m_primitive; NLLIGO::IPrimitive *m_primitive;
}; };
@ -83,12 +88,12 @@ private:
@brief @brief
@details @details
*/ */
class PrimitivesItem: public PrimitiveItem class RootPrimitiveItem: public PrimitiveItem
{ {
public: public:
PrimitivesItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent); RootPrimitiveItem(const QString &name, NLLIGO::CPrimitives *primitives, BaseTreeItem *parent);
PrimitivesItem(const PrimitiveItem &other); RootPrimitiveItem(const RootPrimitiveItem &other);
virtual ~PrimitivesItem(); virtual ~RootPrimitiveItem();
private: private:
NLLIGO::CPrimitives *m_primitives; NLLIGO::CPrimitives *m_primitives;

View file

@ -14,14 +14,18 @@
// You should have received a copy of the GNU Affero General Public License // 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/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <nel/ligo/primitive.h> // Project includes
#include <nel/ligo/ligo_config.h>
#include <nel/ligo/primitive_class.h>
#include <QtGui>
#include "primitive_item.h" #include "primitive_item.h"
#include "primitives_model.h" #include "primitives_model.h"
#include "world_editor_misc.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 namespace WorldEditor
{ {
@ -136,11 +140,77 @@ int PrimitivesTreeModel::rowCount(const QModelIndex &parent) const
return parentItem->childCount(); return parentItem->childCount();
} }
void PrimitivesTreeModel::addPrimitives(const QString &name, NLLIGO::CPrimitives *primitives) NLLIGO::IPrimitive *PrimitivesTreeModel::primitive(const QModelIndex &index)
{
NLLIGO::IPrimitive *prim = 0;
if (index.isValid())
{
PrimitiveItem *item = static_cast<PrimitiveItem *>(index.internalPointer());
prim = item->primitive();
}
return prim;
}
const NLLIGO::CPrimitiveClass *PrimitivesTreeModel::primitiveClass(const QModelIndex &index)
{
if (index.isValid())
{
NLLIGO::IPrimitive *prim = primitive(index);
return ligoConfig()->getPrimitiveClass(*prim);
}
return 0;
}
void PrimitivesTreeModel::loadPrimitive(const QString &fileName)
{
NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives();
// set the primitive context
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = primitives;
NLLIGO::loadXmlPrimitiveFile(*primitives, fileName.toStdString(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig);
// unset the context
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = NULL;
addRootPrimitive(fileName, primitives);
}
void PrimitivesTreeModel::newPrimitiveWithoutUndo(const QString &className, uint id, const QModelIndex &parent)
{
const NLLIGO::CPrimitiveClass *primClass = primitiveClass(parent);
float delta = 10;
// TODO: Set the context
//CPrimitiveContext::instance().CurrentPrimitive = &_DataHierarchy[locator._LocateStack[0]].Primitives;
NLLIGO::IPrimitive *newPrimitive = createPrimitive(className.toStdString().c_str(), className.toStdString().c_str()
, NLMISC::CVector(), delta, primClass->DynamicChildren[id].Parameters, primitive(parent));
// unset the context
//CPrimitiveContext::instance().CurrentPrimitive = NULL;
if (newPrimitive != 0)
{
scanPrimitive(newPrimitive, parent);
}
}
void PrimitivesTreeModel::deletePrimitiveWithoutUndo(const QModelIndex &index)
{
deletePrimitive(primitive(index));
removeRows(index.row(), index.parent());
}
void PrimitivesTreeModel::addRootPrimitive(const QString &name, NLLIGO::CPrimitives *primitives)
{ {
beginResetModel(); beginResetModel();
PrimitivesItem *newPrimitives = new PrimitivesItem(name, primitives, m_rootItem);
// Create root primitive
RootPrimitiveItem *newPrimitives = new RootPrimitiveItem(name, primitives, m_rootItem);
m_rootItem->appendChild(newPrimitives); m_rootItem->appendChild(newPrimitives);
// Scan childs items and add in tree model
for (uint i = 0; i < primitives->RootNode->getNumChildren(); ++i) for (uint i = 0; i < primitives->RootNode->getNumChildren(); ++i)
{ {
NLLIGO::IPrimitive *childPrim; NLLIGO::IPrimitive *childPrim;
@ -150,17 +220,33 @@ void PrimitivesTreeModel::addPrimitives(const QString &name, NLLIGO::CPrimitives
endResetModel(); endResetModel();
} }
void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent) void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, const QModelIndex &parentIndex)
{ {
// const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->getPrimitiveClass(*prim); PrimitiveItem *parent = static_cast<PrimitiveItem *>(parentIndex.internalPointer());
// nlassert (primClass);
// if (primClass->Type == NLLIGO::CPrimitiveClass::Alias)
// return;
if (prim->getClassName() == "CPrimAlias")
return;
// Add in tree model
beginInsertRows(parentIndex, parent->childCount(), parent->childCount());
PrimitiveItem *newItem = new PrimitiveItem(prim, parent); PrimitiveItem *newItem = new PrimitiveItem(prim, parent);
parent->appendChild(newItem); parent->appendChild(newItem);
endInsertRows();
// Scan childs items and add in tree model
QModelIndex childIndex = index(parent->childCount() - 1, 0, parentIndex);
for (uint i = 0; i < prim->getNumChildren(); ++i)
{
NLLIGO::IPrimitive *childPrim;
prim->getChild(childPrim, i);
scanPrimitive(childPrim, childIndex);
}
}
void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent)
{
// Add in tree model
PrimitiveItem *newItem = new PrimitiveItem(prim, parent);
parent->appendChild(newItem);
// Scan childs items and add in tree model
for (uint i = 0; i < prim->getNumChildren(); ++i) for (uint i = 0; i < prim->getNumChildren(); ++i)
{ {
NLLIGO::IPrimitive *childPrim; NLLIGO::IPrimitive *childPrim;
@ -169,4 +255,23 @@ void PrimitivesTreeModel::scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *
} }
} }
void PrimitivesTreeModel::removeRows(int position, const QModelIndex &parent)
{
BaseTreeItem *item = static_cast<BaseTreeItem *>(parent.internalPointer())->child(position);
// Delete all child items from tree model
while (item->childCount() != 0)
removeRows(0, parent.child(position, 0));
// Delete item
beginRemoveRows(parent, position, position);
static_cast<BaseTreeItem *>(parent.internalPointer())->deleteChild(position);
endRemoveRows();
}
NLLIGO::CLigoConfig *PrimitivesTreeModel::ligoConfig() const
{
return NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig;
}
} /* namespace WorldEditor */ } /* namespace WorldEditor */

View file

@ -18,8 +18,13 @@
#ifndef PRIMITIVES_MODEL_H #ifndef PRIMITIVES_MODEL_H
#define PRIMITIVES_MODEL_H #define PRIMITIVES_MODEL_H
// NeL includes
#include <nel/misc/vector.h>
#include <nel/ligo/primitive.h> #include <nel/ligo/primitive.h>
#include <nel/ligo/primitive_class.h>
#include <nel/ligo/ligo_config.h>
// Qt includes
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <QModelIndex> #include <QModelIndex>
#include <QVariant> #include <QVariant>
@ -28,6 +33,7 @@ namespace WorldEditor
{ {
class BaseTreeItem; class BaseTreeItem;
class PrimitiveItem;
/** /**
@class PrimitivesTreeModel @class PrimitivesTreeModel
@ -52,11 +58,31 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const; int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const;
void addPrimitives(const QString &name, NLLIGO::CPrimitives *primitives); // Get primitive
NLLIGO::IPrimitive *primitive(const QModelIndex &index);
// Get primitive class
const NLLIGO::CPrimitiveClass *primitiveClass(const QModelIndex &index);
// Load primitive from file
void loadPrimitive(const QString &fileName);
// Create new primitive and add in tree model
void newPrimitiveWithoutUndo(const QString &className, uint id, const QModelIndex &parent);
void deletePrimitiveWithoutUndo(const QModelIndex &index);
NLLIGO::CLigoConfig *ligoConfig() const;
private: private:
// Add root primitive in tree model and add all its sub-items.
void addRootPrimitive(const QString &name, NLLIGO::CPrimitives *primitives);
void scanPrimitive(NLLIGO::IPrimitive *prim, const QModelIndex &parentIndex);
void scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent = 0); void scanPrimitive(NLLIGO::IPrimitive *prim, BaseTreeItem *parent = 0);
void removeRows(int position, const QModelIndex &parent);
BaseTreeItem *m_rootItem; BaseTreeItem *m_rootItem;
}; };

View file

@ -0,0 +1,197 @@
// 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 "primitive_item.h"
#include "primitives_model.h"
// NeL includes
#include <nel/ligo/primitive.h>
#include <nel/ligo/ligo_config.h>
#include <nel/ligo/primitive_class.h>
// Qt includes
#include <QContextMenuEvent>
#include <QtGui/QMenu>
namespace WorldEditor
{
PrimitivesView::PrimitivesView(QWidget *parent)
: QTreeView(parent),
m_primitivesTreeModel(0)
{
setContextMenuPolicy(Qt::DefaultContextMenu);
m_deleteAction = new QAction("Delete", this);
m_selectChildrenAction = new QAction("Select children", this);
m_helpAction = new QAction("Help", this);
m_showAction = new QAction("Show", this);
m_hideAction = new QAction("Hide", this);
connect(m_deleteAction, SIGNAL(triggered()), this, SLOT(deletePrimitives()));
connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(clickedItem(QModelIndex)));
#ifdef Q_OS_DARWIN
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
#endif
}
PrimitivesView::~PrimitivesView()
{
}
void PrimitivesView::setModel(PrimitivesTreeModel *model)
{
QTreeView::setModel(model);
m_primitivesTreeModel = model;
}
void PrimitivesView::clickedItem(const QModelIndex &index)
{
}
void PrimitivesView::deletePrimitives()
{
QModelIndexList indexList = selectionModel()->selectedRows();
// TODO: use QPersistentModelIndex for deleting several items
m_primitivesTreeModel->deletePrimitiveWithoutUndo(indexList.first());
}
void PrimitivesView::addNewPrimitive(int value)
{
QModelIndexList indexList = selectionModel()->selectedRows();
const NLLIGO::CPrimitiveClass *primClass = m_primitivesTreeModel->primitiveClass(indexList.first());
// Get class name
QString className = primClass->DynamicChildren[value].ClassName.c_str();
m_primitivesTreeModel->newPrimitiveWithoutUndo(className, value, indexList.first());
}
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);
popurMenu->addAction(m_deleteAction);
popurMenu->addAction(m_selectChildrenAction);
popurMenu->addAction(m_helpAction);
popurMenu->addSeparator();
popurMenu->addAction(m_showAction);
popurMenu->addAction(m_hideAction);
popurMenu->addSeparator();
QSignalMapper *addSignalMapper = new QSignalMapper(this);
QSignalMapper *generateSignalMapper = new QSignalMapper(this);
QSignalMapper *openSignalMapper = new QSignalMapper(this);
connect(addSignalMapper, SIGNAL(mapped(int)), this, SLOT(addNewPrimitive(int)));
connect(generateSignalMapper, SIGNAL(mapped(int)), this, SLOT(generatePrimitives(int)));
//connect(openSignalMapper, SIGNAL(mapped(int)), this, SLOT(openItem(int)));
if (indexList.size() == 1)
{
const NLLIGO::CPrimitiveClass *primClass = m_primitivesTreeModel->primitiveClass(indexList.first());
// What class is it ?
if (primClass && primClass->DynamicChildren.size())
{
popurMenu->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("./old_ico/%1.ico").arg(className));
// Create and add action in popur menu
QAction *action = popurMenu->addAction(icon, QString("Add %1").arg(className));
addSignalMapper->setMapping(action, i);
connect(action, SIGNAL(triggered()), addSignalMapper, SLOT(map()));
}
}
// What class is it ?
if (primClass && primClass->GeneratedChildren.size())
{
popurMenu->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 = popurMenu->addAction(QString("Generate %1").arg(childName));
generateSignalMapper->setMapping(action, i);
connect(generateSignalMapper, SIGNAL(triggered()), addSignalMapper, SLOT(map()));
}
}
/*
// What class is it ?
if (primClass)
{
// Look for files
std::vector<std::string> filenames;
// Filenames
buildFilenameVector (*Selection.front (), filenames);
// File names ?
if (!filenames.empty ())
{
// Add separator
popurMenu->addSeparator();
// Found ?
for (uint i = 0; i < filenames.size(); i++)
{
// Add a menu entry
pMenu->AppendMenu (MF_STRING, ID_EDIT_OPEN_FILE_BEGIN+i, ("Open "+NLMISC::CFile::getFilename (filenames[i])).c_str ());
}
}
}
*/
}
popurMenu->exec(event->globalPos());
delete popurMenu;
delete addSignalMapper;
delete generateSignalMapper;
delete openSignalMapper;
event->accept();
}
} /* namespace WorldEditor */

View file

@ -0,0 +1,74 @@
// 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
// 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 <QPersistentModelIndex>
namespace WorldEditor
{
class BaseTreeItem;
class PrimitivesTreeModel;
/**
@class PrimitivesView
@brief
@details
*/
class PrimitivesView : public QTreeView
{
Q_OBJECT
public:
PrimitivesView(QWidget *parent = 0);
~PrimitivesView();
virtual void setModel(PrimitivesTreeModel *model);
private Q_SLOTS:
void clickedItem(const QModelIndex &index);
void deletePrimitives();
void addNewPrimitive(int value);
void generatePrimitives(int value);
void openItem(int value);
protected:
void contextMenuEvent(QContextMenuEvent *event);
QAction *m_deleteAction;
QAction *m_selectChildrenAction;
QAction *m_helpAction;
QAction *m_showAction;
QAction *m_hideAction;
PrimitivesTreeModel *m_primitivesTreeModel;
};
} /* namespace WorldEditor */
#endif // PRIMITIVES_VIEW_H

View file

@ -0,0 +1,494 @@
// 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_misc.h"
// NeL includes
#include <nel/misc/debug.h>
#include <nel/ligo/ligo_config.h>
// Qt includes
namespace WorldEditor
{
uint32 getUniqueId()
{
// Wait 1 ms
sint64 time = NLMISC::CTime::getLocalTime ();
sint64 time2;
while ((time2 = NLMISC::CTime::getLocalTime ()) == time)
{
}
return (uint32)time2;
}
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 &parameter = 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;
// Name ?
if (initParameters[p].Name == "name")
type = NLLIGO::CPrimitiveClass::CParameter::String;
// Continue ?
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 = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->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:
primitive = new NLLIGO::CPrimPath;
break;
case NLLIGO::CPrimitiveClass::Zone:
primitive = new NLLIGO::CPrimZone;
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;
}
// Prim file ?
if (primClass->Type == NLLIGO::CPrimitiveClass::Bitmap)
{
// Create a dialog file
//CFileDialogEx dialog (BASE_REGISTRY_KEY, "image", TRUE, primClass->FileExtension.c_str (), NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
// (primClass->FileType+" (*."+primClass->FileExtension+")|*."+primClass->FileExtension+"|All Files (*.*)|*.*||").c_str (), getMainFrame ());
//if (dialog.DoModal() == IDOK)
//{
// Save filename
// static_cast<CPrimBitmap*>(primitive)->init(dialog.GetPathName ());
//}
}
// Continue ?
if (primitive)
{
// Auto init ?
if (!primClass->AutoInit)
{
// Make a vector of locator
//CDatabaseLocatorPointer locatorPtr;
//getLocator (locatorPtr, locator);
std::list<NLLIGO::IPrimitive*> locators;
//locators.push_back (const_cast<IPrimitive*> (locatorPtr.Primitive));
// Yes, go
//CDialogProperties dialogProperty (locators, getMainFrame ());
//dialogProperty.DoModal ();
}
// Eval the default name property
std::string name;
if (!primitive->getPropertyByName ("name", name) || name.empty())
{
const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->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));
}
}
}
}
}
// Init primitive default values
primitive->initDefaultValues(*NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig);
}
// Done
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)
{
// Modified
bool modified = false;
// Get the prim class
const NLLIGO::CPrimitiveClass *primClass = NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig->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;
}
} /* namespace WorldEditor */

View file

@ -0,0 +1,55 @@
// 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_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>
// Qt includes
namespace WorldEditor
{
// Generate unique identificator
uint32 getUniqueId();
// 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);
// Remove the primitive and don't delete it.
//void takeAtPrimitive(NLLIGO::IPrimitive *primitive);
void deletePrimitive(NLLIGO::IPrimitive *primitive);
} /* namespace WorldEditor */
#endif // WORLD_EDITOR_MISC_H

View file

@ -20,10 +20,14 @@
#include "world_editor_constants.h" #include "world_editor_constants.h"
#include "primitives_model.h" #include "primitives_model.h"
// Core
#include "../core/icore.h" #include "../core/icore.h"
#include "../core/imenu_manager.h" #include "../core/imenu_manager.h"
#include "../core/core_constants.h" #include "../core/core_constants.h"
// Lanscape Editor plugin
//#include "../landscape_editor/project_settings_dialog.h"
// NeL includes // NeL includes
#include <nel/misc/path.h> #include <nel/misc/path.h>
#include <nel/ligo/primitive_utils.h> #include <nel/ligo/primitive_utils.h>
@ -55,12 +59,12 @@ WorldEditorWindow::WorldEditorWindow(QWidget *parent)
createMenus(); createMenus();
createToolBars(); createToolBars();
// readSettings(); readSettings();
} }
WorldEditorWindow::~WorldEditorWindow() WorldEditorWindow::~WorldEditorWindow()
{ {
// writeSettings(); writeSettings();
} }
QUndoStack *WorldEditorWindow::undoStack() const QUndoStack *WorldEditorWindow::undoStack() const
@ -89,14 +93,20 @@ void WorldEditorWindow::open()
void WorldEditorWindow::loadPrimitive(const QString &fileName) void WorldEditorWindow::loadPrimitive(const QString &fileName)
{ {
NLLIGO::CPrimitives *primitives = new NLLIGO::CPrimitives(); m_primitivesModel->loadPrimitive(fileName);
}
// set the primitive context void WorldEditorWindow::openProjectSettings()
NLLIGO::CPrimitiveContext::instance().CurrentPrimitive = primitives; {
/*
NLLIGO::loadXmlPrimitiveFile(*primitives, fileName.toStdString(), *NLLIGO::CPrimitiveContext::instance().CurrentLigoConfig); LandscapeEditor::ProjectSettingsDialog *dialog = new LandscapeEditor::ProjectSettingsDialog("", this);
dialog->show();
m_primitivesModel->addPrimitives(fileName, primitives); int ok = dialog->exec();
if (ok == QDialog::Accepted)
{
}
delete dialog;
*/
} }
void WorldEditorWindow::createMenus() void WorldEditorWindow::createMenus()

View file

@ -43,6 +43,8 @@ public Q_SLOTS:
void open(); void open();
private Q_SLOTS: private Q_SLOTS:
void openProjectSettings();
private: private:
void createMenus(); void createMenus();
void createToolBars(); void createToolBars();

View file

@ -61,7 +61,23 @@
<number>3</number> <number>3</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QTreeView" name="treePrimitivesView"/> <widget class="WorldEditor::PrimitivesView" name="treePrimitivesView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="animated">
<bool>true</bool>
</property>
<attribute name="headerCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="headerDefaultSectionSize">
<number>250</number>
</attribute>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -83,6 +99,11 @@
<extends>QGraphicsView</extends> <extends>QGraphicsView</extends>
<header>../landscape_editor/landscape_view.h</header> <header>../landscape_editor/landscape_view.h</header>
</customwidget> </customwidget>
<customwidget>
<class>WorldEditor::PrimitivesView</class>
<extends>QTreeView</extends>
<header>primitives_view.h</header>
</customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="world_editor.qrc"/> <include location="world_editor.qrc"/>