mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-28 08:39:40 +00:00
Merge branch 'cellselect'
This commit is contained in:
commit
d205d5f0af
17 changed files with 370 additions and 7 deletions
|
@ -24,7 +24,7 @@ opencs_units (model/world
|
|||
|
||||
opencs_units_noqt (model/world
|
||||
universalid record commands columnbase scriptcontext cell refidcollection
|
||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata
|
||||
refidadapter refiddata refidadapterimp ref collectionbase refcollection columns infocollection tablemimedata cellcoordinates cellselection
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (model/world
|
||||
|
|
60
apps/opencs/model/world/cellcoordinates.cpp
Normal file
60
apps/opencs/model/world/cellcoordinates.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
|
||||
#include "cellcoordinates.hpp"
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
CSMWorld::CellCoordinates::CellCoordinates() : mX (0), mY (0) {}
|
||||
|
||||
CSMWorld::CellCoordinates::CellCoordinates (int x, int y) : mX (x), mY (y) {}
|
||||
|
||||
int CSMWorld::CellCoordinates::getX() const
|
||||
{
|
||||
return mX;
|
||||
}
|
||||
|
||||
int CSMWorld::CellCoordinates::getY() const
|
||||
{
|
||||
return mY;
|
||||
}
|
||||
|
||||
CSMWorld::CellCoordinates CSMWorld::CellCoordinates::move (int x, int y) const
|
||||
{
|
||||
return CellCoordinates (mX + x, mY + y);
|
||||
}
|
||||
|
||||
std::string CSMWorld::CellCoordinates::getId (const std::string& worldspace) const
|
||||
{
|
||||
// we ignore the worldspace for now, since there is only one (will change in 1.1)
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << "#" << mX << " " << mY;
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
bool CSMWorld::operator== (const CellCoordinates& left, const CellCoordinates& right)
|
||||
{
|
||||
return left.getX()==right.getX() && left.getY()==right.getY();
|
||||
}
|
||||
|
||||
bool CSMWorld::operator!= (const CellCoordinates& left, const CellCoordinates& right)
|
||||
{
|
||||
return !(left==right);
|
||||
}
|
||||
|
||||
bool CSMWorld::operator< (const CellCoordinates& left, const CellCoordinates& right)
|
||||
{
|
||||
if (left.getX()<right.getX())
|
||||
return true;
|
||||
|
||||
if (left.getX()>right.getX())
|
||||
return false;
|
||||
|
||||
return left.getY()<right.getY();
|
||||
}
|
||||
|
||||
std::ostream& CSMWorld::operator<< (std::ostream& stream, const CellCoordinates& coordiantes)
|
||||
{
|
||||
return stream << coordiantes.getX() << ", " << coordiantes.getY();
|
||||
}
|
42
apps/opencs/model/world/cellcoordinates.hpp
Normal file
42
apps/opencs/model/world/cellcoordinates.hpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#ifndef CSM_WOLRD_CELLCOORDINATES_H
|
||||
#define CSM_WOLRD_CELLCOORDINATES_H
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class CellCoordinates
|
||||
{
|
||||
int mX;
|
||||
int mY;
|
||||
|
||||
public:
|
||||
|
||||
CellCoordinates();
|
||||
|
||||
CellCoordinates (int x, int y);
|
||||
|
||||
int getX() const;
|
||||
|
||||
int getY() const;
|
||||
|
||||
CellCoordinates move (int x, int y) const;
|
||||
///< Return a copy of *this, moved by the given offset.
|
||||
|
||||
std::string getId (const std::string& worldspace) const;
|
||||
///< Return the ID for the cell at these coordinates.
|
||||
};
|
||||
|
||||
bool operator== (const CellCoordinates& left, const CellCoordinates& right);
|
||||
bool operator!= (const CellCoordinates& left, const CellCoordinates& right);
|
||||
bool operator< (const CellCoordinates& left, const CellCoordinates& right);
|
||||
|
||||
std::ostream& operator<< (std::ostream& stream, const CellCoordinates& coordiantes);
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE (CSMWorld::CellCoordinates)
|
||||
|
||||
#endif
|
83
apps/opencs/model/world/cellselection.cpp
Normal file
83
apps/opencs/model/world/cellselection.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
|
||||
#include "cellselection.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include <limits>
|
||||
|
||||
CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::begin() const
|
||||
{
|
||||
return mCells.begin();
|
||||
}
|
||||
|
||||
CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::end() const
|
||||
{
|
||||
return mCells.end();
|
||||
}
|
||||
|
||||
bool CSMWorld::CellSelection::add (const CellCoordinates& coordinates)
|
||||
{
|
||||
return mCells.insert (coordinates).second;
|
||||
}
|
||||
|
||||
void CSMWorld::CellSelection::remove (const CellCoordinates& coordinates)
|
||||
{
|
||||
mCells.erase (coordinates);
|
||||
}
|
||||
|
||||
bool CSMWorld::CellSelection::has (const CellCoordinates& coordinates) const
|
||||
{
|
||||
return mCells.find (coordinates)!=end();
|
||||
}
|
||||
|
||||
int CSMWorld::CellSelection::getSize() const
|
||||
{
|
||||
return mCells.size();
|
||||
}
|
||||
|
||||
CSMWorld::CellCoordinates CSMWorld::CellSelection::getCentre() const
|
||||
{
|
||||
if (mCells.empty())
|
||||
throw std::logic_error ("call of getCentre on empty cell selection");
|
||||
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
|
||||
for (Iterator iter = begin(); iter!=end(); ++iter)
|
||||
{
|
||||
x += iter->getX();
|
||||
y += iter->getY();
|
||||
}
|
||||
|
||||
x /= mCells.size();
|
||||
y /= mCells.size();
|
||||
|
||||
Iterator closest = begin();
|
||||
double distance = std::numeric_limits<double>::max();
|
||||
|
||||
for (Iterator iter (begin()); iter!=end(); ++iter)
|
||||
{
|
||||
double deltaX = x - iter->getX();
|
||||
double deltaY = y - iter->getY();
|
||||
|
||||
double delta = std::sqrt (deltaX * deltaX + deltaY * deltaY);
|
||||
|
||||
if (delta<distance)
|
||||
{
|
||||
distance = delta;
|
||||
closest = iter;
|
||||
}
|
||||
}
|
||||
|
||||
return *closest;
|
||||
}
|
||||
|
||||
void CSMWorld::CellSelection::move (int x, int y)
|
||||
{
|
||||
Container moved;
|
||||
|
||||
for (Iterator iter = begin(); iter!=end(); ++iter)
|
||||
moved.insert (iter->move (x, y));
|
||||
|
||||
mCells.swap (moved);
|
||||
}
|
57
apps/opencs/model/world/cellselection.hpp
Normal file
57
apps/opencs/model/world/cellselection.hpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef CSM_WOLRD_CELLSELECTION_H
|
||||
#define CSM_WOLRD_CELLSELECTION_H
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
#include "cellcoordinates.hpp"
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
/// \brief Selection of cells in a paged worldspace
|
||||
///
|
||||
/// \note The CellSelection does not specify the worldspace it applies to.
|
||||
class CellSelection
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::set<CellCoordinates> Container;
|
||||
typedef Container::const_iterator Iterator;
|
||||
|
||||
private:
|
||||
|
||||
Container mCells;
|
||||
|
||||
public:
|
||||
|
||||
Iterator begin() const;
|
||||
|
||||
Iterator end() const;
|
||||
|
||||
bool add (const CellCoordinates& coordinates);
|
||||
///< Ignored if the cell specified by \a coordinates is already part of the selection.
|
||||
///
|
||||
/// \return Was a cell added to the collection?
|
||||
|
||||
void remove (const CellCoordinates& coordinates);
|
||||
///< ignored if the cell specified by \a coordinates is not part of the selection.
|
||||
|
||||
bool has (const CellCoordinates& coordinates) const;
|
||||
///< \return Is the cell specified by \a coordinates part of the selection?
|
||||
|
||||
int getSize() const;
|
||||
///< Return number of cells.
|
||||
|
||||
CellCoordinates getCentre() const;
|
||||
///< Return the selected cell that is closest to the geometric centre of the selection.
|
||||
///
|
||||
/// \attention This function must not be called on selections that are empty.
|
||||
|
||||
void move (int x, int y);
|
||||
};
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE (CSMWorld::CellSelection)
|
||||
|
||||
#endif
|
|
@ -1,6 +1,47 @@
|
|||
|
||||
#include "pagedworldspacewidget.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent)
|
||||
: WorldspaceWidget (parent)
|
||||
{}
|
||||
{}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint)
|
||||
{
|
||||
if (!hint.empty())
|
||||
{
|
||||
CSMWorld::CellSelection selection;
|
||||
|
||||
if (hint[0]=='c')
|
||||
{
|
||||
// syntax: c:#x1 y1; #x2 y2 (number of coordinate pairs can be 0 or larger)
|
||||
char ignore;
|
||||
|
||||
std::istringstream stream (hint.c_str());
|
||||
if (stream >> ignore)
|
||||
{
|
||||
char ignore1; // : or ;
|
||||
char ignore2; // #
|
||||
int x, y;
|
||||
|
||||
while (stream >> ignore1 >> ignore2 >> x >> y)
|
||||
selection.add (CSMWorld::CellCoordinates (x, y));
|
||||
|
||||
/// \todo adjust camera position
|
||||
}
|
||||
}
|
||||
else if (hint[0]=='r')
|
||||
{
|
||||
/// \todo implement 'r' type hints
|
||||
}
|
||||
|
||||
setCellSelection (selection);
|
||||
}
|
||||
}
|
||||
|
||||
void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSelection& selection)
|
||||
{
|
||||
mSelection = selection;
|
||||
emit cellSelectionChanged (mSelection);
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||
#define OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||
|
||||
#include "../../model/world/cellselection.hpp"
|
||||
|
||||
#include "worldspacewidget.hpp"
|
||||
|
||||
namespace CSVRender
|
||||
|
@ -9,9 +11,22 @@ namespace CSVRender
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
CSMWorld::CellSelection mSelection;
|
||||
|
||||
public:
|
||||
|
||||
PagedWorldspaceWidget (QWidget *parent);
|
||||
///< \note Sets the cell area selection to an invalid value to indicate that currently
|
||||
/// no cells are displayed. The cells to be displayed will be specified later through
|
||||
/// hint system.
|
||||
|
||||
virtual void useViewHint (const std::string& hint);
|
||||
|
||||
void setCellSelection (const CSMWorld::CellSelection& selection);
|
||||
|
||||
signals:
|
||||
|
||||
void cellSelectionChanged (const CSMWorld::CellSelection& selection);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
|||
setNavigation (&mOrbit);
|
||||
}
|
||||
|
||||
void CSVRender::WorldspaceWidget::useViewHint (const std::string& hint) {}
|
||||
|
||||
void CSVRender::WorldspaceWidget::selectDefaultNavigationMode()
|
||||
{
|
||||
setNavigation (&m1st);
|
||||
|
|
|
@ -33,6 +33,9 @@ namespace CSVRender
|
|||
|
||||
void selectDefaultNavigationMode();
|
||||
|
||||
virtual void useViewHint (const std::string& hint);
|
||||
///< Default-implementation: ignored.
|
||||
|
||||
private slots:
|
||||
|
||||
void selectNavigationMode (const std::string& mode);
|
||||
|
|
|
@ -28,7 +28,7 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo
|
|||
else
|
||||
mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), this);
|
||||
|
||||
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||
SceneToolbar *toolbar = new SceneToolbar (48+6, this);
|
||||
|
||||
SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar);
|
||||
toolbar->addTool (lightingTool);
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
|
||||
#include "scenesubview.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include "../../model/doc/document.hpp"
|
||||
|
||||
#include "../../model/world/cellselection.hpp"
|
||||
|
||||
#include "../filter/filterbox.hpp"
|
||||
|
||||
#include "../render/pagedworldspacewidget.hpp"
|
||||
|
@ -32,10 +36,15 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D
|
|||
|
||||
layout2->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||
|
||||
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||
SceneToolbar *toolbar = new SceneToolbar (48+6, this);
|
||||
|
||||
if (id.getId()=="sys::default")
|
||||
mScene = new CSVRender::PagedWorldspaceWidget (this);
|
||||
{
|
||||
CSVRender::PagedWorldspaceWidget *widget = new CSVRender::PagedWorldspaceWidget (this);
|
||||
mScene = widget;
|
||||
connect (widget, SIGNAL (cellSelectionChanged (const CSMWorld::CellSelection&)),
|
||||
this, SLOT (cellSelectionChanged (const CSMWorld::CellSelection&)));
|
||||
}
|
||||
else
|
||||
mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this);
|
||||
|
||||
|
@ -83,7 +92,38 @@ void CSVWorld::SceneSubView::setStatusBar (bool show)
|
|||
mBottom->setStatusBar (show);
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::useHint (const std::string& hint)
|
||||
{
|
||||
mScene->useViewHint (hint);
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::closeRequest()
|
||||
{
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection& selection)
|
||||
{
|
||||
int size = selection.getSize();
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "Scene: " << getUniversalId().getId();
|
||||
|
||||
if (size==0)
|
||||
stream << " (empty)";
|
||||
else if (size==1)
|
||||
{
|
||||
stream << " (" << *selection.begin() << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << " (" << selection.getCentre() << " and " << size-1 << " more ";
|
||||
|
||||
if (size>1)
|
||||
stream << "cells around it)";
|
||||
else
|
||||
stream << "cell around it)";
|
||||
}
|
||||
|
||||
setWindowTitle (QString::fromUtf8 (stream.str().c_str()));
|
||||
}
|
|
@ -5,6 +5,11 @@
|
|||
|
||||
class QModelIndex;
|
||||
|
||||
namespace CSMWorld
|
||||
{
|
||||
class CellSelection;
|
||||
}
|
||||
|
||||
namespace CSMDoc
|
||||
{
|
||||
class Document;
|
||||
|
@ -38,9 +43,13 @@ namespace CSVWorld
|
|||
|
||||
virtual void setStatusBar (bool show);
|
||||
|
||||
virtual void useHint (const std::string& hint);
|
||||
|
||||
private slots:
|
||||
|
||||
void closeRequest();
|
||||
|
||||
void cellSelectionChanged (const CSMWorld::CellSelection& selection);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
CSVWorld::SceneTool::SceneTool (SceneToolbar *parent) : QPushButton (parent)
|
||||
{
|
||||
setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
setIconSize (QSize (parent->getIconSize(), parent->getIconSize()));
|
||||
setFixedSize (parent->getButtonSize(), parent->getButtonSize());
|
||||
|
||||
connect (this, SIGNAL (clicked()), this, SLOT (openRequest()));
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "scenetool.hpp"
|
||||
|
||||
CSVWorld::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent)
|
||||
: QWidget (parent), mButtonSize (buttonSize)
|
||||
: QWidget (parent), mButtonSize (buttonSize), mIconSize (buttonSize-6)
|
||||
{
|
||||
setFixedWidth (mButtonSize);
|
||||
|
||||
|
@ -26,4 +26,9 @@ void CSVWorld::SceneToolbar::addTool (SceneTool *tool)
|
|||
int CSVWorld::SceneToolbar::getButtonSize() const
|
||||
{
|
||||
return mButtonSize;
|
||||
}
|
||||
|
||||
int CSVWorld::SceneToolbar::getIconSize() const
|
||||
{
|
||||
return mIconSize;
|
||||
}
|
|
@ -15,6 +15,7 @@ namespace CSVWorld
|
|||
|
||||
QVBoxLayout *mLayout;
|
||||
int mButtonSize;
|
||||
int mIconSize;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -23,6 +24,8 @@ namespace CSVWorld
|
|||
void addTool (SceneTool *tool);
|
||||
|
||||
int getButtonSize() const;
|
||||
|
||||
int getIconSize() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "scenetoolbar.hpp"
|
||||
|
||||
CSVWorld::SceneToolMode::SceneToolMode (SceneToolbar *parent)
|
||||
: SceneTool (parent), mButtonSize (parent->getButtonSize())
|
||||
: SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize())
|
||||
{
|
||||
mPanel = new QFrame (this, Qt::Popup);
|
||||
|
||||
|
@ -29,6 +29,7 @@ void CSVWorld::SceneToolMode::addButton (const std::string& icon, const std::str
|
|||
{
|
||||
QPushButton *button = new QPushButton (QIcon (QPixmap (icon.c_str())), "", mPanel);
|
||||
button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
button->setIconSize (QSize (mIconSize, mIconSize));
|
||||
button->setFixedSize (mButtonSize, mButtonSize);
|
||||
|
||||
mLayout->addWidget (button);
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace CSVWorld
|
|||
QHBoxLayout *mLayout;
|
||||
std::map<QPushButton *, std::string> mButtons; // widget, id
|
||||
int mButtonSize;
|
||||
int mIconSize;
|
||||
|
||||
public:
|
||||
|
||||
|
|
Loading…
Reference in a new issue