Merge branch 'master' of https://github.com/OpenMW/openmw.git into AIFix2
Conflicts: apps/openmw/mwmechanics/aifollow.cppactorid
commit
bee057346b
@ -1,93 +0,0 @@
|
|||||||
Copyright (c) 2010, 2011 Georg Duffner (http://www.georgduffner.at)
|
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
||||||
This license is copied below, and is also available with a FAQ at:
|
|
||||||
http://scripts.sil.org/OFL
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------
|
|
||||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
||||||
-----------------------------------------------------------
|
|
||||||
|
|
||||||
PREAMBLE
|
|
||||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
||||||
development of collaborative font projects, to support the font creation
|
|
||||||
efforts of academic and linguistic communities, and to provide a free and
|
|
||||||
open framework in which fonts may be shared and improved in partnership
|
|
||||||
with others.
|
|
||||||
|
|
||||||
The OFL allows the licensed fonts to be used, studied, modified and
|
|
||||||
redistributed freely as long as they are not sold by themselves. The
|
|
||||||
fonts, including any derivative works, can be bundled, embedded,
|
|
||||||
redistributed and/or sold with any software provided that any reserved
|
|
||||||
names are not used by derivative works. The fonts and derivatives,
|
|
||||||
however, cannot be released under any other type of license. The
|
|
||||||
requirement for fonts to remain under this license does not apply
|
|
||||||
to any document created using the fonts or their derivatives.
|
|
||||||
|
|
||||||
DEFINITIONS
|
|
||||||
"Font Software" refers to the set of files released by the Copyright
|
|
||||||
Holder(s) under this license and clearly marked as such. This may
|
|
||||||
include source files, build scripts and documentation.
|
|
||||||
|
|
||||||
"Reserved Font Name" refers to any names specified as such after the
|
|
||||||
copyright statement(s).
|
|
||||||
|
|
||||||
"Original Version" refers to the collection of Font Software components as
|
|
||||||
distributed by the Copyright Holder(s).
|
|
||||||
|
|
||||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
||||||
or substituting -- in part or in whole -- any of the components of the
|
|
||||||
Original Version, by changing formats or by porting the Font Software to a
|
|
||||||
new environment.
|
|
||||||
|
|
||||||
"Author" refers to any designer, engineer, programmer, technical
|
|
||||||
writer or other person who contributed to the Font Software.
|
|
||||||
|
|
||||||
PERMISSION & CONDITIONS
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
||||||
redistribute, and sell modified and unmodified copies of the Font
|
|
||||||
Software, subject to the following conditions:
|
|
||||||
|
|
||||||
1) Neither the Font Software nor any of its individual components,
|
|
||||||
in Original or Modified Versions, may be sold by itself.
|
|
||||||
|
|
||||||
2) Original or Modified Versions of the Font Software may be bundled,
|
|
||||||
redistributed and/or sold with any software, provided that each copy
|
|
||||||
contains the above copyright notice and this license. These can be
|
|
||||||
included either as stand-alone text files, human-readable headers or
|
|
||||||
in the appropriate machine-readable metadata fields within text or
|
|
||||||
binary files as long as those fields can be easily viewed by the user.
|
|
||||||
|
|
||||||
3) No Modified Version of the Font Software may use the Reserved Font
|
|
||||||
Name(s) unless explicit written permission is granted by the corresponding
|
|
||||||
Copyright Holder. This restriction only applies to the primary font name as
|
|
||||||
presented to the users.
|
|
||||||
|
|
||||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
||||||
Software shall not be used to promote, endorse or advertise any
|
|
||||||
Modified Version, except to acknowledge the contribution(s) of the
|
|
||||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
||||||
permission.
|
|
||||||
|
|
||||||
5) The Font Software, modified or unmodified, in part or in whole,
|
|
||||||
must be distributed entirely under this license, and must not be
|
|
||||||
distributed under any other license. The requirement for fonts to
|
|
||||||
remain under this license does not apply to any document created
|
|
||||||
using the Font Software.
|
|
||||||
|
|
||||||
TERMINATION
|
|
||||||
This license becomes null and void if any of the above conditions are
|
|
||||||
not met.
|
|
||||||
|
|
||||||
DISCLAIMER
|
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
||||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
||||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
||||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
||||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
#include "lighting.hpp"
|
||||||
|
|
||||||
|
CSVRender::Lighting::~Lighting() {}
|
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef OPENCS_VIEW_LIGHTING_H
|
||||||
|
#define OPENCS_VIEW_LIGHTING_H
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class SceneManager;
|
||||||
|
class ColourValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class Lighting
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~Lighting();
|
||||||
|
|
||||||
|
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient = 0) = 0;
|
||||||
|
|
||||||
|
virtual void deactivate() = 0;
|
||||||
|
|
||||||
|
virtual void setDefaultAmbient (const Ogre::ColourValue& colour) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
#include "lightingbright.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
|
CSVRender::LightingBright::LightingBright() : mSceneManager (0), mLight (0) {}
|
||||||
|
|
||||||
|
void CSVRender::LightingBright::activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient)
|
||||||
|
{
|
||||||
|
mSceneManager = sceneManager;
|
||||||
|
|
||||||
|
mSceneManager->setAmbientLight (Ogre::ColourValue (1.0, 1.0, 1.0, 1));
|
||||||
|
|
||||||
|
mLight = mSceneManager->createLight();
|
||||||
|
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||||
|
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||||
|
mLight->setDiffuseColour (Ogre::ColourValue (1.0, 1.0, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingBright::deactivate()
|
||||||
|
{
|
||||||
|
if (mLight)
|
||||||
|
{
|
||||||
|
mSceneManager->destroyLight (mLight);
|
||||||
|
mLight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingBright::setDefaultAmbient (const Ogre::ColourValue& colour) {}
|
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef OPENCS_VIEW_LIGHTING_BRIGHT_H
|
||||||
|
#define OPENCS_VIEW_LIGHTING_BRIGHT_H
|
||||||
|
|
||||||
|
#include "lighting.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class LightingBright : public Lighting
|
||||||
|
{
|
||||||
|
Ogre::SceneManager *mSceneManager;
|
||||||
|
Ogre::Light *mLight;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LightingBright();
|
||||||
|
|
||||||
|
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient = 0);
|
||||||
|
|
||||||
|
virtual void deactivate();
|
||||||
|
|
||||||
|
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
#include "lightingday.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
|
CSVRender::LightingDay::LightingDay() : mSceneManager (0), mLight (0) {}
|
||||||
|
|
||||||
|
void CSVRender::LightingDay::activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient)
|
||||||
|
{
|
||||||
|
mSceneManager = sceneManager;
|
||||||
|
|
||||||
|
if (defaultAmbient)
|
||||||
|
mSceneManager->setAmbientLight (*defaultAmbient);
|
||||||
|
else
|
||||||
|
mSceneManager->setAmbientLight (Ogre::ColourValue (0.7, 0.7, 0.7, 1));
|
||||||
|
|
||||||
|
mLight = mSceneManager->createLight();
|
||||||
|
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||||
|
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||||
|
mLight->setDiffuseColour (Ogre::ColourValue (1, 1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingDay::deactivate()
|
||||||
|
{
|
||||||
|
if (mLight)
|
||||||
|
{
|
||||||
|
mSceneManager->destroyLight (mLight);
|
||||||
|
mLight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingDay::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||||
|
{
|
||||||
|
mSceneManager->setAmbientLight (colour);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef OPENCS_VIEW_LIGHTING_DAY_H
|
||||||
|
#define OPENCS_VIEW_LIGHTING_DAY_H
|
||||||
|
|
||||||
|
#include "lighting.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class LightingDay : public Lighting
|
||||||
|
{
|
||||||
|
Ogre::SceneManager *mSceneManager;
|
||||||
|
Ogre::Light *mLight;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LightingDay();
|
||||||
|
|
||||||
|
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient = 0);
|
||||||
|
|
||||||
|
virtual void deactivate();
|
||||||
|
|
||||||
|
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
#include "lightingnight.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
|
||||||
|
CSVRender::LightingNight::LightingNight() : mSceneManager (0), mLight (0) {}
|
||||||
|
|
||||||
|
void CSVRender::LightingNight::activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient)
|
||||||
|
{
|
||||||
|
mSceneManager = sceneManager;
|
||||||
|
|
||||||
|
if (defaultAmbient)
|
||||||
|
mSceneManager->setAmbientLight (*defaultAmbient);
|
||||||
|
else
|
||||||
|
mSceneManager->setAmbientLight (Ogre::ColourValue (0.2, 0.2, 0.2, 1));
|
||||||
|
|
||||||
|
mLight = mSceneManager->createLight();
|
||||||
|
mLight->setType (Ogre::Light::LT_DIRECTIONAL);
|
||||||
|
mLight->setDirection (Ogre::Vector3 (0, 0, -1));
|
||||||
|
mLight->setDiffuseColour (Ogre::ColourValue (0.2, 0.2, 0.2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingNight::deactivate()
|
||||||
|
{
|
||||||
|
if (mLight)
|
||||||
|
{
|
||||||
|
mSceneManager->destroyLight (mLight);
|
||||||
|
mLight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::LightingNight::setDefaultAmbient (const Ogre::ColourValue& colour)
|
||||||
|
{
|
||||||
|
mSceneManager->setAmbientLight (colour);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef OPENCS_VIEW_LIGHTING_NIGHT_H
|
||||||
|
#define OPENCS_VIEW_LIGHTING_NIGHT_H
|
||||||
|
|
||||||
|
#include "lighting.hpp"
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class LightingNight : public Lighting
|
||||||
|
{
|
||||||
|
Ogre::SceneManager *mSceneManager;
|
||||||
|
Ogre::Light *mLight;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
LightingNight();
|
||||||
|
|
||||||
|
virtual void activate (Ogre::SceneManager *sceneManager,
|
||||||
|
const Ogre::ColourValue *defaultAmbient = 0);
|
||||||
|
|
||||||
|
virtual void deactivate();
|
||||||
|
|
||||||
|
virtual void setDefaultAmbient (const Ogre::ColourValue& colour);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#include "navigation.hpp"
|
||||||
|
|
||||||
|
float CSVRender::Navigation::getFactor (bool mouse) const
|
||||||
|
{
|
||||||
|
float factor = mFastModeFactor;
|
||||||
|
|
||||||
|
if (mouse)
|
||||||
|
factor /= 2; /// \todo make this configurable
|
||||||
|
|
||||||
|
return factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::Navigation::~Navigation() {}
|
||||||
|
|
||||||
|
void CSVRender::Navigation::setFastModeFactor (float factor)
|
||||||
|
{
|
||||||
|
mFastModeFactor = factor;
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef OPENCS_VIEW_NAVIGATION_H
|
||||||
|
#define OPENCS_VIEW_NAVIGATION_H
|
||||||
|
|
||||||
|
class QPoint;
|
||||||
|
|
||||||
|
namespace Ogre
|
||||||
|
{
|
||||||
|
class Camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class Navigation
|
||||||
|
{
|
||||||
|
float mFastModeFactor;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
float getFactor (bool mouse) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~Navigation();
|
||||||
|
|
||||||
|
void setFastModeFactor (float factor);
|
||||||
|
///< Set currently applying fast mode factor.
|
||||||
|
|
||||||
|
virtual bool activate (Ogre::Camera *camera) = 0;
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool wheelMoved (int delta) = 0;
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool mouseMoved (const QPoint& delta, int mode) = 0;
|
||||||
|
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||||
|
/// \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleMovementKeys (int vertical, int horizontal) = 0;
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleRollKeys (int delta) = 0;
|
||||||
|
///< \return Update required?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,85 @@
|
|||||||
|
|
||||||
|
#include "navigation1st.hpp"
|
||||||
|
|
||||||
|
#include <OgreCamera.h>
|
||||||
|
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
CSVRender::Navigation1st::Navigation1st() : mCamera (0) {}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::activate (Ogre::Camera *camera)
|
||||||
|
{
|
||||||
|
mCamera = camera;
|
||||||
|
mCamera->setFixedYawAxis (true, Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
|
Ogre::Radian pitch = mCamera->getOrientation().getPitch();
|
||||||
|
|
||||||
|
Ogre::Radian limit (Ogre::Math::PI/2-0.5);
|
||||||
|
|
||||||
|
if (pitch>limit)
|
||||||
|
mCamera->pitch (-(pitch-limit));
|
||||||
|
else if (pitch<-limit)
|
||||||
|
mCamera->pitch (pitch-limit);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::wheelMoved (int delta)
|
||||||
|
{
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDirection() * delta);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::mouseMoved (const QPoint& delta, int mode)
|
||||||
|
{
|
||||||
|
if (mode==0)
|
||||||
|
{
|
||||||
|
// turn camera
|
||||||
|
if (delta.x())
|
||||||
|
mCamera->yaw (Ogre::Degree (getFactor (true) * delta.x()));
|
||||||
|
|
||||||
|
if (delta.y())
|
||||||
|
{
|
||||||
|
Ogre::Radian oldPitch = mCamera->getOrientation().getPitch();
|
||||||
|
float deltaPitch = getFactor (true) * delta.y();
|
||||||
|
Ogre::Radian newPitch = oldPitch + Ogre::Degree (deltaPitch);
|
||||||
|
|
||||||
|
Ogre::Radian limit (Ogre::Math::PI/2-0.5);
|
||||||
|
|
||||||
|
if ((deltaPitch>0 && newPitch<limit) || (deltaPitch<0 && newPitch>-limit))
|
||||||
|
mCamera->pitch (Ogre::Degree (deltaPitch));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (mode==1)
|
||||||
|
{
|
||||||
|
// pan camera
|
||||||
|
if (delta.x())
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * delta.x());
|
||||||
|
|
||||||
|
if (delta.y())
|
||||||
|
mCamera->move (getFactor (true) * -mCamera->getDerivedUp() * delta.y());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::handleMovementKeys (int vertical, int horizontal)
|
||||||
|
{
|
||||||
|
if (vertical)
|
||||||
|
mCamera->move (getFactor (false) * mCamera->getDirection() * vertical);
|
||||||
|
|
||||||
|
if (horizontal)
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * horizontal);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::Navigation1st::handleRollKeys (int delta)
|
||||||
|
{
|
||||||
|
// we don't roll this way in 1st person mode
|
||||||
|
return false;
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef OPENCS_VIEW_NAVIGATION1ST_H
|
||||||
|
#define OPENCS_VIEW_NAVIGATION1ST_H
|
||||||
|
|
||||||
|
#include "navigation.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
/// \brief First person-like camera controls
|
||||||
|
class Navigation1st : public Navigation
|
||||||
|
{
|
||||||
|
Ogre::Camera *mCamera;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Navigation1st();
|
||||||
|
|
||||||
|
virtual bool activate (Ogre::Camera *camera);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool wheelMoved (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||||
|
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||||
|
/// \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleRollKeys (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
#include "navigationfree.hpp"
|
||||||
|
|
||||||
|
#include <OgreCamera.h>
|
||||||
|
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
CSVRender::NavigationFree::NavigationFree() : mCamera (0) {}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::activate (Ogre::Camera *camera)
|
||||||
|
{
|
||||||
|
mCamera = camera;
|
||||||
|
mCamera->setFixedYawAxis (false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::wheelMoved (int delta)
|
||||||
|
{
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDirection() * delta);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::mouseMoved (const QPoint& delta, int mode)
|
||||||
|
{
|
||||||
|
if (mode==0)
|
||||||
|
{
|
||||||
|
// turn camera
|
||||||
|
if (delta.x())
|
||||||
|
mCamera->yaw (Ogre::Degree (getFactor (true) * delta.x()));
|
||||||
|
|
||||||
|
if (delta.y())
|
||||||
|
mCamera->pitch (Ogre::Degree (getFactor (true) * delta.y()));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (mode==1)
|
||||||
|
{
|
||||||
|
// pan camera
|
||||||
|
if (delta.x())
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * delta.x());
|
||||||
|
|
||||||
|
if (delta.y())
|
||||||
|
mCamera->move (getFactor (true) * -mCamera->getDerivedUp() * delta.y());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::handleMovementKeys (int vertical, int horizontal)
|
||||||
|
{
|
||||||
|
if (vertical)
|
||||||
|
mCamera->move (getFactor (false) * mCamera->getDerivedUp() * vertical);
|
||||||
|
|
||||||
|
if (horizontal)
|
||||||
|
mCamera->move (getFactor (true) * mCamera->getDerivedRight() * horizontal);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationFree::handleRollKeys (int delta)
|
||||||
|
{
|
||||||
|
mCamera->roll (Ogre::Degree (getFactor (false) * delta));
|
||||||
|
return true;
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef OPENCS_VIEW_NAVIGATIONFREE_H
|
||||||
|
#define OPENCS_VIEW_NAVIGATIONFREE_H
|
||||||
|
|
||||||
|
#include "navigation.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
/// \brief Free camera controls
|
||||||
|
class NavigationFree : public Navigation
|
||||||
|
{
|
||||||
|
Ogre::Camera *mCamera;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NavigationFree();
|
||||||
|
|
||||||
|
virtual bool activate (Ogre::Camera *camera);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool wheelMoved (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||||
|
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||||
|
/// \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleRollKeys (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,100 @@
|
|||||||
|
|
||||||
|
#include "navigationorbit.hpp"
|
||||||
|
|
||||||
|
#include <OgreCamera.h>
|
||||||
|
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
void CSVRender::NavigationOrbit::rotateCamera (const Ogre::Vector3& diff)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 pos = mCamera->getPosition();
|
||||||
|
|
||||||
|
float distance = (pos-mCentre).length();
|
||||||
|
|
||||||
|
Ogre::Vector3 direction = (pos+diff)-mCentre;
|
||||||
|
direction.normalise();
|
||||||
|
|
||||||
|
mCamera->setPosition (mCentre + direction*distance);
|
||||||
|
mCamera->lookAt (mCentre);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::NavigationOrbit::NavigationOrbit() : mCamera (0), mCentre (0, 0, 0), mDistance (100)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::activate (Ogre::Camera *camera)
|
||||||
|
{
|
||||||
|
mCamera = camera;
|
||||||
|
mCamera->setFixedYawAxis (false);
|
||||||
|
|
||||||
|
if ((mCamera->getPosition()-mCentre).length()<mDistance)
|
||||||
|
{
|
||||||
|
// move camera out of the centre area
|
||||||
|
Ogre::Vector3 direction = mCentre-mCamera->getPosition();
|
||||||
|
direction.normalise();
|
||||||
|
|
||||||
|
if (direction.length()==0)
|
||||||
|
direction = Ogre::Vector3 (1, 0, 0);
|
||||||
|
|
||||||
|
mCamera->setPosition (mCentre - direction * mDistance);
|
||||||
|
}
|
||||||
|
|
||||||
|
mCamera->lookAt (mCentre);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::wheelMoved (int delta)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 diff = getFactor (true) * mCamera->getDirection() * delta;
|
||||||
|
|
||||||
|
Ogre::Vector3 pos = mCamera->getPosition();
|
||||||
|
|
||||||
|
if (delta>0 && diff.length()>=(pos-mCentre).length()-mDistance)
|
||||||
|
{
|
||||||
|
pos = mCentre-(mCamera->getDirection() * mDistance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos += diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCamera->setPosition (pos);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::mouseMoved (const QPoint& delta, int mode)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 diff =
|
||||||
|
getFactor (true) * -mCamera->getDerivedRight() * delta.x()
|
||||||
|
+ getFactor (true) * mCamera->getDerivedUp() * delta.y();
|
||||||
|
|
||||||
|
if (mode==0)
|
||||||
|
{
|
||||||
|
rotateCamera (diff);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (mode==1)
|
||||||
|
{
|
||||||
|
mCamera->move (diff);
|
||||||
|
mCentre += diff;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::handleMovementKeys (int vertical, int horizontal)
|
||||||
|
{
|
||||||
|
rotateCamera (
|
||||||
|
- getFactor (false) * -mCamera->getDerivedRight() * horizontal
|
||||||
|
+ getFactor (false) * mCamera->getDerivedUp() * vertical);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVRender::NavigationOrbit::handleRollKeys (int delta)
|
||||||
|
{
|
||||||
|
mCamera->roll (Ogre::Degree (getFactor (false) * delta));
|
||||||
|
return true;
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef OPENCS_VIEW_NAVIGATIONORBIT_H
|
||||||
|
#define OPENCS_VIEW_NAVIGATIONORBIT_H
|
||||||
|
|
||||||
|
#include "navigation.hpp"
|
||||||
|
|
||||||
|
#include <OgreVector3.h>
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
/// \brief Orbiting camera controls
|
||||||
|
class NavigationOrbit : public Navigation
|
||||||
|
{
|
||||||
|
Ogre::Camera *mCamera;
|
||||||
|
Ogre::Vector3 mCentre;
|
||||||
|
int mDistance;
|
||||||
|
|
||||||
|
void rotateCamera (const Ogre::Vector3& diff);
|
||||||
|
///< Rotate camera around centre.
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
NavigationOrbit();
|
||||||
|
|
||||||
|
virtual bool activate (Ogre::Camera *camera);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool wheelMoved (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool mouseMoved (const QPoint& delta, int mode);
|
||||||
|
///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1
|
||||||
|
/// \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleMovementKeys (int vertical, int horizontal);
|
||||||
|
///< \return Update required?
|
||||||
|
|
||||||
|
virtual bool handleRollKeys (int delta);
|
||||||
|
///< \return Update required?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
#include "pagedworldspacewidget.hpp"
|
||||||
|
|
||||||
|
CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget *parent)
|
||||||
|
: WorldspaceWidget (parent)
|
||||||
|
{}
|
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||||
|
#define OPENCS_VIEW_PAGEDWORLDSPACEWIDGET_H
|
||||||
|
|
||||||
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class PagedWorldspaceWidget : public WorldspaceWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PagedWorldspaceWidget (QWidget *parent);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,201 @@
|
|||||||
|
|
||||||
|
#include "previewwidget.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::setup()
|
||||||
|
{
|
||||||
|
setNavigation (&mOrbit);
|
||||||
|
|
||||||
|
mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode();
|
||||||
|
mNode->setPosition (Ogre::Vector3 (0, 0, 0));
|
||||||
|
|
||||||
|
setModel();
|
||||||
|
|
||||||
|
QAbstractItemModel *referenceables =
|
||||||
|
mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables);
|
||||||
|
|
||||||
|
connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (ReferenceableDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (ReferenceableAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::setModel()
|
||||||
|
{
|
||||||
|
if (mNode)
|
||||||
|
{
|
||||||
|
mObject.setNull();
|
||||||
|
|
||||||
|
if (mReferenceableId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int column =
|
||||||
|
mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model);
|
||||||
|
|
||||||
|
int row = mData.getReferenceables().searchId (mReferenceableId);
|
||||||
|
|
||||||
|
if (row==-1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QVariant value = mData.getReferenceables().getData (row, column);
|
||||||
|
|
||||||
|
if (!value.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string model = value.toString().toUtf8().constData();
|
||||||
|
|
||||||
|
if (model.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::adjust()
|
||||||
|
{
|
||||||
|
if (mNode)
|
||||||
|
{
|
||||||
|
int row = mData.getReferences().getIndex (mReferenceId);
|
||||||
|
|
||||||
|
float scale = mData.getReferences().getData (row, mData.getReferences().
|
||||||
|
findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat();
|
||||||
|
float rotX = mData.getReferences().getData (row, mData.getReferences().
|
||||||
|
findColumnIndex (CSMWorld::Columns::ColumnId_PositionXRot)).toFloat();
|
||||||
|
float rotY = mData.getReferences().getData (row, mData.getReferences().
|
||||||
|
findColumnIndex (CSMWorld::Columns::ColumnId_PositionYRot)).toFloat();
|
||||||
|
float rotZ = mData.getReferences().getData (row, mData.getReferences().
|
||||||
|
findColumnIndex (CSMWorld::Columns::ColumnId_PositionZRot)).toFloat();
|
||||||
|
|
||||||
|
mNode->setScale (scale, scale, scale);
|
||||||
|
|
||||||
|
Ogre::Quaternion xr (Ogre::Radian(-rotX), Ogre::Vector3::UNIT_X);
|
||||||
|
|
||||||
|
Ogre::Quaternion yr (Ogre::Radian(-rotY), Ogre::Vector3::UNIT_Y);
|
||||||
|
|
||||||
|
Ogre::Quaternion zr (Ogre::Radian(-rotZ), Ogre::Vector3::UNIT_Z);
|
||||||
|
|
||||||
|
mNode->setOrientation (xr*yr*zr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
||||||
|
const std::string& referenceableId, QWidget *parent)
|
||||||
|
: SceneWidget (parent), mData (data), mNode (0), mReferenceableId (referenceableId)
|
||||||
|
{
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data,
|
||||||
|
const std::string& referenceableId, const std::string& referenceId, QWidget *parent)
|
||||||
|
: SceneWidget (parent), mData (data), mReferenceableId (referenceableId),
|
||||||
|
mReferenceId (referenceId)
|
||||||
|
{
|
||||||
|
setup();
|
||||||
|
|
||||||
|
adjust();
|
||||||
|
|
||||||
|
QAbstractItemModel *references =
|
||||||
|
mData.getTableModel (CSMWorld::UniversalId::Type_References);
|
||||||
|
|
||||||
|
connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (ReferenceDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (ReferenceAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
if (mReferenceableId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||||
|
|
||||||
|
QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0);
|
||||||
|
|
||||||
|
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
|
||||||
|
{
|
||||||
|
/// \todo possible optimisation; check columns and only update if relevant columns have
|
||||||
|
/// changed
|
||||||
|
setModel();
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||||
|
int end)
|
||||||
|
{
|
||||||
|
if (mReferenceableId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CSMWorld::IdTable& referenceables = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables));
|
||||||
|
|
||||||
|
QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0);
|
||||||
|
|
||||||
|
if (index.row()>=start && index.row()<=end)
|
||||||
|
{
|
||||||
|
if (mReferenceId.empty())
|
||||||
|
{
|
||||||
|
// this is a preview for a referenceble
|
||||||
|
emit closeRequest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this is a preview for a reference
|
||||||
|
mObject.setNull();
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
if (mReferenceId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
|
int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId);
|
||||||
|
|
||||||
|
QModelIndex index = references.getModelIndex (mReferenceId, columnIndex);
|
||||||
|
|
||||||
|
if (index.row()>=topLeft.row() && index.row()<=bottomRight.row())
|
||||||
|
{
|
||||||
|
/// \todo possible optimisation; check columns and only update if relevant columns have
|
||||||
|
/// changed
|
||||||
|
adjust();
|
||||||
|
|
||||||
|
if (index.column()>=topLeft.column() && index.column()<=bottomRight.row())
|
||||||
|
{
|
||||||
|
mReferenceableId = references.data (index).toString().toUtf8().constData();
|
||||||
|
emit referenceableIdChanged (mReferenceableId);
|
||||||
|
setModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
flagAsModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start,
|
||||||
|
int end)
|
||||||
|
{
|
||||||
|
if (mReferenceId.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CSMWorld::IdTable& references = dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*mData.getTableModel (CSMWorld::UniversalId::Type_References));
|
||||||
|
|
||||||
|
QModelIndex index = references.getModelIndex (mReferenceId, 0);
|
||||||
|
|
||||||
|
if (index.row()>=start && index.row()<=end)
|
||||||
|
emit closeRequest();
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef OPENCS_VIEW_PREVIEWWIDGET_H
|
||||||
|
#define OPENCS_VIEW_PREVIEWWIDGET_H
|
||||||
|
|
||||||
|
#include <components/nifogre/ogrenifloader.hpp>
|
||||||
|
|
||||||
|
#include "scenewidget.hpp"
|
||||||
|
|
||||||
|
#include "navigationorbit.hpp"
|
||||||
|
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class PreviewWidget : public SceneWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSMWorld::Data& mData;
|
||||||
|
CSVRender::NavigationOrbit mOrbit;
|
||||||
|
NifOgre::ObjectScenePtr mObject;
|
||||||
|
Ogre::SceneNode *mNode;
|
||||||
|
std::string mReferenceId;
|
||||||
|
std::string mReferenceableId;
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
|
||||||
|
void setModel();
|
||||||
|
|
||||||
|
void adjust();
|
||||||
|
///< Adjust referenceable preview according to the reference
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
|
||||||
|
QWidget *parent = 0);
|
||||||
|
|
||||||
|
PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId,
|
||||||
|
const std::string& referenceId, QWidget *parent = 0);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void closeRequest();
|
||||||
|
|
||||||
|
void referenceableIdChanged (const std::string& id);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void ReferenceableDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
|
||||||
|
void ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
#include "unpagedworldspacewidget.hpp"
|
||||||
|
|
||||||
|
#include <OgreColourValue.h>
|
||||||
|
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
|
||||||
|
#include "../../model/world/data.hpp"
|
||||||
|
#include "../../model/world/idtable.hpp"
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::update()
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::Cell>& record =
|
||||||
|
dynamic_cast<const CSMWorld::Record<CSMWorld::Cell>&> (mCellsModel->getRecord (mCellId));
|
||||||
|
|
||||||
|
Ogre::ColourValue colour;
|
||||||
|
colour.setAsABGR (record.get().mAmbi.mAmbient);
|
||||||
|
setDefaultAmbient (colour);
|
||||||
|
|
||||||
|
/// \todo deal with mSunlight and mFog/mForDensity
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId,
|
||||||
|
CSMDoc::Document& document, QWidget *parent)
|
||||||
|
: WorldspaceWidget (parent), mCellId (cellId)
|
||||||
|
{
|
||||||
|
mCellsModel = &dynamic_cast<CSMWorld::IdTable&> (
|
||||||
|
*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells));
|
||||||
|
|
||||||
|
connect (mCellsModel, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)),
|
||||||
|
this, SLOT (cellDataChanged (const QModelIndex&, const QModelIndex&)));
|
||||||
|
connect (mCellsModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
|
||||||
|
this, SLOT (cellRowsAboutToBeRemoved (const QModelIndex&, int, int)));
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft,
|
||||||
|
const QModelIndex& bottomRight)
|
||||||
|
{
|
||||||
|
int index = mCellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification);
|
||||||
|
QModelIndex cellIndex = mCellsModel->getModelIndex (mCellId, index);
|
||||||
|
|
||||||
|
if (cellIndex.row()>=topLeft.row() && cellIndex.row()<=bottomRight.row())
|
||||||
|
{
|
||||||
|
if (mCellsModel->data (cellIndex).toInt()==CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
emit closeRequest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/// \todo possible optimisation: check columns and update only if relevant columns have
|
||||||
|
/// changed
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelIndex& parent,
|
||||||
|
int start, int end)
|
||||||
|
{
|
||||||
|
QModelIndex cellIndex = mCellsModel->getModelIndex (mCellId, 0);
|
||||||
|
|
||||||
|
if (cellIndex.row()>=start && cellIndex.row()<=end)
|
||||||
|
emit closeRequest();
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H
|
||||||
|
#define OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class IdTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class UnpagedWorldspaceWidget : public WorldspaceWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
std::string mCellId;
|
||||||
|
CSMWorld::IdTable *mCellsModel;
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document,
|
||||||
|
QWidget *parent);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight);
|
||||||
|
|
||||||
|
void cellRowsAboutToBeRemoved (const QModelIndex& parent, int start, int end);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
#include "worldspacewidget.hpp"
|
||||||
|
|
||||||
|
#include <OgreSceneNode.h>
|
||||||
|
#include <OgreSceneManager.h>
|
||||||
|
#include <OgreEntity.h>
|
||||||
|
|
||||||
|
#include "../world/scenetoolmode.hpp"
|
||||||
|
|
||||||
|
CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent)
|
||||||
|
: SceneWidget (parent)
|
||||||
|
{
|
||||||
|
Ogre::Entity* ent = getSceneManager()->createEntity("cube", Ogre::SceneManager::PT_CUBE);
|
||||||
|
ent->setMaterialName("BaseWhite");
|
||||||
|
|
||||||
|
getSceneManager()->getRootSceneNode()->attachObject(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
|
||||||
|
{
|
||||||
|
if (mode=="1st")
|
||||||
|
setNavigation (&m1st);
|
||||||
|
else if (mode=="free")
|
||||||
|
setNavigation (&mFree);
|
||||||
|
else if (mode=="orbit")
|
||||||
|
setNavigation (&mOrbit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVRender::WorldspaceWidget::selectDefaultNavigationMode()
|
||||||
|
{
|
||||||
|
setNavigation (&m1st);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector (
|
||||||
|
CSVWorld::SceneToolbar *parent)
|
||||||
|
{
|
||||||
|
CSVWorld::SceneToolMode *tool = new CSVWorld::SceneToolMode (parent);
|
||||||
|
|
||||||
|
tool->addButton (":door.png", "1st"); /// \todo replace icons
|
||||||
|
tool->addButton (":GMST.png", "free");
|
||||||
|
tool->addButton (":Info.png", "orbit");
|
||||||
|
|
||||||
|
connect (tool, SIGNAL (modeChanged (const std::string&)),
|
||||||
|
this, SLOT (selectNavigationMode (const std::string&)));
|
||||||
|
|
||||||
|
return tool;
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||||
|
#define OPENCS_VIEW_WORLDSPACEWIDGET_H
|
||||||
|
|
||||||
|
#include "scenewidget.hpp"
|
||||||
|
|
||||||
|
#include "navigation1st.hpp"
|
||||||
|
#include "navigationfree.hpp"
|
||||||
|
#include "navigationorbit.hpp"
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class SceneToolMode;
|
||||||
|
class SceneToolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class WorldspaceWidget : public SceneWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSVRender::Navigation1st m1st;
|
||||||
|
CSVRender::NavigationFree mFree;
|
||||||
|
CSVRender::NavigationOrbit mOrbit;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
WorldspaceWidget (QWidget *parent = 0);
|
||||||
|
|
||||||
|
CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent);
|
||||||
|
///< \attention The created tool is not added to the toolbar (via addTool). Doing that
|
||||||
|
/// is the responsibility of the calling function.
|
||||||
|
|
||||||
|
void selectDefaultNavigationMode();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void selectNavigationMode (const std::string& mode);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void closeRequest();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,98 +1,689 @@
|
|||||||
|
|
||||||
#include "dialoguesubview.hpp"
|
#include "dialoguesubview.hpp"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QSize>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QDoubleSpinBox>
|
#include <QDoubleSpinBox>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
#include <QEvent>
|
||||||
#include <QDataWidgetMapper>
|
#include <QDataWidgetMapper>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
#include "../../model/world/columnbase.hpp"
|
#include "../../model/world/columnbase.hpp"
|
||||||
#include "../../model/world/idtable.hpp"
|
#include "../../model/world/idtable.hpp"
|
||||||
|
#include "../../model/world/columns.hpp"
|
||||||
|
#include "../../model/world/record.hpp"
|
||||||
|
#include "../../model/world/tablemimedata.hpp"
|
||||||
|
#include "../../model/doc/document.hpp"
|
||||||
|
#include "../../model/world/commands.hpp"
|
||||||
|
|
||||||
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
#include "recordstatusdelegate.hpp"
|
||||||
bool createAndDelete)
|
#include "util.hpp"
|
||||||
: SubView (id)
|
#include "tablebottombox.hpp"
|
||||||
|
/*
|
||||||
|
==============================NotEditableSubDelegate==========================================
|
||||||
|
*/
|
||||||
|
CSVWorld::NotEditableSubDelegate::NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent) :
|
||||||
|
QAbstractItemDelegate(parent),
|
||||||
|
mTable(table)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CSVWorld::NotEditableSubDelegate::setEditorData (QLabel* editor, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
QVariant v = index.data(Qt::EditRole);
|
||||||
|
if (!v.isValid())
|
||||||
|
{
|
||||||
|
v = index.data(Qt::DisplayRole);
|
||||||
|
if (!v.isValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QVariant::String == v.type())
|
||||||
|
{
|
||||||
|
editor->setText(v.toString());
|
||||||
|
} else //else we are facing enums
|
||||||
|
{
|
||||||
|
int data = v.toInt();
|
||||||
|
std::vector<std::string> enumNames (CSMWorld::Columns::getEnums (static_cast<CSMWorld::Columns::ColumnId> (mTable->getColumnId (index.column()))));
|
||||||
|
editor->setText(QString::fromUtf8(enumNames.at(data).c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::NotEditableSubDelegate::setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||||
|
{
|
||||||
|
//not editable widgets will not save model data
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::NotEditableSubDelegate::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
//does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize CSVWorld::NotEditableSubDelegate::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
return QSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* CSVWorld::NotEditableSubDelegate::createEditor (QWidget *parent,
|
||||||
|
const QStyleOptionViewItem& option,
|
||||||
|
const QModelIndex& index,
|
||||||
|
CSMWorld::ColumnBase::Display display) const
|
||||||
|
{
|
||||||
|
return new QLabel(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==============================DialogueDelegateDispatcherProxy==========================================
|
||||||
|
*/
|
||||||
|
CSVWorld::DialogueDelegateDispatcherProxy::refWrapper::refWrapper(const QModelIndex& index) :
|
||||||
|
mIndex(index)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSVWorld::DialogueDelegateDispatcherProxy::DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display) :
|
||||||
|
mEditor(editor),
|
||||||
|
mDisplay(display),
|
||||||
|
mIndexWrapper(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcherProxy::editorDataCommited()
|
||||||
|
{
|
||||||
|
if (mIndexWrapper.get())
|
||||||
|
{
|
||||||
|
emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcherProxy::setIndex(const QModelIndex& index)
|
||||||
|
{
|
||||||
|
mIndexWrapper.reset(new refWrapper(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const
|
||||||
|
{
|
||||||
|
return mEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>& data, const CSMDoc::Document* document)
|
||||||
|
{
|
||||||
|
QLineEdit* lineEdit = qobject_cast<QLineEdit*>(mEditor);
|
||||||
|
{
|
||||||
|
if (!lineEdit || !mIndexWrapper.get())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < data.size(); ++i)
|
||||||
|
{
|
||||||
|
CSMWorld::UniversalId::Type type = data[i].getType();
|
||||||
|
if (mDisplay == CSMWorld::ColumnBase::Display_Referenceable)
|
||||||
|
{
|
||||||
|
if ( type == CSMWorld::UniversalId::Type_Activator
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Potion
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Apparatus
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Armor
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Book
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Clothing
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Container
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Creature
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Door
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Ingredient
|
||||||
|
|| type == CSMWorld::UniversalId::Type_CreatureLevelledList
|
||||||
|
|| type == CSMWorld::UniversalId::Type_ItemLevelledList
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Light
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Lockpick
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Miscellaneous
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Npc
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Probe
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Repair
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Static
|
||||||
|
|| type == CSMWorld::UniversalId::Type_Weapon)
|
||||||
|
{
|
||||||
|
type = CSMWorld::UniversalId::Type_Referenceable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mDisplay == CSMWorld::TableMimeData::convertEnums(type))
|
||||||
|
{
|
||||||
|
emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document);
|
||||||
|
emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
==============================DialogueDelegateDispatcher==========================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack) :
|
||||||
|
mParent(parent),
|
||||||
|
mTable(table),
|
||||||
|
mUndoStack(undoStack),
|
||||||
|
mNotEditableDelegate(table, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CSMWorld::ColumnBase::Display display)
|
||||||
{
|
{
|
||||||
QWidget *widget = new QWidget (this);
|
CommandDelegate *delegate = NULL;
|
||||||
|
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||||
|
if (delegateIt == mDelegates.end())
|
||||||
|
{
|
||||||
|
delegate = CommandDelegateFactoryCollection::get().makeDelegate (
|
||||||
|
display, mUndoStack, mParent);
|
||||||
|
mDelegates.insert(std::make_pair<int, CommandDelegate*>(display, delegate));
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
delegate = delegateIt->second;
|
||||||
|
}
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
setWidget (widget);
|
void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display)
|
||||||
|
{
|
||||||
|
setModelData(editor, mTable, index, display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||||
|
(mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||||
|
|
||||||
QGridLayout *layout = new QGridLayout;
|
QLabel* label = qobject_cast<QLabel*>(editor);
|
||||||
|
if(label)
|
||||||
|
{
|
||||||
|
mNotEditableDelegate.setEditorData(label, index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
widget->setLayout (layout);
|
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||||
|
if (delegateIt != mDelegates.end())
|
||||||
|
{
|
||||||
|
delegateIt->second->setEditorData(editor, index, true);
|
||||||
|
}
|
||||||
|
|
||||||
QAbstractItemModel *model = document.getData().getTableModel (id);
|
for (unsigned i = 0; i < mProxys.size(); ++i)
|
||||||
|
{
|
||||||
|
if (mProxys[i]->getEditor() == editor)
|
||||||
|
{
|
||||||
|
mProxys[i]->setIndex(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const
|
||||||
|
{
|
||||||
|
std::map<int, CommandDelegate*>::const_iterator delegateIt(mDelegates.find(display));
|
||||||
|
if (delegateIt != mDelegates.end())
|
||||||
|
{
|
||||||
|
delegateIt->second->setModelData(editor, model, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
//Does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
return QSize(); //silencing warning, otherwise does nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index)
|
||||||
|
{
|
||||||
|
QVariant variant = index.data();
|
||||||
|
if (!variant.isValid())
|
||||||
|
{
|
||||||
|
variant = index.data(Qt::DisplayRole);
|
||||||
|
if (!variant.isValid())
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* editor = NULL;
|
||||||
|
if (! (mTable->flags (index) & Qt::ItemIsEditable))
|
||||||
|
{
|
||||||
|
return mNotEditableDelegate.createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index, display);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<int, CommandDelegate*>::iterator delegateIt(mDelegates.find(display));
|
||||||
|
if (delegateIt != mDelegates.end())
|
||||||
|
{
|
||||||
|
editor = delegateIt->second->createEditor(qobject_cast<QWidget*>(mParent), QStyleOptionViewItem(), index, display);
|
||||||
|
DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display);
|
||||||
|
|
||||||
|
bool skip = false;
|
||||||
|
if (qobject_cast<DropLineEdit*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
|
||||||
|
connect(editor, SIGNAL(tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>&, const CSMDoc::Document*)),
|
||||||
|
proxy, SLOT(tableMimeDataDropped(const std::vector<CSMWorld::UniversalId>&, const CSMDoc::Document*)));
|
||||||
|
connect(proxy, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)),
|
||||||
|
this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
if(!skip && qobject_cast<QCheckBox*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(stateChanged(int)), proxy, SLOT(editorDataCommited()));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
if(!skip && qobject_cast<QPlainTextEdit*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(textChanged()), proxy, SLOT(editorDataCommited()));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
if(!skip && qobject_cast<QComboBox*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited()));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
if(!skip && qobject_cast<QAbstractSpinBox*>(editor))
|
||||||
|
{
|
||||||
|
connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited()));
|
||||||
|
skip = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)));
|
||||||
|
mProxys.push_back(proxy); //deleted in the destructor
|
||||||
|
}
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher()
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < mProxys.size(); ++i)
|
||||||
|
{
|
||||||
|
delete mProxys[i]; //unique_ptr could be handy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=============================================================EditWidget=====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete) :
|
||||||
|
mDispatcher(this, table, undoStack),
|
||||||
|
QScrollArea(parent),
|
||||||
|
mWidgetMapper(NULL),
|
||||||
|
mMainWidget(NULL),
|
||||||
|
mUndoStack(undoStack),
|
||||||
|
mTable(table)
|
||||||
|
{
|
||||||
|
remake (row);
|
||||||
|
connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
|
||||||
|
}
|
||||||
|
|
||||||
int columns = model->columnCount();
|
void CSVWorld::EditWidget::remake(int row)
|
||||||
|
{
|
||||||
|
if (mMainWidget)
|
||||||
|
{
|
||||||
|
delete mMainWidget;
|
||||||
|
}
|
||||||
|
mMainWidget = new QWidget (this);
|
||||||
|
|
||||||
|
//not sure if widget mapper can handle deleting the widgets that were mapped
|
||||||
|
if (mWidgetMapper)
|
||||||
|
{
|
||||||
|
delete mWidgetMapper;
|
||||||
|
}
|
||||||
mWidgetMapper = new QDataWidgetMapper (this);
|
mWidgetMapper = new QDataWidgetMapper (this);
|
||||||
mWidgetMapper->setModel (model);
|
mWidgetMapper->setModel(mTable);
|
||||||
|
mWidgetMapper->setItemDelegate(&mDispatcher);
|
||||||
|
|
||||||
|
QFrame* line = new QFrame(mMainWidget);
|
||||||
|
line->setObjectName(QString::fromUtf8("line"));
|
||||||
|
line->setGeometry(QRect(320, 150, 118, 3));
|
||||||
|
line->setFrameShape(QFrame::HLine);
|
||||||
|
line->setFrameShadow(QFrame::Sunken);
|
||||||
|
|
||||||
|
QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget);
|
||||||
|
QGridLayout *unlockedLayout = new QGridLayout();
|
||||||
|
QGridLayout *lockedLayout = new QGridLayout();
|
||||||
|
mainLayout->addLayout(lockedLayout, 0);
|
||||||
|
mainLayout->addWidget(line, 1);
|
||||||
|
mainLayout->addLayout(unlockedLayout, 2);
|
||||||
|
mainLayout->addStretch(1);
|
||||||
|
|
||||||
|
int unlocked = 0;
|
||||||
|
int locked = 0;
|
||||||
|
const int columns = mTable->columnCount();
|
||||||
for (int i=0; i<columns; ++i)
|
for (int i=0; i<columns; ++i)
|
||||||
{
|
{
|
||||||
int flags = model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
|
int flags = mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt();
|
||||||
|
|
||||||
if (flags & CSMWorld::ColumnBase::Flag_Dialogue)
|
if (flags & CSMWorld::ColumnBase::Flag_Dialogue)
|
||||||
{
|
{
|
||||||
layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i, 0);
|
|
||||||
|
|
||||||
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
CSMWorld::ColumnBase::Display display = static_cast<CSMWorld::ColumnBase::Display>
|
||||||
(model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
(mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt());
|
||||||
|
|
||||||
QWidget *widget = 0;
|
mDispatcher.makeDelegate(display);
|
||||||
|
QWidget *editor = mDispatcher.makeEditor(display, (mTable->index (row, i)));
|
||||||
|
|
||||||
if (model->flags (model->index (0, i)) & Qt::ItemIsEditable)
|
if (editor)
|
||||||
{
|
{
|
||||||
switch (display)
|
mWidgetMapper->addMapping (editor, i);
|
||||||
|
QLabel* label = new QLabel(mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget);
|
||||||
|
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||||
|
if (! (mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable))
|
||||||
|
{
|
||||||
|
lockedLayout->addWidget (label, locked, 0);
|
||||||
|
lockedLayout->addWidget (editor, locked, 1);
|
||||||
|
++locked;
|
||||||
|
} else
|
||||||
{
|
{
|
||||||
case CSMWorld::ColumnBase::Display_String:
|
unlockedLayout->addWidget (label, unlocked, 0);
|
||||||
|
unlockedLayout->addWidget (editor, unlocked, 1);
|
||||||
|
++unlocked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
layout->addWidget (widget = new QLineEdit, i, 1);
|
mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0));
|
||||||
break;
|
|
||||||
|
|
||||||
case CSMWorld::ColumnBase::Display_Integer:
|
this->setMinimumWidth(325); //TODO find better way to set the width or make it customizable
|
||||||
|
this->setWidget(mMainWidget);
|
||||||
|
this->setWidgetResizable(true);
|
||||||
|
}
|
||||||
|
|
||||||
/// \todo configure widget properly (range)
|
/*
|
||||||
layout->addWidget (widget = new QSpinBox, i, 1);
|
==============================DialogueSubView==========================================
|
||||||
break;
|
*/
|
||||||
|
|
||||||
case CSMWorld::ColumnBase::Display_Float:
|
CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document,
|
||||||
|
const CreatorFactoryBase& creatorFactory, bool sorting) :
|
||||||
|
|
||||||
/// \todo configure widget properly (range, format?)
|
SubView (id),
|
||||||
layout->addWidget (widget = new QDoubleSpinBox, i, 1);
|
mEditWidget(0),
|
||||||
break;
|
mMainLayout(NULL),
|
||||||
|
mUndoStack(document.getUndoStack()),
|
||||||
|
mTable(dynamic_cast<CSMWorld::IdTable*>(document.getData().getTableModel(id))),
|
||||||
|
mRow (-1),
|
||||||
|
mLocked(false),
|
||||||
|
mDocument(document)
|
||||||
|
|
||||||
default: break; // silence warnings for other times for now
|
{
|
||||||
}
|
connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&)));
|
||||||
|
mRow = mTable->getModelIndex (id.getId(), 0).row();
|
||||||
|
QWidget *mainWidget = new QWidget(this);
|
||||||
|
|
||||||
|
QHBoxLayout *buttonsLayout = new QHBoxLayout;
|
||||||
|
QToolButton* prevButton = new QToolButton(mainWidget);
|
||||||
|
prevButton->setIcon(QIcon(":/go-previous.png"));
|
||||||
|
QToolButton* nextButton = new QToolButton(mainWidget);
|
||||||
|
nextButton->setIcon(QIcon(":/go-next.png"));
|
||||||
|
buttonsLayout->addWidget(prevButton, 0);
|
||||||
|
buttonsLayout->addWidget(nextButton, 1);
|
||||||
|
buttonsLayout->addStretch(2);
|
||||||
|
|
||||||
|
QToolButton* cloneButton = new QToolButton(mainWidget);
|
||||||
|
cloneButton->setIcon(QIcon(":/edit-clone.png"));
|
||||||
|
QToolButton* addButton = new QToolButton(mainWidget);
|
||||||
|
addButton->setIcon(QIcon(":/add.png"));
|
||||||
|
QToolButton* deleteButton = new QToolButton(mainWidget);
|
||||||
|
deleteButton->setIcon(QIcon(":/edit-delete.png"));
|
||||||
|
QToolButton* revertButton = new QToolButton(mainWidget);
|
||||||
|
revertButton->setIcon(QIcon(":/edit-undo.png"));
|
||||||
|
|
||||||
|
if (mTable->hasPreview())
|
||||||
|
{
|
||||||
|
QToolButton* previewButton = new QToolButton(mainWidget);
|
||||||
|
previewButton->setIcon(QIcon(":/edit-preview.png"));
|
||||||
|
buttonsLayout->addWidget(previewButton);
|
||||||
|
connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTable->getViewing()!=CSMWorld::IdTable::Viewing_None)
|
||||||
|
{
|
||||||
|
QToolButton* viewButton = new QToolButton(mainWidget);
|
||||||
|
viewButton->setIcon(QIcon(":/cell.png"));
|
||||||
|
buttonsLayout->addWidget(viewButton);
|
||||||
|
connect(viewButton, SIGNAL(clicked()), this, SLOT(viewRecord()));
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonsLayout->addWidget(cloneButton);
|
||||||
|
buttonsLayout->addWidget(addButton);
|
||||||
|
buttonsLayout->addWidget(deleteButton);
|
||||||
|
buttonsLayout->addWidget(revertButton);
|
||||||
|
|
||||||
|
connect(nextButton, SIGNAL(clicked()), this, SLOT(nextId()));
|
||||||
|
connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId()));
|
||||||
|
connect(cloneButton, SIGNAL(clicked()), this, SLOT(cloneRequest()));
|
||||||
|
connect(revertButton, SIGNAL(clicked()), this, SLOT(revertRecord()));
|
||||||
|
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteRecord()));
|
||||||
|
|
||||||
|
mMainLayout = new QVBoxLayout(mainWidget);
|
||||||
|
|
||||||
|
mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false);
|
||||||
|
connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)),
|
||||||
|
this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)));
|
||||||
|
|
||||||
|
mMainLayout->addWidget(mEditWidget);
|
||||||
|
mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||||
|
|
||||||
|
mMainLayout->addWidget (mBottom =
|
||||||
|
new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this));
|
||||||
|
|
||||||
|
mBottom->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||||
|
connect(mBottom, SIGNAL(requestFocus(const std::string&)), this, SLOT(requestFocus(const std::string&)));
|
||||||
|
connect(addButton, SIGNAL(clicked()), mBottom, SLOT(createRequest()));
|
||||||
|
|
||||||
|
if(!mBottom->canCreateAndDelete())
|
||||||
|
{
|
||||||
|
cloneButton->setDisabled(true);
|
||||||
|
addButton->setDisabled(true);
|
||||||
|
deleteButton->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataChanged(mTable->index(mRow, 0));
|
||||||
|
mMainLayout->addLayout(buttonsLayout);
|
||||||
|
setWidget(mainWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::prevId()
|
||||||
|
{
|
||||||
|
int newRow = mRow - 1;
|
||||||
|
if (newRow < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (newRow >= 0)
|
||||||
|
{
|
||||||
|
QModelIndex newIndex(mTable->index(newRow, 0));
|
||||||
|
|
||||||
|
if (!newIndex.isValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (newRow, 1)).toInt());
|
||||||
|
if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased))
|
||||||
|
{
|
||||||
|
mEditWidget->remake(newRow);
|
||||||
|
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
|
||||||
|
mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||||
|
mRow = newRow;
|
||||||
|
mEditWidget->setDisabled(mLocked);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
--newRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::nextId()
|
||||||
|
{
|
||||||
|
int newRow = mRow + 1;
|
||||||
|
|
||||||
|
if (newRow >= mTable->rowCount())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (newRow < mTable->rowCount())
|
||||||
|
{
|
||||||
|
QModelIndex newIndex(mTable->index(newRow, 0));
|
||||||
|
|
||||||
|
if (!newIndex.isValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (newRow, 1)).toInt());
|
||||||
|
if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased))
|
||||||
|
{
|
||||||
|
mEditWidget->remake(newRow);
|
||||||
|
setUniversalId(CSMWorld::UniversalId (static_cast<CSMWorld::UniversalId::Type> (mTable->data (mTable->index (newRow, 2)).toInt()),
|
||||||
|
mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData()));
|
||||||
|
mRow = newRow;
|
||||||
|
mEditWidget->setDisabled(mLocked);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
++newRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
||||||
|
{
|
||||||
|
mLocked = locked;
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
|
if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(true);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(mLocked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index)
|
||||||
|
{
|
||||||
|
if (index.row() == mRow)
|
||||||
|
{
|
||||||
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
|
if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(true);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(mLocked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor,
|
||||||
|
const QModelIndex& index,
|
||||||
|
const CSMWorld::UniversalId& id,
|
||||||
|
const CSMDoc::Document* document)
|
||||||
|
{
|
||||||
|
if (document == &mDocument)
|
||||||
|
{
|
||||||
|
qobject_cast<DropLineEdit*>(editor)->setText(id.getId().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::revertRecord()
|
||||||
|
{
|
||||||
|
int rows = mTable->rowCount();
|
||||||
|
if (!mLocked && mTable->columnCount() > 0 && mRow < mTable->rowCount() )
|
||||||
|
{
|
||||||
|
CSMWorld::RecordBase::State state =
|
||||||
|
static_cast<CSMWorld::RecordBase::State> (mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
|
|
||||||
|
if (state!=CSMWorld::RecordBase::State_BaseOnly)
|
||||||
|
{
|
||||||
|
mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()));
|
||||||
|
}
|
||||||
|
if (rows != mTable->rowCount())
|
||||||
|
{
|
||||||
|
if (mTable->rowCount() == 0)
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(true); //closing the editor is other option
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
if (mRow >= mTable->rowCount())
|
||||||
{
|
{
|
||||||
switch (display)
|
prevId();
|
||||||
{
|
} else {
|
||||||
case CSMWorld::ColumnBase::Display_String:
|
dataChanged(mTable->index(mRow, 0));
|
||||||
case CSMWorld::ColumnBase::Display_Integer:
|
}
|
||||||
case CSMWorld::ColumnBase::Display_Float:
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
layout->addWidget (widget = new QLabel, i, 1);
|
void CSVWorld::DialogueSubView::deleteRecord()
|
||||||
break;
|
{
|
||||||
|
int rows = mTable->rowCount();
|
||||||
|
|
||||||
default: break; // silence warnings for other times for now
|
//easier than disabling the button
|
||||||
}
|
CSMWorld::RecordBase::State state = static_cast<CSMWorld::RecordBase::State>(mTable->data (mTable->index (mRow, 1)).toInt());
|
||||||
}
|
bool deledetedOrErased = (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased);
|
||||||
|
|
||||||
if (widget)
|
if (!mLocked &&
|
||||||
mWidgetMapper->addMapping (widget, i);
|
mTable->columnCount() > 0 &&
|
||||||
|
!deledetedOrErased &&
|
||||||
|
mRow < rows &&
|
||||||
|
mBottom->canCreateAndDelete())
|
||||||
|
{
|
||||||
|
mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()));
|
||||||
|
if (rows != mTable->rowCount())
|
||||||
|
{
|
||||||
|
if (mTable->rowCount() == 0)
|
||||||
|
{
|
||||||
|
mEditWidget->setDisabled(true); //closing the editor is other option
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mRow >= mTable->rowCount())
|
||||||
|
{
|
||||||
|
prevId();
|
||||||
|
} else {
|
||||||
|
dataChanged(mTable->index(mRow, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mWidgetMapper->setCurrentModelIndex (
|
void CSVWorld::DialogueSubView::requestFocus (const std::string& id)
|
||||||
dynamic_cast<CSMWorld::IdTable&> (*model).getModelIndex (id.getId(), 0));
|
{
|
||||||
|
mRow = mTable->getModelIndex (id, 0).row();
|
||||||
|
mEditWidget->remake(mRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSVWorld::DialogueSubView::setEditLock (bool locked)
|
void CSVWorld::DialogueSubView::cloneRequest ()
|
||||||
{
|
{
|
||||||
|
mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData(),
|
||||||
|
static_cast<CSMWorld::UniversalId::Type>(mTable->data(mTable->index(mRow, 2)).toInt()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
void CSVWorld::DialogueSubView::showPreview ()
|
||||||
|
{
|
||||||
|
if (mTable->hasPreview() && mRow < mTable->rowCount())
|
||||||
|
{
|
||||||
|
emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::DialogueSubView::viewRecord()
|
||||||
|
{
|
||||||
|
if (mRow < mTable->rowCount())
|
||||||
|
{
|
||||||
|
std::pair<CSMWorld::UniversalId, std::string> params = mTable->view (mRow);
|
||||||
|
|
||||||
|
if (params.first.getType()!=CSMWorld::UniversalId::Type_None)
|
||||||
|
emit focusId (params.first, params.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
#include "previewsubview.hpp"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
#include "../render/previewwidget.hpp"
|
||||||
|
|
||||||
|
#include "scenetoolbar.hpp"
|
||||||
|
#include "scenetoolmode.hpp"
|
||||||
|
|
||||||
|
CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
|
||||||
|
: SubView (id)
|
||||||
|
{
|
||||||
|
QHBoxLayout *layout = new QHBoxLayout;
|
||||||
|
|
||||||
|
layout->setContentsMargins (QMargins (0, 0, 0, 0));
|
||||||
|
|
||||||
|
if (document.getData().getReferenceables().searchId (id.getId())==-1)
|
||||||
|
{
|
||||||
|
std::string referenceableId =
|
||||||
|
document.getData().getReferences().getRecord (id.getId()).get().mRefID;
|
||||||
|
|
||||||
|
referenceableIdChanged (referenceableId);
|
||||||
|
|
||||||
|
mScene =
|
||||||
|
new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), this);
|
||||||
|
|
||||||
|
SceneToolbar *toolbar = new SceneToolbar (48, this);
|
||||||
|
|
||||||
|
SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar);
|
||||||
|
toolbar->addTool (lightingTool);
|
||||||
|
|
||||||
|
layout->addWidget (toolbar, 0);
|
||||||
|
|
||||||
|
layout->addWidget (mScene, 1);
|
||||||
|
|
||||||
|
QWidget *widget = new QWidget;
|
||||||
|
|
||||||
|
widget->setLayout (layout);
|
||||||
|
|
||||||
|
setWidget (widget);
|
||||||
|
|
||||||
|
connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest()));
|
||||||
|
connect (mScene, SIGNAL (referenceableIdChanged (const std::string&)),
|
||||||
|
this, SLOT (referenceableIdChanged (const std::string&)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::PreviewSubView::setEditLock (bool locked) {}
|
||||||
|
|
||||||
|
void CSVWorld::PreviewSubView::closeRequest()
|
||||||
|
{
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVWorld::PreviewSubView::referenceableIdChanged (const std::string& id)
|
||||||
|
{
|
||||||
|
if (id.empty())
|
||||||
|
setWindowTitle ("Preview: Reference to <nothing>");
|
||||||
|
else
|
||||||
|
setWindowTitle (("Preview: Reference to " + id).c_str());
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef CSV_WORLD_PREVIEWSUBVIEW_H
|
||||||
|
#define CSV_WORLD_PREVIEWSUBVIEW_H
|
||||||
|
|
||||||
|
#include "../doc/subview.hpp"
|
||||||
|
|
||||||
|
namespace CSMDoc
|
||||||
|
{
|
||||||
|
class Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVRender
|
||||||
|
{
|
||||||
|
class PreviewWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSVWorld
|
||||||
|
{
|
||||||
|
class PreviewSubView : public CSVDoc::SubView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
CSVRender::PreviewWidget *mScene;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);
|
||||||
|
|
||||||
|
virtual void setEditLock (bool locked);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void closeRequest();
|
||||||
|
|
||||||
|
void referenceableIdChanged (const std::string& id);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue