Merge branch 'cellselect'

actorid
Marc Zinnschlag 11 years ago
commit d205d5f0af

@ -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

@ -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();
}

@ -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

@ -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);
}

@ -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…
Cancel
Save