Compare commits
21 Commits
main/gingo
...
hg/feature
Author | SHA1 | Date |
---|---|---|
kaetemi | e72f40fd17 | 9 years ago |
kaetemi | ad549070e1 | 9 years ago |
kaetemi | 197ffd7c6a | 9 years ago |
kaetemi | 8c6952b268 | 9 years ago |
kaetemi | ef9228df16 | 9 years ago |
kaetemi | 531398bf0a | 9 years ago |
kaetemi | 67a5497883 | 9 years ago |
kaetemi | e6385a1b34 | 9 years ago |
kaetemi | 5aab1d651a | 9 years ago |
kaetemi | 8205a8ee51 | 9 years ago |
kaetemi | 93e8e11cf7 | 9 years ago |
kaetemi | 47bc7e439a | 9 years ago |
kaetemi | 019ca734c7 | 9 years ago |
kaetemi | 95ea710466 | 9 years ago |
kaetemi | 2053e075fc | 9 years ago |
kaetemi | 596a4ba7a3 | 9 years ago |
kaetemi | ab790a5f08 | 9 years ago |
kaetemi | 697299d61b | 9 years ago |
kaetemi | 26c8bbff46 | 9 years ago |
kaetemi | 571ab41ffc | 9 years ago |
kaetemi | 7012965c78 | 9 years ago |
@ -0,0 +1,39 @@
|
||||
|
||||
FILE(GLOB SRCS *.cpp)
|
||||
FILE(GLOB HDRS *.h)
|
||||
IF (WIN32)
|
||||
FILE(GLOB RSRC *.rc)
|
||||
ENDIF (WIN32)
|
||||
FILE(GLOB RESOURCES *.qrc)
|
||||
|
||||
SOURCE_GROUP("" FILES ${SRCS} ${HDRS} ${RSRC} ${RESOURCES})
|
||||
|
||||
SET(CMAKE_AUTOMOC ON)
|
||||
|
||||
QT5_ADD_RESOURCES(RESOURCE_ADDED ${RESOURCES})
|
||||
|
||||
ADD_EXECUTABLE(nl_mesh_editor WIN32 ${SRC}
|
||||
${SRCS}
|
||||
${HDRS}
|
||||
${RSRC}
|
||||
${RESOURCE_ADDED}
|
||||
)
|
||||
|
||||
IF(QT_STATIC)
|
||||
SET(PANOPLY_PREVIEW_QT_LIBRARIES ${QT_LIBRARIES})
|
||||
ELSE()
|
||||
SET(PANOPLY_PREVIEW_QT_LIBRARIES Qt5::Widgets)
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(nl_mesh_editor
|
||||
nelmisc
|
||||
nel3d
|
||||
nelsound
|
||||
nelpipeline
|
||||
shared_widgets
|
||||
mesh_utils)
|
||||
|
||||
NL_DEFAULT_PROPS(nl_mesh_editor "NeL, Tools, 3D: Mesh Editor")
|
||||
NL_ADD_RUNTIME_FLAGS(nl_mesh_editor)
|
||||
|
||||
INSTALL(TARGETS nl_mesh_editor RUNTIME DESTINATION ${NL_BIN_PREFIX} COMPONENT samples3d)
|
@ -0,0 +1,242 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include "configuration.h"
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
#include <nel/misc/hierarchical_timer.h>
|
||||
#include <nel/misc/config_file.h>
|
||||
#include <nel/misc/path.h>
|
||||
#include <nel/misc/i18n.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace NLMISC;
|
||||
|
||||
CConfiguration::CConfiguration()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CConfiguration::~CConfiguration()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CConfiguration::init()
|
||||
{
|
||||
// verify data
|
||||
nlassert(m_ConfigCallbacks.empty());
|
||||
|
||||
// load config
|
||||
std::string appData = CPath::getApplicationDirectory("NeL");
|
||||
m_ConfigFile.load(appData + "mesh_editor.cfg");
|
||||
|
||||
// log config
|
||||
CConfiguration::setAndCallback("NegFiltersDebug", CConfigCallback(this, &CConfiguration::cfcbLogFilter));
|
||||
CConfiguration::setAndCallback("NegFiltersInfo", CConfigCallback(this, &CConfiguration::cfcbLogFilter));
|
||||
CConfiguration::setAndCallback("NegFiltersWarning", CConfigCallback(this, &CConfiguration::cfcbLogFilter));
|
||||
CConfiguration::setAndCallback("NegFiltersAssert", CConfigCallback(this, &CConfiguration::cfcbLogFilter));
|
||||
CConfiguration::setAndCallback("NegFiltersError", CConfigCallback(this, &CConfiguration::cfcbLogFilter));
|
||||
|
||||
// set the search paths (kinda important)
|
||||
/*
|
||||
CConfigFile::CVar *var;
|
||||
var = m_ConfigFile.getVarPtr("SearchPaths");
|
||||
uint varsize = var->size();
|
||||
for (uint i = 0; i < varsize; ++i)
|
||||
CPath::addSearchPath(var->asString(i), true, false);
|
||||
var = m_ConfigFile.getVarPtr("RemapExtensions");
|
||||
varsize = var->size();
|
||||
for (uint i = 0; i < varsize; i += 2)
|
||||
CPath::remapExtension(var->asString(i), var->asString(i + 1), true);
|
||||
*/
|
||||
}
|
||||
|
||||
void CConfiguration::release()
|
||||
{
|
||||
// bye bye log config
|
||||
CConfigFile::CVar emptyVar;
|
||||
emptyVar.Name = "NegFiltersDebug";
|
||||
CConfiguration::dropCallback(emptyVar.Name);
|
||||
cfcbLogFilter(emptyVar);
|
||||
emptyVar.Name = "NegFiltersInfo";
|
||||
CConfiguration::dropCallback(emptyVar.Name);
|
||||
cfcbLogFilter(emptyVar);
|
||||
emptyVar.Name = "NegFiltersWarning";
|
||||
CConfiguration::dropCallback(emptyVar.Name);
|
||||
cfcbLogFilter(emptyVar);
|
||||
emptyVar.Name = "NegFiltersAssert";
|
||||
CConfiguration::dropCallback(emptyVar.Name);
|
||||
cfcbLogFilter(emptyVar);
|
||||
emptyVar.Name = "NegFiltersError";
|
||||
CConfiguration::dropCallback(emptyVar.Name);
|
||||
cfcbLogFilter(emptyVar);
|
||||
|
||||
// save and release the config file
|
||||
if (m_ConfigFile.exists("SaveConfig") && m_ConfigFile.getVarPtr("SaveConfig")->asBool())
|
||||
{
|
||||
m_ConfigFile.save();
|
||||
}
|
||||
m_ConfigFile.clear();
|
||||
|
||||
// release the search paths etc
|
||||
CPath::releaseInstance();
|
||||
|
||||
// verify data
|
||||
nlassert(!m_ConfigCallbacks.size());
|
||||
}
|
||||
|
||||
void CConfiguration::updateUtilities()
|
||||
{
|
||||
//H_AUTO2
|
||||
|
||||
CConfigFile::checkConfigFiles();
|
||||
}
|
||||
|
||||
void CConfiguration::setAndCallback(const std::string &varName, CConfigCallback configCallback)
|
||||
{
|
||||
m_ConfigCallbacks[varName] = configCallback;
|
||||
m_ConfigFile.setCallback(varName, cbConfigCallback);
|
||||
configCallback(*m_ConfigFile.getVarPtr(varName));
|
||||
}
|
||||
|
||||
void CConfiguration::setCallback(const std::string &varName, CConfigCallback configCallback)
|
||||
{
|
||||
m_ConfigCallbacks[varName] = configCallback;
|
||||
m_ConfigFile.setCallback(varName, cbConfigCallback);
|
||||
}
|
||||
|
||||
void CConfiguration::dropCallback(const std::string &varName)
|
||||
{
|
||||
m_ConfigFile.setCallback(varName, NULL);
|
||||
m_ConfigCallbacks.erase(varName);
|
||||
}
|
||||
|
||||
float CConfiguration::getValue(const string &varName, float defaultValue)
|
||||
{
|
||||
if (m_ConfigFile.exists(varName)) return m_ConfigFile.getVar(varName).asFloat();
|
||||
CConfigFile::CVar varToCopy;
|
||||
varToCopy.forceAsDouble((double)defaultValue);
|
||||
m_ConfigFile.insertVar(varName, varToCopy);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
double CConfiguration::getValue(const string &varName, double defaultValue)
|
||||
{
|
||||
if (m_ConfigFile.exists(varName)) return m_ConfigFile.getVar(varName).asDouble();
|
||||
CConfigFile::CVar varToCopy;
|
||||
varToCopy.forceAsDouble(defaultValue);
|
||||
m_ConfigFile.insertVar(varName, varToCopy);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
int CConfiguration::getValue(const string &varName, int defaultValue)
|
||||
{
|
||||
if (m_ConfigFile.exists(varName)) return m_ConfigFile.getVar(varName).asInt();
|
||||
CConfigFile::CVar varToCopy;
|
||||
varToCopy.forceAsInt(defaultValue);
|
||||
m_ConfigFile.insertVar(varName, varToCopy);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
string CConfiguration::getValue(const string &varName, const string &defaultValue)
|
||||
{
|
||||
if (m_ConfigFile.exists(varName)) return m_ConfigFile.getVar(varName).asString();
|
||||
CConfigFile::CVar varToCopy;
|
||||
varToCopy.forceAsString(defaultValue);
|
||||
m_ConfigFile.insertVar(varName, varToCopy);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
ucstring CConfiguration::getValue(const string &varName, const ucstring &defaultValue)
|
||||
{
|
||||
if (m_ConfigFile.exists(varName)) return ucstring::makeFromUtf8(m_ConfigFile.getVar(varName).asString());
|
||||
CConfigFile::CVar varToCopy;
|
||||
varToCopy.forceAsString(defaultValue.toUtf8());
|
||||
m_ConfigFile.insertVar(varName, varToCopy);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
bool CConfiguration::getValue(const string &varName, bool defaultValue)
|
||||
{
|
||||
if (m_ConfigFile.exists(varName)) return m_ConfigFile.getVar(varName).asBool();
|
||||
CConfigFile::CVar varToCopy;
|
||||
varToCopy.forceAsInt(defaultValue ? 1 : 0);
|
||||
m_ConfigFile.insertVar(varName, varToCopy);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
CRGBA CConfiguration::getValue(const string &varName, const CRGBA &defaultValue)
|
||||
{
|
||||
if (m_ConfigFile.exists(varName))
|
||||
{
|
||||
return getValue(m_ConfigFile.getVar(varName), defaultValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// create a new value only if one doesn't exist
|
||||
CConfigFile::CVar varToCopy;
|
||||
varToCopy.forceAsInt(defaultValue.R);
|
||||
varToCopy.setAsInt(defaultValue.G, 1);
|
||||
varToCopy.setAsInt(defaultValue.B, 2);
|
||||
varToCopy.setAsInt(defaultValue.A, 3);
|
||||
m_ConfigFile.insertVar(varName, varToCopy);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
CRGBA CConfiguration::getValue(const CConfigFile::CVar &var, const CRGBA &defaultValue)
|
||||
{
|
||||
if (var.size() >= 3)
|
||||
{
|
||||
if (var.size() > 4) nlwarning("RGBA value in config value '%s' is too long, ignoring unused values");
|
||||
return CRGBA((uint8)var.asInt(0), (uint8)var.asInt(1), (uint8)var.asInt(2), var.size() >= 4 ? (uint8)var.asInt(3) : 255);
|
||||
}
|
||||
nlwarning("Invalid RGBA value in config value '%s', reverting to default { %i, %i, %i, %i }", var.Name.c_str(), (sint)defaultValue.R, (sint)defaultValue.G, (sint)defaultValue.B, (sint)defaultValue.A);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
void CConfiguration::cbConfigCallback(NLMISC::CConfigFile::CVar &var)
|
||||
{
|
||||
CConfiguration::getInstance()->m_ConfigCallbacks[var.Name](var);
|
||||
}
|
||||
|
||||
void CConfiguration::cfcbLogFilter(CConfigFile::CVar &var)
|
||||
{
|
||||
// from nel/net/service.cpp
|
||||
CLog *log = NULL;
|
||||
if (var.Name == "NegFiltersDebug") log = DebugLog;
|
||||
else if (var.Name == "NegFiltersInfo") log = InfoLog;
|
||||
else if (var.Name == "NegFiltersWarning") log = WarningLog;
|
||||
else if (var.Name == "NegFiltersAssert") log = AssertLog;
|
||||
else if (var.Name == "NegFiltersError") log = ErrorLog;
|
||||
else nlstop;
|
||||
|
||||
// remove all old filters from config file
|
||||
CConfigFile::CVar &oldvar = m_ConfigFile.getVar(var.Name);
|
||||
for (uint j = 0; j < oldvar.size(); j++)
|
||||
log->removeFilter(oldvar.asString(j).c_str());
|
||||
|
||||
// add all new filters from config file
|
||||
for (uint i = 0; i < var.size(); i++)
|
||||
log->addNegativeFilter(var.asString(i).c_str());
|
||||
}
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,81 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef NLQT_CONFIGURATION_H
|
||||
#define NLQT_CONFIGURATION_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
#include <map>
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/callback.h>
|
||||
#include <nel/misc/config_file.h>
|
||||
#include <nel/misc/rgba.h>
|
||||
#include <nel/misc/ucstring.h>
|
||||
#include <nel/misc/singleton.h>
|
||||
|
||||
typedef NLMISC::CCallback<void, NLMISC::CConfigFile::CVar &> CConfigCallback;
|
||||
|
||||
/**
|
||||
* CConfiguration
|
||||
* \brief CConfiguration
|
||||
* \date 2010-02-05 15:44GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CConfiguration : public NLMISC::CManualSingleton<CConfiguration> // singleton due to cconfigfile issues
|
||||
{
|
||||
public:
|
||||
CConfiguration();
|
||||
virtual ~CConfiguration();
|
||||
|
||||
void init();
|
||||
void release();
|
||||
|
||||
void updateUtilities();
|
||||
|
||||
void setAndCallback(const std::string &varName, CConfigCallback configCallback);
|
||||
void setCallback(const std::string &varName, CConfigCallback configCallback);
|
||||
void dropCallback(const std::string &varName);
|
||||
|
||||
float getValue(const std::string &varName, float defaultValue);
|
||||
double getValue(const std::string &varName, double defaultValue);
|
||||
int getValue(const std::string &varName, int defaultValue);
|
||||
std::string getValue(const std::string &varName, const std::string &defaultValue);
|
||||
ucstring getValue(const std::string &varName, const ucstring &defaultValue);
|
||||
bool getValue(const std::string &varName, bool defaultValue);
|
||||
NLMISC::CRGBA getValue(const std::string &varName, const NLMISC::CRGBA &defaultValue);
|
||||
NLMISC::CRGBA getValue(const NLMISC::CConfigFile::CVar &var, const NLMISC::CRGBA &defaultValue);
|
||||
|
||||
inline NLMISC::CConfigFile &getConfigFile() { return m_ConfigFile; }
|
||||
|
||||
private:
|
||||
static void cbConfigCallback(NLMISC::CConfigFile::CVar &var);
|
||||
void cfcbLogFilter(NLMISC::CConfigFile::CVar &var);
|
||||
|
||||
private:
|
||||
CConfiguration(const CConfiguration &);
|
||||
CConfiguration &operator=(const CConfiguration &);
|
||||
|
||||
private:
|
||||
NLMISC::CConfigFile m_ConfigFile;
|
||||
std::map<std::string, CConfigCallback> m_ConfigCallbacks;
|
||||
|
||||
}; /* class CConfiguration */
|
||||
|
||||
#endif /* #ifndef NLQT_CONFIGURATION_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>data/andbasr.ttf</file>
|
||||
<file>data/mesh_editor.cfg</file>
|
||||
<file>data/mesh_editor_default.cfg</file>
|
||||
</qresource>
|
||||
</RCC>
|
Binary file not shown.
@ -0,0 +1 @@
|
||||
RootConfigFilename = "mesh_editor_default.cfg";
|
@ -0,0 +1,84 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Config file for NeL Mesh Editor ///////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// This file is used to setup the NeL Mesh Editor tool.
|
||||
//
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// NeL Mesh Editor ///////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Log filters
|
||||
NegFiltersDebug += { ".zonel", "FRONT: " };
|
||||
NegFiltersInfo += { };
|
||||
NegFiltersWarning += { ".zonel", "FRONT: " };
|
||||
NegFiltersAssert += { };
|
||||
NegFiltersError += { };
|
||||
|
||||
// The language code of the client
|
||||
LanguageCode = "en";
|
||||
|
||||
// If changes to the config should be saved on exit
|
||||
SaveConfig = 1;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Graphics //////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Use OpenGL or Direct3D (Windows)
|
||||
GraphicsEnabled = 1;
|
||||
GraphicsDrivers = { "OpenGL", "Direct3D" };
|
||||
GraphicsDriver = "OpenGL";
|
||||
|
||||
// Font name used for all text in the client (it can be a .ttf, .fon, .pfb)
|
||||
FontName = "andbasr.ttf";
|
||||
FontShadow = 1;
|
||||
|
||||
// Background color
|
||||
BackgroundColor = { 41, 57, 85 };
|
||||
|
||||
// Screenshot formats
|
||||
ScreenshotJPG = 1;
|
||||
ScreenshotPNG = 1;
|
||||
ScreenshotTGA = 0;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Environment ///////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SunDirection = { -2.935, +0.107, -1.22 };
|
||||
SunAmbient = { 190, 170, 150 };
|
||||
SunDiffuse = { 255, 248, 255 };
|
||||
SunSpecular = { 255, 255, 255};
|
||||
|
||||
// 1 if you want to see the fog
|
||||
// FogEnable = 1;
|
||||
// FogStart = 100.0; // in meter
|
||||
// FogEnd = 250.0; // in meter
|
||||
// FogColor = { 129, 136, 205 }; // { 147, 125, 114 };
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Sound /////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// The sound driver, choose between "Auto", "FMod", "DSound" and "OpenAl"
|
||||
SoundEnabled = 0;
|
||||
SoundDrivers = { "Auto", "OpenAL", "XAudio2", "FMod", "DSound" };
|
||||
SoundDriver = "OpenAL";
|
||||
SoundDevice = "";
|
||||
SoundMaxTrack = 48;
|
||||
SoundEnableOccludeObstruct = 1;
|
||||
SoundEnableReverb = 1;
|
||||
SoundManualRolloff = 1;
|
||||
SoundUseADPCM = 0;
|
||||
SoundForceSoftware = 0;
|
||||
SoundAutoLoadSample = 1;
|
||||
|
||||
|
||||
// end of file
|
@ -0,0 +1,258 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include "graphics_config.h"
|
||||
|
||||
// STL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QUndoStack>
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
|
||||
// Project includes
|
||||
#include "main_window.h"
|
||||
#include "configuration.h"
|
||||
#include "undo_redo_binders.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace NLMISC;
|
||||
|
||||
CGraphicsConfig::CGraphicsConfig(QWidget *parent, CConfiguration *configuration, QUndoStack *undoStack)
|
||||
: QWidget(parent), m_Configuration(configuration), m_UndoStack(undoStack),
|
||||
m_DriverGroup(NULL), m_Enabled(NULL), m_DriverLabel(NULL), m_Driver(NULL),
|
||||
m_FontNameLabel(NULL), m_FontName(NULL), m_Apply(NULL),
|
||||
m_RenderGroup(NULL), m_BackgroundColor(NULL), m_FontShadow(NULL),
|
||||
m_ScreenshotGroup(NULL)
|
||||
{
|
||||
nlassert(m_Configuration);
|
||||
nlassert(m_UndoStack);
|
||||
|
||||
QVBoxLayout *vboxLayout = new QVBoxLayout();
|
||||
|
||||
// Driver
|
||||
{
|
||||
nlassert(!m_DriverGroup);
|
||||
m_DriverGroup = new QGroupBox();
|
||||
QVBoxLayout *groupVboxLayout = new QVBoxLayout();
|
||||
|
||||
// Enabled
|
||||
{
|
||||
nlassert(!m_Enabled);
|
||||
m_Enabled = new QCheckBox();
|
||||
groupVboxLayout->addWidget(m_Enabled);
|
||||
}
|
||||
|
||||
// Driver
|
||||
{
|
||||
QHBoxLayout *hboxLayout = new QHBoxLayout();
|
||||
nlassert(!m_DriverLabel);
|
||||
m_DriverLabel = new QLabel();
|
||||
nlassert(!m_Driver);
|
||||
m_Driver = new QComboBox();
|
||||
m_DriverLabel->setBuddy(m_Driver);
|
||||
hboxLayout->addWidget(m_DriverLabel);
|
||||
hboxLayout->addWidget(m_Driver);
|
||||
hboxLayout->setStretch(1, 1);
|
||||
groupVboxLayout->addLayout(hboxLayout);
|
||||
}
|
||||
|
||||
// Font Name
|
||||
{
|
||||
QHBoxLayout *hboxLayout = new QHBoxLayout();
|
||||
nlassert(!m_FontNameLabel);
|
||||
m_FontNameLabel = new QLabel();
|
||||
nlassert(!m_FontName);
|
||||
m_FontName = new QLineEdit();
|
||||
m_FontNameLabel->setBuddy(m_FontName);
|
||||
hboxLayout->addWidget(m_FontNameLabel);
|
||||
hboxLayout->addWidget(m_FontName);
|
||||
hboxLayout->setStretch(1, 1);
|
||||
groupVboxLayout->addLayout(hboxLayout);
|
||||
}
|
||||
|
||||
// Apply
|
||||
{
|
||||
nlassert(!m_Apply);
|
||||
m_Apply = new QPushButton();
|
||||
m_Apply->setDefault(true);
|
||||
groupVboxLayout->addWidget(m_Apply);
|
||||
connect(m_Apply, SIGNAL(pressed()), this, SLOT(applyPressed()));
|
||||
}
|
||||
|
||||
m_DriverGroup->setLayout(groupVboxLayout);
|
||||
vboxLayout->addWidget(m_DriverGroup);
|
||||
}
|
||||
|
||||
// Render
|
||||
{
|
||||
nlassert(!m_RenderGroup);
|
||||
m_RenderGroup = new QGroupBox();
|
||||
QVBoxLayout *groupVboxLayout = new QVBoxLayout();
|
||||
|
||||
// Background Color
|
||||
{
|
||||
m_BackgroundColor = new QtColorPicker();
|
||||
m_BackgroundColor->setStandardColors();
|
||||
groupVboxLayout->addWidget(m_BackgroundColor);
|
||||
connect(m_BackgroundColor, SIGNAL(colorChanged(const QColor &)), this, SLOT(uicbBackgroundColor(const QColor &)));
|
||||
}
|
||||
|
||||
// Font Shadow
|
||||
{
|
||||
nlassert(!m_FontShadow);
|
||||
m_FontShadow = new QCheckBox();
|
||||
groupVboxLayout->addWidget(m_FontShadow);
|
||||
connect(m_FontShadow, SIGNAL(toggled(bool)), this, SLOT(uicbFontShadow(bool)));
|
||||
}
|
||||
|
||||
m_RenderGroup->setLayout(groupVboxLayout);
|
||||
vboxLayout->addWidget(m_RenderGroup);
|
||||
}
|
||||
|
||||
// Screenshots
|
||||
{
|
||||
nlassert(!m_ScreenshotGroup);
|
||||
m_ScreenshotGroup = new QGroupBox();
|
||||
QVBoxLayout *groupVboxLayout = new QVBoxLayout();
|
||||
|
||||
m_ScreenshotGroup->setLayout(groupVboxLayout);
|
||||
vboxLayout->addWidget(m_ScreenshotGroup);
|
||||
|
||||
m_ScreenshotGroup->setVisible(false);
|
||||
}
|
||||
|
||||
vboxLayout->addStretch();
|
||||
setLayout(vboxLayout);
|
||||
|
||||
// setup config file callbacks and initialize values
|
||||
m_Configuration->setAndCallback("GraphicsEnabled", CConfigCallback(this, &CGraphicsConfig::cfcbGraphicsEnabled));
|
||||
m_Configuration->setCallback("GraphicsDriver", CConfigCallback(this, &CGraphicsConfig::cfcbGraphicsDriver));
|
||||
m_Configuration->setAndCallback("GraphicsDrivers", CConfigCallback(this, &CGraphicsConfig::cfcbGraphicsDrivers));
|
||||
m_Configuration->setAndCallback("FontName", CConfigCallback(this, &CGraphicsConfig::cfcbFontName));
|
||||
m_Configuration->setAndCallback("BackgroundColor", CConfigCallback(this, &CGraphicsConfig::cfcbBackgroundColor));
|
||||
m_Configuration->setAndCallback("FontShadow", CConfigCallback(this, &CGraphicsConfig::cfcbFontShadow));
|
||||
|
||||
// setup translation callback and initialize translation
|
||||
incbTranslate();
|
||||
|
||||
// setup undo/redo automation
|
||||
CUndoRedoBinderButton *undoRedoEnabled = new CUndoRedoBinderButton(m_Enabled, undoStack);
|
||||
CUndoRedoBinderComboBox *undoRedoDriver = new CUndoRedoBinderComboBox(m_Driver, undoStack);
|
||||
CUndoRedoBinderLineEdit *undoRedoFontName = new CUndoRedoBinderLineEdit(m_FontName, undoStack);
|
||||
CUndoRedoBinderColorPicker *undoRedoBackgroundColor = new CUndoRedoBinderColorPicker(m_BackgroundColor, undoStack);
|
||||
CUndoRedoBinderButton *undoRedoFontShadow = new CUndoRedoBinderButton(m_FontShadow, undoStack);
|
||||
}
|
||||
|
||||
CGraphicsConfig::~CGraphicsConfig()
|
||||
{
|
||||
m_Configuration->dropCallback("FontShadow");
|
||||
m_Configuration->dropCallback("BackgroundColor");
|
||||
m_Configuration->dropCallback("FontName");
|
||||
m_Configuration->dropCallback("GraphicsDrivers");
|
||||
m_Configuration->dropCallback("GraphicsDriver");
|
||||
m_Configuration->dropCallback("GraphicsEnabled");
|
||||
}
|
||||
|
||||
void CGraphicsConfig::incbTranslate()
|
||||
{
|
||||
m_DriverGroup->setTitle(tr("Driver Settings"));
|
||||
m_Enabled->setText(tr("Enabled"));
|
||||
m_DriverLabel->setText(tr("Driver: "));
|
||||
m_FontNameLabel->setText(tr("Font: "));
|
||||
m_Apply->setText(tr("Apply"));
|
||||
|
||||
m_RenderGroup->setTitle(tr("Render Settings"));
|
||||
m_BackgroundColor->setText(tr("Background Color"));
|
||||
m_FontShadow->setText(tr("Font Shadow"));
|
||||
|
||||
m_ScreenshotGroup->setTitle(tr("Screenshot Settings"));
|
||||
}
|
||||
|
||||
void CGraphicsConfig::cfcbGraphicsEnabled(NLMISC::CConfigFile::CVar &var)
|
||||
{
|
||||
m_Enabled->setChecked(var.asBool());
|
||||
}
|
||||
|
||||
void CGraphicsConfig::cfcbGraphicsDrivers(NLMISC::CConfigFile::CVar &var)
|
||||
{
|
||||
while (m_Driver->count())
|
||||
m_Driver->removeItem(0);
|
||||
for (uint i = 0; i < var.size(); ++i)
|
||||
m_Driver->addItem(var.asString(i).c_str());
|
||||
cfcbGraphicsDriver(m_Configuration->getConfigFile().getVar("GraphicsDriver"));
|
||||
m_UndoStack->clear();
|
||||
}
|
||||
|
||||
void CGraphicsConfig::cfcbGraphicsDriver(NLMISC::CConfigFile::CVar &var)
|
||||
{
|
||||
QString value = var.asString().c_str();
|
||||
QString dn = value.toLower();
|
||||
for (sint i = 0; i < m_Driver->count(); ++i)
|
||||
{
|
||||
if (dn == m_Driver->itemText(i).toLower())
|
||||
{
|
||||
m_Driver->setCurrentIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
nlwarning("Unknown GraphicsDriver specified in config, skipping value.");
|
||||
}
|
||||
|
||||
void CGraphicsConfig::cfcbFontName(NLMISC::CConfigFile::CVar &var)
|
||||
{
|
||||
m_FontName->setText(var.asString().c_str());
|
||||
}
|
||||
|
||||
void CGraphicsConfig::cfcbBackgroundColor(NLMISC::CConfigFile::CVar &var)
|
||||
{
|
||||
m_BackgroundColor->setCurrentColor(QColor(var.asInt(0), var.asInt(1), var.asInt(2)));
|
||||
emit onBackgroundColor(getBackgroundColor());
|
||||
}
|
||||
|
||||
void CGraphicsConfig::cfcbFontShadow(NLMISC::CConfigFile::CVar &var)
|
||||
{
|
||||
m_FontShadow->setChecked(var.asBool());
|
||||
emit onFontShadow(getFontShadow());
|
||||
}
|
||||
|
||||
void CGraphicsConfig::applyPressed()
|
||||
{
|
||||
m_Configuration->getConfigFile().getVar("GraphicsEnabled").setAsInt(getGraphicsEnabled() ? 1 : 0);
|
||||
m_Configuration->getConfigFile().getVar("GraphicsDriver").setAsString(getGraphicsDriver());
|
||||
m_Configuration->getConfigFile().getVar("FontName").setAsString(getFontName());
|
||||
emit applyGraphicsConfig();
|
||||
}
|
||||
|
||||
void CGraphicsConfig::uicbBackgroundColor(const QColor &backgroundColor)
|
||||
{
|
||||
m_Configuration->getConfigFile().getVar("BackgroundColor").setAsInt(backgroundColor.red(), 0);
|
||||
m_Configuration->getConfigFile().getVar("BackgroundColor").setAsInt(backgroundColor.green(), 1);
|
||||
m_Configuration->getConfigFile().getVar("BackgroundColor").setAsInt(backgroundColor.blue(), 2);
|
||||
emit onBackgroundColor(getBackgroundColor());
|
||||
}
|
||||
|
||||
void CGraphicsConfig::uicbFontShadow(bool checked)
|
||||
{
|
||||
m_Configuration->getConfigFile().getVar("FontShadow").setAsInt(checked ? 1 : 0);
|
||||
emit onFontShadow(checked);
|
||||
}
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,116 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef NLQT_GRAPHICS_CONFIG_H
|
||||
#define NLQT_GRAPHICS_CONFIG_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QWidget>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QGroupBox>
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/config_file.h>
|
||||
#include <nel/misc/rgba.h>
|
||||
|
||||
// Project includes
|
||||
#include "qtcolorpicker.h"
|
||||
|
||||
class QUndoStack;
|
||||
|
||||
class CMainWindow;
|
||||
class CConfiguration;
|
||||
|
||||
/**
|
||||
* CGraphicsConfig
|
||||
* \brief CGraphicsConfig
|
||||
* \date 2010-02-07 10:15GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CGraphicsConfig : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CGraphicsConfig(QWidget *parent, CConfiguration *configuration, QUndoStack *undoStack);
|
||||
virtual ~CGraphicsConfig();
|
||||
|
||||
void incbTranslate();
|
||||
|
||||
inline bool getGraphicsEnabled() const { return m_Enabled->isChecked(); }
|
||||
inline std::string getGraphicsDriver() const { std::string v = std::string(m_Driver->currentText().toLatin1()); return v; }
|
||||
inline std::string getFontName() const { std::string v = std::string(m_FontName->text().toLatin1()); return v; }
|
||||
|
||||
inline NLMISC::CRGBA getBackgroundColor() const { QColor c = m_BackgroundColor->currentColor(); NLMISC::CRGBA v(c.red(), c.green(), c.blue()); return v; }
|
||||
inline bool getFontShadow() const { return m_FontShadow->isChecked(); }
|
||||
|
||||
inline bool getScreenshotJPG() const { return true; }
|
||||
inline bool getScreenshotPNG() const { return true; }
|
||||
inline bool getScreenshotTGA() const { return false; }
|
||||
|
||||
private slots:
|
||||
void applyPressed();
|
||||
void uicbBackgroundColor(const QColor &backgroundColor);
|
||||
void uicbFontShadow(bool checked);
|
||||
|
||||
signals:
|
||||
/// GraphicsEnabled, GraphicsDriver, FontName
|
||||
void applyGraphicsConfig();
|
||||
void onBackgroundColor(NLMISC::CRGBA backgroundColor);
|
||||
void onFontShadow(bool fontShadow);
|
||||
|
||||
private:
|
||||
void cfcbGraphicsEnabled(NLMISC::CConfigFile::CVar &var);
|
||||
void cfcbGraphicsDrivers(NLMISC::CConfigFile::CVar &var);
|
||||
void cfcbGraphicsDriver(NLMISC::CConfigFile::CVar &var);
|
||||
void cfcbFontName(NLMISC::CConfigFile::CVar &var);
|
||||
void cfcbBackgroundColor(NLMISC::CConfigFile::CVar &var);
|
||||
void cfcbFontShadow(NLMISC::CConfigFile::CVar &var);
|
||||
|
||||
private:
|
||||
CConfiguration *m_Configuration;
|
||||
QUndoStack *m_UndoStack;
|
||||
|
||||
QGroupBox *m_DriverGroup;
|
||||
QCheckBox *m_Enabled;
|
||||
QLabel *m_DriverLabel;
|
||||
QComboBox *m_Driver;
|
||||
QLabel *m_FontNameLabel;
|
||||
QLineEdit *m_FontName;
|
||||
QPushButton *m_Apply;
|
||||
|
||||
QGroupBox *m_RenderGroup;
|
||||
QtColorPicker *m_BackgroundColor;
|
||||
QCheckBox *m_FontShadow;
|
||||
|
||||
QGroupBox *m_ScreenshotGroup;
|
||||
|
||||
private:
|
||||
CGraphicsConfig(const CGraphicsConfig &);
|
||||
CGraphicsConfig &operator=(const CGraphicsConfig &);
|
||||
|
||||
}; /* class CGraphicsConfig */
|
||||
|
||||
#endif /* #ifndef NLQT_GRAPHICS_CONFIG_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,229 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include "graphics_viewport.h"
|
||||
|
||||
// STL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QAction>
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
#include <nel/misc/hierarchical_timer.h>
|
||||
#include <nel/misc/file.h>
|
||||
#include <nel/misc/bitmap.h>
|
||||
#include <nel/misc/path.h>
|
||||
#include <nel/misc/i18n.h>
|
||||
#include <nel/3d/u_driver.h>
|
||||
#include <nel/3d/u_text_context.h>
|
||||
|
||||
// Project includes
|
||||
#include "graphics_config.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace NLMISC;
|
||||
using namespace NL3D;
|
||||
|
||||
namespace {
|
||||
|
||||
QString nli18n(const char *label)
|
||||
{
|
||||
return QString::fromUtf16(CI18N::get(label).c_str());
|
||||
}
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
CGraphicsViewport::CGraphicsViewport(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_GraphicsConfig(NULL),
|
||||
m_Driver(NULL),
|
||||
m_TextContext(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CGraphicsViewport::~CGraphicsViewport()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CGraphicsViewport::init(CGraphicsConfig *graphicsConfig)
|
||||
{
|
||||
//H_AUTO2
|
||||
nldebug("CGraphicsViewport::init");
|
||||
|
||||
// copy parameters
|
||||
m_GraphicsConfig = graphicsConfig;
|
||||
|
||||
// check stuff we need
|
||||
nlassert(m_GraphicsConfig);
|
||||
|
||||
// create the driver
|
||||
nlassert(!m_Driver);
|
||||
m_Direct3D = false;
|
||||
std::string driver = m_GraphicsConfig->getGraphicsDriver();
|
||||
if (driver == "Direct3D") m_Direct3D = true; //m_Driver = Direct3D;
|
||||
else if (driver == "OpenGL") m_Direct3D = false; //m_Driver = OpenGL;
|
||||
else
|
||||
{
|
||||
nlwarning("Invalid driver specified, defaulting to OpenGL");
|
||||
//m_Configuration->getConfigFile().getVar("GraphicsDriver").forceAsString("OpenGL");
|
||||
//m_Driver = OpenGL;
|
||||
}
|
||||
m_Driver = UDriver::createDriver(NULL, m_Direct3D, NULL);
|
||||
nlassert(m_Driver);
|
||||
|
||||
// initialize the window with config file values
|
||||
m_Driver->setDisplay((nlWindow)winId(), NL3D::UDriver::CMode(width(), height(), 32));
|
||||
|
||||
// register config callbacks
|
||||
connect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)),
|
||||
this, SLOT(cfcbBackgroundColor(NLMISC::CRGBA)));
|
||||
m_BackgroundColor = m_GraphicsConfig->getBackgroundColor();
|
||||
|
||||
// set the cache size for the font manager(in bytes)
|
||||
m_Driver->setFontManagerMaxMemory(2097152);
|
||||
|
||||
// create the text context
|
||||
nlassert(!m_TextContext);
|
||||
std::string localAppData = CPath::getApplicationDirectory("NeL", true);
|
||||
std::string fontAppData = localAppData + m_GraphicsConfig->getFontName();
|
||||
m_TextContext = m_Driver->createTextContext(CFile::isExists(fontAppData) ? fontAppData : m_GraphicsConfig->getFontName());
|
||||
nlassert(m_TextContext);
|
||||
connect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)),
|
||||
this, SLOT(cfcbFontShadow(bool)));
|
||||
m_TextContext->setShaded(m_GraphicsConfig->getFontShadow());
|
||||
}
|
||||
|
||||
void CGraphicsViewport::release()
|
||||
{
|
||||
//H_AUTO2
|
||||
nldebug("CGraphicsViewport::release");
|
||||
|
||||
// release text context
|
||||
nlassert(m_TextContext);
|
||||
disconnect(m_GraphicsConfig, SIGNAL(onFontShadow(bool)),
|
||||
this, SLOT(cfcbFontShadow(bool)));
|
||||
m_Driver->deleteTextContext(m_TextContext);
|
||||
m_TextContext = NULL;
|
||||
|
||||
// release driver
|
||||
nlassert(m_Driver);
|
||||
disconnect(m_GraphicsConfig, SIGNAL(onBackgroundColor(NLMISC::CRGBA)),
|
||||
this, SLOT(cfcbBackgroundColor(NLMISC::CRGBA)));
|
||||
m_Driver->release();
|
||||
delete m_Driver;
|
||||
m_Driver = NULL;
|
||||
|
||||
// reset parameters
|
||||
m_GraphicsConfig = NULL;
|
||||
}
|
||||
|
||||
void CGraphicsViewport::updateInput()
|
||||
{
|
||||
// m_Driver->EventServer.pump(); // Can't do this, conflicts with Qt processing
|
||||
}
|
||||
|
||||
void CGraphicsViewport::renderDriver()
|
||||
{
|
||||
m_Driver->clearBuffers(m_BackgroundColor);
|
||||
}
|
||||
|
||||
void CGraphicsViewport::renderDebug2D()
|
||||
{
|
||||
m_TextContext->setColor(NL3D::CRGBA (255, 255, 255));
|
||||
m_TextContext->setFontSize(40);
|
||||
m_TextContext->setHotSpot(NL3D::UTextContext::BottomLeft);
|
||||
m_TextContext->printAt(0.3f, 0.5f, std::string("NeL Qt"));
|
||||
}
|
||||
|
||||
void CGraphicsViewport::cfcbBackgroundColor(NLMISC::CRGBA backgroundColor)
|
||||
{
|
||||
m_BackgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
void CGraphicsViewport::cfcbFontShadow(bool fontShadow)
|
||||
{
|
||||
m_TextContext->setShaded(fontShadow);
|
||||
}
|
||||
|
||||
QAction *CGraphicsViewport::createSaveScreenshotAction(QObject *parent)
|
||||
{
|
||||
QAction *action = new QAction(parent);
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(saveScreenshot()));
|
||||
return action;
|
||||
}
|
||||
|
||||
void CGraphicsViewport::saveScreenshot()
|
||||
{
|
||||
saveScreenshot(
|
||||
m_GraphicsConfig->getScreenshotJPG(),
|
||||
m_GraphicsConfig->getScreenshotPNG(),
|
||||
m_GraphicsConfig->getScreenshotTGA());
|
||||
}
|
||||
|
||||
void CGraphicsViewport::saveScreenshot(bool jpg, bool png, bool tga)
|
||||
{
|
||||
//H_AUTO2
|
||||
|
||||
// empty bitmap
|
||||
CBitmap bitmap;
|
||||
// copy the driver buffer to the bitmap
|
||||
m_Driver->getBuffer(bitmap);
|
||||
// create the file name
|
||||
string filename = NLMISC::CPath::getApplicationDirectory("NeL") + "screenshots/mesh_editor_";
|
||||
// write the bitmap as a jpg, png or tga to the file
|
||||
if (jpg)
|
||||
{
|
||||
string newfilename = CFile::findNewFile(filename + ".jpg");
|
||||
COFile outputFile(newfilename);
|
||||
bitmap.writeJPG(outputFile, 100);
|
||||
nlinfo("Screenshot '%s' saved", newfilename.c_str());
|
||||
}
|
||||
if (png)
|
||||
{
|
||||
string newfilename = CFile::findNewFile(filename + ".png");
|
||||
COFile outputFile(newfilename);
|
||||
bitmap.writePNG(outputFile, 24);
|
||||
nlinfo("Screenshot '%s' saved", newfilename.c_str());
|
||||
}
|
||||
if (tga)
|
||||
{
|
||||
string newfilename = CFile::findNewFile(filename + ".tga");
|
||||
COFile outputFile(newfilename);
|
||||
bitmap.writeTGA(outputFile, 24, false);
|
||||
nlinfo("Screenshot '%s' saved", newfilename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CGraphicsViewport::resizeEvent(QResizeEvent *resizeEvent)
|
||||
{
|
||||
QWidget::resizeEvent(resizeEvent);
|
||||
if (m_Driver && !m_Direct3D)
|
||||
{
|
||||
m_Driver->setMode(UDriver::CMode(resizeEvent->size().width(), resizeEvent->size().height(), 32));
|
||||
}
|
||||
|
||||
// The OpenGL driver does not resize automatically.
|
||||
// The Direct3D driver breaks the window mode to include window borders when calling setMode windowed.
|
||||
|
||||
// Resizing the window after switching drivers a few times becomes slow.
|
||||
// There is probably something inside the drivers not being released properly.
|
||||
}
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,102 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef NLQT_GRAPHICS_VIEWPORT_H
|
||||
#define NLQT_GRAPHICS_VIEWPORT_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QWidget>
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/config_file.h>
|
||||
#include <nel/misc/rgba.h>
|
||||
|
||||
// Project includes
|
||||
|
||||
class QAction;
|
||||
|
||||
namespace NL3D {
|
||||
class UDriver;
|
||||
class UTextContext;
|
||||
class UScene;
|
||||
}
|
||||
|
||||
class CGraphicsConfig;
|
||||
|
||||
/**
|
||||
* CGraphicsViewport
|
||||
* \brief CGraphicsViewport
|
||||
* \date 2010-02-06 10:11GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CGraphicsViewport : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CGraphicsViewport(QWidget *parent);
|
||||
virtual ~CGraphicsViewport();
|
||||
|
||||
virtual QPaintEngine* paintEngine() const { return NULL; }
|
||||
|
||||
void init(CGraphicsConfig *graphicsConfig);
|
||||
void release();
|
||||
|
||||
void updateInput();
|
||||
void renderDriver();
|
||||
void renderDebug2D();
|
||||
|
||||
QAction *createSaveScreenshotAction(QObject *parent);
|
||||
|
||||
void saveScreenshot(bool jpg, bool png, bool tga);
|
||||
|
||||
inline NL3D::UDriver *getDriver() { return m_Driver; }
|
||||
inline NL3D::UTextContext *getTextContext() { return m_TextContext; }
|
||||
// inline NL3D::UScene *getScene() { return m_Scene; }
|
||||
|
||||
public slots:
|
||||
void saveScreenshot();
|
||||
|
||||
private slots:
|
||||
void cfcbBackgroundColor(NLMISC::CRGBA backgroundColor);
|
||||
void cfcbFontShadow(bool fontShadow);
|
||||
|
||||
private:
|
||||
virtual void resizeEvent(QResizeEvent *resizeEvent);
|
||||
|
||||
private:
|
||||
NLMISC::CRGBA m_BackgroundColor;
|
||||
|
||||
CGraphicsConfig *m_GraphicsConfig;
|
||||
|
||||
NL3D::UDriver *m_Driver;
|
||||
NL3D::UTextContext *m_TextContext;
|
||||
// NL3D::UScene *m_Scene;
|
||||
|
||||
bool m_Direct3D;
|
||||
|
||||
private:
|
||||
CGraphicsViewport(const CGraphicsViewport &);
|
||||
CGraphicsViewport &operator=(const CGraphicsViewport &);
|
||||
|
||||
}; /* class CGraphicsViewport */
|
||||
|
||||
#endif /* #ifndef NLQT_GRAPHICS_VIEWPORT_H */
|
||||
|
||||
/* end of file */
|
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
@ -0,0 +1 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "greenpill.ico"
|
@ -0,0 +1,8 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>icons/cross-circle.png</file>
|
||||
<file>icons/exclamation.png</file>
|
||||
<file>icons/information-white.png</file>
|
||||
<file>icons/folder-open-image.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
Binary file not shown.
After Width: | Height: | Size: 689 B |
Binary file not shown.
After Width: | Height: | Size: 613 B |
Binary file not shown.
After Width: | Height: | Size: 764 B |
Binary file not shown.
After Width: | Height: | Size: 651 B |
@ -0,0 +1,165 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2014 Jan BOON (jan.boon@kaetemi.be)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
#include <stdio.h>
|
||||
#ifdef NL_OS_WINDOWS
|
||||
# include <windows.h>
|
||||
# include <direct.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
// Qt includes
|
||||
#include <qglobal.h>
|
||||
|
||||
#ifdef Q_COMPILER_RVALUE_REFS
|
||||
#undef Q_COMPILER_RVALUE_REFS
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMap>
|
||||
#include <QStyleFactory>
|
||||
#include <QFileInfo>
|
||||
|
||||
#ifdef QT_STATICPLUGIN
|
||||
|
||||
#include <QtPlugin>
|
||||
|
||||
#if defined(Q_OS_WIN32)
|
||||
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
|
||||
#elif defined(Q_OS_MAC)
|
||||
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
|
||||
#elif defined(Q_OS_UNIX)
|
||||
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
#include <nel/misc/common.h>
|
||||
#include <nel/misc/file.h>
|
||||
#include <nel/misc/path.h>
|
||||
#include <nel/misc/command.h>
|
||||
#include <nel/misc/sheet_id.h>
|
||||
|
||||
// Project includes
|
||||
#include "../shared_widgets/common.h"
|
||||
#include "main_window.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace NLMISC;
|
||||
|
||||
#define NLTOOLS_LOG_FILE "mesh_editor.log"
|
||||
|
||||
namespace {
|
||||
|
||||
CFileDisplayer *s_FileDisplayer = NULL;
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
#ifdef NL_OS_WINDOWS
|
||||
# ifdef _UNICODE
|
||||
# define tstring wstring
|
||||
# else
|
||||
# define tstring string
|
||||
# endif
|
||||
#endif
|
||||
|
||||
sint main(int argc, char **argv)
|
||||
{
|
||||
// low fragmentation heap (windows)
|
||||
#ifdef NL_OS_WINDOWS
|
||||
ULONG heapFragValue = 2; // enable low fragmentation heap
|
||||
if (HeapSetInformation(GetProcessHeap(),
|
||||
HeapCompatibilityInformation,
|
||||
&heapFragValue, sizeof(heapFragValue)))
|
||||
{
|
||||
nlinfo("HeapSetInformation OK!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
nlwarning("HeapSetInformation FAIL! (%d)\n", GetLastError());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NL_OS_WINDOWS
|
||||
HRESULT hr;
|
||||
hr = hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
bool coInitOk = (hr == S_OK) || (hr == S_FALSE);
|
||||
#endif
|
||||
|
||||
std::string localAppData = CPath::getApplicationDirectory("NeL", true);
|
||||
std::string appData = CPath::getApplicationDirectory("NeL");
|
||||
CFile::createDirectoryTree(localAppData);
|
||||
CFile::createDirectoryTree(appData);
|
||||
CFile::createDirectoryTree(appData + "screenshots/");
|
||||
|
||||
CFile::setRWAccess(localAppData + "andbasr.ttf");
|
||||
QFile::remove(QString::fromUtf8((localAppData + "andbasr.ttf").c_str()));
|
||||
QFile(":/data/andbasr.ttf").copy(QString::fromUtf8((localAppData + "andbasr.ttf").c_str()));
|
||||
CFile::setRWAccess(appData + "mesh_editor_default.cfg");
|
||||
QFile::remove(QString::fromUtf8((appData + "mesh_editor_default.cfg").c_str()));
|
||||
QFile(":/data/mesh_editor_default.cfg").copy(QString::fromUtf8((appData + "mesh_editor_default.cfg").c_str()));
|
||||
if (!QFileInfo(QString::fromUtf8((appData + "mesh_editor.cfg").c_str())).exists())
|
||||
{
|
||||
QFile(":/data/mesh_editor.cfg").copy(QString::fromUtf8((appData + "mesh_editor.cfg").c_str()));
|
||||
CFile::setRWAccess(appData + "mesh_editor.cfg");
|
||||
}
|
||||
|
||||
NLQT::preApplication();
|
||||
QApplication app(argc, const_cast<char **>(argv));
|
||||
NLQT::postApplication();
|
||||
|
||||
// go nel!
|
||||
{
|
||||
// use log.log if NEL_LOG_IN_FILE and NLTOOLS_USE_LOG_LOG defined as 1
|
||||
createDebug(NULL, false, false);
|
||||
|
||||
// create log
|
||||
// filedisplayer only deletes the 001 etc
|
||||
if (CFile::isExists(localAppData + NLTOOLS_LOG_FILE))
|
||||
CFile::deleteFile(localAppData + NLTOOLS_LOG_FILE);
|
||||
// initialize the log file
|
||||
s_FileDisplayer = new CFileDisplayer();
|
||||
s_FileDisplayer->setParam(localAppData + NLTOOLS_LOG_FILE, true);
|
||||
DebugLog->addDisplayer(s_FileDisplayer);
|
||||
InfoLog->addDisplayer(s_FileDisplayer);
|
||||
WarningLog->addDisplayer(s_FileDisplayer);
|
||||
AssertLog->addDisplayer(s_FileDisplayer);
|
||||
ErrorLog->addDisplayer(s_FileDisplayer);
|
||||
|
||||
nlinfo("Welcome to NeL!");
|
||||
}
|
||||
|
||||
CSheetId::initWithoutSheet();
|
||||
|
||||
CMainWindow mainWin;
|
||||
mainWin.resize(1280, 720);
|
||||
mainWin.show();
|
||||
|
||||
int result = app.exec();
|
||||
|
||||
#ifdef NL_OS_WINDOWS
|
||||
if (coInitOk) CoUninitialize();
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,548 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include "main_window.h"
|
||||
|
||||
// STL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QtGui>
|
||||
#include <QTreeView>
|
||||
#include <QDirModel>
|
||||
#include <QUndoStack>
|
||||
#include <QScrollArea>
|
||||
#include <QAction>
|
||||
#include <QMenuBar>
|
||||
#include <QToolBar>
|
||||
#include <QStatusBar>
|
||||
#include <QDockWidget>
|
||||
#include <QMessageBox>
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
#include <nel/3d/u_driver.h>
|
||||
#include <nel/misc/path.h>
|
||||
#include <nel/pipeline/project_config.h>
|
||||
|
||||
// Project includes
|
||||
#include "../shared_widgets/command_log.h"
|
||||
#include "../shared_widgets/error_list.h"
|
||||
#include "graphics_viewport.h"
|
||||
#include "graphics_config.h"
|
||||
#include "texture_select_dialog.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace NLMISC;
|
||||
using namespace NLQT;
|
||||
|
||||
CMainWindow::CMainWindow(QWidget *parent, Qt::WindowFlags flags)
|
||||
: QMainWindow(parent, flags),
|
||||
m_UndoStack(NULL),
|
||||
m_IsGraphicsInitialized(false), m_IsGraphicsEnabled(false),
|
||||
m_IsSoundInitialized(false), m_IsSoundEnabled(false),
|
||||
m_Timer(NULL), m_GraphicsViewport(NULL),
|
||||
m_CommandLog(NULL), m_CommandLogDock(NULL),
|
||||
m_ErrorList(NULL), m_ErrorListDock(NULL),
|
||||
m_GraphicsConfig(NULL), m_GraphicsConfigScroll(NULL), m_GraphicsConfigDock(NULL),
|
||||
m_FileMenu(NULL), m_EditMenu(NULL), m_ViewportMenu(NULL), m_WidgetsMenu(NULL), m_HelpMenu(NULL),
|
||||
m_FileToolBar(NULL), m_EditToolBar(NULL),
|
||||
m_AboutAct(NULL), m_QuitAct(NULL), m_PrintDebugAct(NULL),
|
||||
m_UndoAct(NULL), m_RedoAct(NULL), m_SaveScreenshotAct(NULL),
|
||||
m_IsExiting(false)
|
||||
{
|
||||
setObjectName("CMainWindow");
|
||||
setWindowTitle(tr("NeL Mesh Editor"));
|
||||
|
||||
m_UndoStack = new QUndoStack(this);
|
||||
|
||||
m_Configuration.init();
|
||||
|
||||
m_GraphicsViewport = new CGraphicsViewport(this);
|
||||
setCentralWidget(m_GraphicsViewport);
|
||||
|
||||
createActions();
|
||||
createMenus();
|
||||
createToolBars();
|
||||
createStatusBar();
|
||||
createDockWindows();
|
||||
|
||||
m_Configuration.setAndCallback("LanguageCode", CConfigCallback(this, &CMainWindow::cfcbLanguageCode));
|
||||
|
||||
recalculateMinimumWidth();
|
||||
|
||||
m_Timer = new QTimer(this);
|
||||
connect(m_Timer, SIGNAL(timeout()), this, SLOT(updateRender()));
|
||||
m_Timer->start(40); // 25fps
|
||||
|
||||
m_IsGraphicsEnabled = m_GraphicsConfig->getGraphicsEnabled();
|
||||
connect(m_GraphicsConfig, SIGNAL(applyGraphicsConfig()), this, SLOT(applyGraphicsConfig()));
|
||||
m_Configuration.setAndCallback("SoundEnabled", CConfigCallback(this, &CMainWindow::cfcbSoundEnabled));
|
||||
|
||||
NLMISC::CConfigFile::CVar *recentFiles = m_Configuration.getConfigFile().getVarPtr("RecentFiles");
|
||||
if (recentFiles)
|
||||
{
|
||||
for (uint i = 0; i < recentFiles->size(); ++i)
|
||||
{
|
||||
if (NLMISC::CFile::isExists(recentFiles->asString()))
|
||||
{
|
||||
initProjectConfig(recentFiles->asString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
QDockWidget *dock = new QDockWidget(this);
|
||||
dock->setFloating(true);
|
||||
CTextureBrowser *browser = new CTextureBrowser(dock);
|
||||
dock->setWidget(browser);
|
||||
dock->resize(800, 800);
|
||||
*/
|
||||
|
||||
CTextureSelectDialog *textureSelect = new CTextureSelectDialog(this);
|
||||
textureSelect->exec();
|
||||
}
|
||||
|
||||
CMainWindow::~CMainWindow()
|
||||
{
|
||||
m_Timer->stop();
|
||||
updateInitialization(false);
|
||||
|
||||
delete m_GraphicsConfig; m_GraphicsConfig = NULL;
|
||||
|
||||
m_Configuration.dropCallback("SoundEnabled");
|
||||
m_Configuration.dropCallback("LanguageCode");
|
||||
|
||||
m_Configuration.release();
|
||||
}
|
||||
|
||||
void CMainWindow::initProjectConfig(const std::string &asset)
|
||||
{
|
||||
NLPIPELINE::CProjectConfig::init(asset,
|
||||
NLPIPELINE::CProjectConfig::DatabaseTextureSearchPaths,
|
||||
true);
|
||||
|
||||
std::string databaseRoot = NLPIPELINE::CProjectConfig::getAssetRoot();
|
||||
m_AssetTreeView->setRootIndex(m_AssetTreeModel->index(QString::fromUtf8(databaseRoot.c_str())));
|
||||
}
|
||||
|
||||
void CMainWindow::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
m_Timer->stop();
|
||||
updateInitialization(false);
|
||||
|
||||
QMainWindow::closeEvent(e);
|
||||
}
|
||||
|
||||
void CMainWindow::setVisible(bool visible)
|
||||
{
|
||||
// called by show()
|
||||
// code assuming visible window needed to init the 3d driver
|
||||
if (visible != isVisible())
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
QMainWindow::setVisible(true);
|
||||
updateInitialization(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
updateInitialization(false);
|
||||
QMainWindow::setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMainWindow::updateInitialization(bool visible)
|
||||
{
|
||||
bool done;
|
||||
do
|
||||
{
|
||||
done = true; // set false whenever change
|
||||
bool wantSound = m_IsSoundEnabled && visible;
|
||||
bool wantGraphics = m_IsGraphicsEnabled && visible;
|
||||
// bool wantLandscape = wantGraphics && m_IsGraphicsInitialized && isLandscapeEnabled;
|
||||
|
||||
// .. stuff that depends on other stuff goes on top to prioritize deinitialization
|
||||
|
||||
// Landscape
|
||||
// ...
|
||||
|
||||
// Graphics (Driver)
|
||||
if (m_IsGraphicsInitialized)
|
||||
{
|
||||
if (!wantGraphics)
|
||||
{
|
||||
m_IsGraphicsInitialized = false;
|
||||
if (m_IsSoundInitialized)
|
||||
m_SoundUtilities.releaseGraphics();
|
||||
m_GraphicsViewport->release();
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wantGraphics)
|
||||
{
|
||||
m_GraphicsViewport->init(m_GraphicsConfig);
|
||||
if (m_IsSoundInitialized)
|
||||
m_SoundUtilities.initGraphics(m_GraphicsViewport);
|
||||
m_IsGraphicsInitialized = true;
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Sound (AudioMixer)
|
||||
if (m_IsSoundInitialized)
|
||||
{
|
||||
if (!wantSound)
|
||||
{
|
||||
m_IsSoundInitialized = false;
|
||||
if (m_IsGraphicsInitialized)
|
||||
m_SoundUtilities.releaseGraphics();
|
||||
m_SoundUtilities.release();
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wantSound)
|
||||
{
|
||||
|
||||
m_SoundUtilities.init(&m_Configuration);
|
||||
if (m_IsGraphicsInitialized)
|
||||
m_SoundUtilities.initGraphics(m_GraphicsViewport);
|
||||
m_IsSoundInitialized = true;
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
void CMainWindow::createActions()
|
||||
{
|
||||
m_QuitAct = new QAction(this);
|
||||
m_QuitAct->setShortcuts(QKeySequence::Quit);
|
||||
connect(m_QuitAct, SIGNAL(triggered()), this, SLOT(close()));
|
||||
|
||||
m_AboutAct = new QAction(this);
|
||||
connect(m_AboutAct, SIGNAL(triggered()), this, SLOT(about()));
|
||||
|
||||
m_PrintDebugAct = new QAction(this);
|
||||
connect(m_PrintDebugAct, SIGNAL(triggered()), this, SLOT(printDebug()));
|
||||
|
||||
m_UndoAct = m_UndoStack->createUndoAction(this);
|
||||
m_UndoAct->setShortcuts(QKeySequence::Undo);
|
||||
m_RedoAct = m_UndoStack->createRedoAction(this);
|
||||
m_RedoAct->setShortcuts(QKeySequence::Redo);
|
||||
|
||||
m_SaveScreenshotAct = m_GraphicsViewport->createSaveScreenshotAction(this);
|
||||
}
|
||||
|
||||
void CMainWindow::translateActions()
|
||||
{
|
||||
m_QuitAct->setText(tr("&Exit"));
|
||||
m_QuitAct->setStatusTip(tr("Close the NeL Qt application."));
|
||||
m_AboutAct->setText(tr("&About"));
|
||||
m_AboutAct->setStatusTip(tr("Show the about box."));
|
||||
m_PrintDebugAct->setText(tr("Print Debug"));
|
||||
m_PrintDebugAct->setStatusTip(tr("Print something to debug."));
|
||||
m_UndoAct->setText(tr("&Undo"));
|
||||
m_UndoAct->setStatusTip(tr("Undo the last action."));
|
||||
m_RedoAct->setText(tr("&Redo"));
|
||||
m_RedoAct->setStatusTip(tr("Redo the last undone action."));
|
||||
m_SaveScreenshotAct->setText(tr("Save &Screenshot"));
|
||||
m_SaveScreenshotAct->setStatusTip(tr("Make a screenshot of the current viewport and save it to the default screenshot directory."));
|
||||
}
|
||||
|
||||
void CMainWindow::createMenus()
|
||||
{
|
||||
m_FileMenu = menuBar()->addMenu(QString::null);
|
||||
//m_FileMenu->addAction(saveAct);
|
||||
//m_FileMenu->addSeparator();
|
||||
m_FileMenu->addAction(m_QuitAct);
|
||||
|
||||
m_EditMenu = menuBar()->addMenu(QString::null);
|
||||
m_EditMenu->addAction(m_UndoAct);
|
||||
m_EditMenu->addAction(m_RedoAct);
|
||||
|
||||
m_ViewportMenu = menuBar()->addMenu(QString::null);
|
||||
m_ViewportMenu->addAction(m_SaveScreenshotAct);
|
||||
|
||||
m_WidgetsMenu = menuBar()->addMenu(QString::null);
|
||||
|
||||
menuBar()->addSeparator();
|
||||
|
||||
m_HelpMenu = menuBar()->addMenu(QString::null);
|
||||
m_HelpMenu->addAction(m_AboutAct);
|
||||
}
|
||||
|
||||
void CMainWindow::translateMenus()
|
||||
{
|
||||
m_FileMenu->setTitle(tr("&File"));
|
||||
m_EditMenu->setTitle(tr("&Edit"));
|
||||
m_ViewportMenu->setTitle(tr("&Viewport"));
|
||||
m_WidgetsMenu->setTitle(tr("&Widgets"));
|
||||
m_HelpMenu->setTitle(tr("&Help"));
|
||||
}
|
||||
|
||||
void CMainWindow::createToolBars()
|
||||
{
|
||||
m_FileToolBar = addToolBar(QString::null);
|
||||
m_FileToolBar->addAction(m_QuitAct);
|
||||
m_FileToolBar->addAction(m_PrintDebugAct);
|
||||
|
||||
m_EditToolBar = addToolBar(QString::null);
|
||||
m_EditToolBar->addAction(m_AboutAct);
|
||||
}
|
||||
|
||||
void CMainWindow::translateToolBars()
|
||||
{
|
||||
m_FileToolBar->setWindowTitle(tr("File"));
|
||||
m_EditToolBar->setWindowTitle(tr("Edit"));
|
||||
}
|
||||
|
||||
void CMainWindow::createStatusBar()
|
||||
{
|
||||
statusBar()->showMessage(tr("Ready"));
|
||||
}
|
||||
|
||||
void CMainWindow::createDockWindows()
|
||||
{
|
||||
//QDockWidget *dock = new QDockWidget(tr("Test1"), this);
|
||||
//dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
//customerList = new QListWidget(dock);
|
||||
//dock->setWidget(customerList);
|
||||
//addDockWidget(Qt::RightDockWidgetArea, dock);
|
||||
//m_WidgetsMenu->addAction(dock->toggleViewAction());
|
||||
|
||||
//dock = new QDockWidget(tr("Test2"), this);
|
||||
//paragraphsList = new QListWidget(dock);
|
||||
//dock->setWidget(paragraphsList);
|
||||
//addDockWidget(Qt::RightDockWidgetArea, dock);
|
||||
//m_WidgetsMenu->addAction(dock->toggleViewAction());
|
||||
|
||||
//connect(customerList, SIGNAL(currentTextChanged(QString)),
|
||||
// this, SLOT(insertCustomer(QString)));
|
||||
//connect(paragraphsList, SIGNAL(currentTextChanged(QString)),
|
||||
// this, SLOT(addParagraph(QString)));
|
||||
|
||||
//dock = new QDockWidget(
|
||||
|
||||
// CommandLog (Console)
|
||||
{
|
||||
m_CommandLogDock = new QDockWidget(this);
|
||||
m_CommandLogDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
|
||||
m_CommandLog = new CCommandLogDisplayer(m_CommandLogDock);
|
||||
m_CommandLogDock->setWidget(m_CommandLog);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, m_CommandLogDock);
|
||||
m_WidgetsMenu->addAction(m_CommandLogDock->toggleViewAction());
|
||||
}
|
||||
|
||||
// ErrorList (Error List)
|
||||
{
|
||||
m_ErrorListDock = new QDockWidget(this);
|
||||
m_ErrorListDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
|
||||
m_ErrorList = new CErrorList(m_ErrorListDock);
|
||||
m_ErrorListDock->setWidget(m_ErrorList);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, m_ErrorListDock);
|
||||
m_WidgetsMenu->addAction(m_ErrorListDock->toggleViewAction());
|
||||
tabifyDockWidget(m_CommandLogDock, m_ErrorListDock);
|
||||
}
|
||||
|
||||
// GraphicsConfig (Graphics Configuration)
|
||||
{
|
||||
m_GraphicsConfigDock = new QDockWidget(this);
|
||||
m_GraphicsConfigDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
m_GraphicsConfigScroll = new QScrollArea();
|
||||
m_GraphicsConfigScroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_GraphicsConfigScroll->setWidgetResizable(true);
|
||||
m_GraphicsConfig = new CGraphicsConfig(m_GraphicsConfigDock, &m_Configuration, m_UndoStack);
|
||||
m_GraphicsConfigScroll->setWidget(m_GraphicsConfig);
|
||||
m_GraphicsConfigDock->setWidget(m_GraphicsConfigScroll);
|
||||
addDockWidget(Qt::RightDockWidgetArea, m_GraphicsConfigDock);
|
||||
m_WidgetsMenu->addAction(m_GraphicsConfigDock->toggleViewAction());
|
||||
}
|
||||
|
||||
// AssetTree (Assets)
|
||||
{
|
||||
m_AssetTreeDock = new QDockWidget(this);
|
||||
m_AssetTreeDock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||
m_AssetTreeView = new QTreeView(m_AssetTreeDock);
|
||||
m_AssetTreeModel = new QDirModel();
|
||||
/*
|
||||
QStringList filters;
|
||||
filters.push_back("*.nelmat");
|
||||
filters.push_back("*.dae");
|
||||
filters.push_back("*.3ds");
|
||||
filters.push_back("*.fbx");
|
||||
filters.push_back("*.blend");
|
||||
m_AssetTreeModel->setNameFilters(filters);
|
||||
*/
|
||||
m_AssetTreeView->setModel(m_AssetTreeModel);
|
||||
m_AssetTreeView->setSortingEnabled(true);
|
||||
m_AssetTreeDock->setWidget(m_AssetTreeView);
|
||||
addDockWidget(Qt::LeftDockWidgetArea, m_AssetTreeDock);
|
||||
m_WidgetsMenu->addAction(m_AssetTreeDock->toggleViewAction());
|
||||
}
|
||||
}
|
||||
|
||||
void CMainWindow::translateDockWindows()
|
||||
{
|
||||
m_CommandLogDock->setWindowTitle(tr("Console"));
|
||||
m_ErrorListDock->setWindowTitle(tr("Error List"));
|
||||
m_GraphicsConfigDock->setWindowTitle(tr("Graphics Configuration"));
|
||||
m_AssetTreeDock->setWindowTitle(tr("Asset Database"));
|
||||
}
|
||||
|
||||
void CMainWindow::recalculateMinimumWidth()
|
||||
{
|
||||
if (m_GraphicsConfigScroll)
|
||||
m_GraphicsConfigScroll->setMinimumWidth(m_GraphicsConfig->minimumSizeHint().width() + m_GraphicsConfigScroll->minimumSizeHint().width());
|
||||
}
|
||||
|
||||
void CMainWindow::applyGraphicsConfig()
|
||||
{
|
||||
// reinitializes the graphics system completely
|
||||
// heavy lifting is done in updateInitialization
|
||||
m_IsGraphicsEnabled = false;
|
||||
updateInitialization(isVisible());
|
||||
m_IsGraphicsEnabled = m_GraphicsConfig->getGraphicsEnabled();
|
||||
updateInitialization(isVisible());
|
||||
}
|
||||
|
||||
void CMainWindow::cfcbSoundEnabled(NLMISC::CConfigFile::CVar &var)
|
||||
{
|
||||
// temp, todo as above
|
||||
m_IsSoundEnabled = var.asBool(); // update loop inits
|
||||
}
|
||||
|
||||
void CMainWindow::cfcbLanguageCode(NLMISC::CConfigFile::CVar &var)
|
||||
{
|
||||
setWindowTitle(tr("NeL Mesh Editor"));
|
||||
translateActions();
|
||||
translateMenus();
|
||||
translateToolBars();
|
||||
translateDockWindows();
|
||||
recalculateMinimumWidth();
|
||||
}
|
||||
|
||||
void CMainWindow::about()
|
||||
{
|
||||
QMessageBox::about(this, tr("NeL Mesh Editor"), tr("NeL Mesh Editor"));
|
||||
}
|
||||
|
||||
void CMainWindow::updateRender()
|
||||
{
|
||||
bool visible = isVisible();
|
||||
updateInitialization(visible);
|
||||
|
||||
if (visible)
|
||||
{
|
||||
|
||||
// call all update functions
|
||||
// 01. Update Utilities (configuration etc)
|
||||
m_Configuration.updateUtilities();
|
||||
|
||||
// 02. Update Time (deltas)
|
||||
// ...
|
||||
|
||||
// 03. Update Receive (network, servertime, receive messages)
|
||||
// ...
|
||||
|
||||
// 04. Update Input (keyboard controls, etc)
|
||||
if (m_IsGraphicsInitialized)
|
||||
m_GraphicsViewport->updateInput();
|
||||
|
||||
// 05. Update Weather (sky, snow, wind, fog, sun)
|
||||
// ...
|
||||
|
||||
// 06. Update Entities (movement, do after possible tp from incoming messages etc)
|
||||
// - Move other entities
|
||||
// - Update self entity
|
||||
// - Move bullets
|
||||
// ...
|
||||
|
||||
// 07. Update Landscape (async zone loading near entity)
|
||||
// ...
|
||||
|
||||
// 08. Update Collisions (entities)
|
||||
// - Update entities
|
||||
// - Update move container (swap with Update entities? todo: check code!)
|
||||
// - Update bullets
|
||||
// ...
|
||||
|
||||
// 09. Update Animations (playlists)
|
||||
// - Needs to be either before or after entities, not sure,
|
||||
// there was a problem with wrong order a while ago!!!
|
||||
// ...
|
||||
|
||||
// 10. Update Camera (depends on entities)
|
||||
// ...
|
||||
|
||||
// 11. Update Interface (login, ui, etc)
|
||||
// ...
|
||||
|
||||
// 12. Update Sound (sound driver)
|
||||
if (m_IsSoundInitialized)
|
||||
m_SoundUtilities.updateSound();
|
||||
|
||||
// 13. Update Send (network, send new position etc)
|
||||
// ...
|
||||
|
||||
// 14. Update Debug (stuff for dev)
|
||||
// ...
|
||||
|
||||
if (m_IsGraphicsInitialized && !m_GraphicsViewport->getDriver()->isLost())
|
||||
{
|
||||
// 01. Render Driver (background color)
|
||||
m_GraphicsViewport->renderDriver(); // clear all buffers
|
||||
|
||||
// 02. Render Sky (sky scene)
|
||||
// ...
|
||||
|
||||
// 04. Render Scene (entity scene)
|
||||
// ...
|
||||
|
||||
// 05. Render Effects (flare)
|
||||
// ...
|
||||
|
||||
// 06. Render Interface 3D (player names)
|
||||
// ...
|
||||
|
||||
// 07. Render Debug 3D
|
||||
// ...
|
||||
|
||||
// 08. Render Interface 2D (chatboxes etc, optionally does have 3d)
|
||||
// ...
|
||||
|
||||
// 09. Render Debug 2D (stuff for dev)
|
||||
m_GraphicsViewport->renderDebug2D();
|
||||
|
||||
// swap 3d buffers
|
||||
m_GraphicsViewport->getDriver()->swapBuffers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMainWindow::printDebug()
|
||||
{
|
||||
nldebug("This is a debug message.");
|
||||
}
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,193 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef NLQT_MAIN_WINDOW_H
|
||||
#define NLQT_MAIN_WINDOW_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QMainWindow>
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/rgba.h>
|
||||
#include <nel/misc/ucstring.h>
|
||||
#include <nel/misc/time_nl.h>
|
||||
#include <nel/3d/animation_time.h>
|
||||
#include <nel/net/login_cookie.h>
|
||||
|
||||
// Project includes
|
||||
#include "configuration.h"
|
||||
#include "sound_utilities.h"
|
||||
|
||||
class QTreeView;
|
||||
class QDirModel;
|
||||
class QUndoStack;
|
||||
class QScrollArea;
|
||||
class QTimer;
|
||||
|
||||
namespace NLMISC {
|
||||
class CConfigFile;
|
||||
}
|
||||
|
||||
namespace NL3D {
|
||||
class UDriver;
|
||||
class UScene;
|
||||
class UTextContext;
|
||||
class UVisualCollisionManager;
|
||||
}
|
||||
|
||||
namespace NLPACS {
|
||||
class UMoveContainer;
|
||||
class UGlobalRetriever;
|
||||
}
|
||||
|
||||
namespace NLSOUND {
|
||||
class UAudioMixer;
|
||||
class CSoundAnimManager;
|
||||
}
|
||||
|
||||
namespace NLQT {
|
||||
class CCommandLogDisplayer;
|
||||
class CErrorList;
|
||||
}
|
||||
|
||||
class CGraphicsViewport;
|
||||
class CGraphicsConfig;
|
||||
|
||||
/**
|
||||
* CMainWindow
|
||||
* \brief CMainWindow
|
||||
* \date 2010-02-05 13:01GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CMainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
|
||||
virtual ~CMainWindow();
|
||||
|
||||
virtual void setVisible(bool visible);
|
||||
|
||||
private slots:
|
||||
void applyGraphicsConfig();
|
||||
// void applySoundConfig();
|
||||
|
||||
void about();
|
||||
void updateRender();
|
||||
void printDebug();
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent *e);
|
||||
|
||||
private:
|
||||
void updateInitialization(bool visible);
|
||||
|
||||
void initProjectConfig(const std::string &asset);
|
||||
|
||||
void createActions();
|
||||
void translateActions();
|
||||
void createMenus();
|
||||
void translateMenus();
|
||||
void createToolBars();
|
||||
void translateToolBars();
|
||||
void createStatusBar();
|
||||
void createDockWindows();
|
||||
void translateDockWindows();
|
||||
|
||||
void recalculateMinimumWidth();
|
||||
|
||||
void cfcbSoundEnabled(NLMISC::CConfigFile::CVar &var);
|
||||
|
||||
void cfcbLanguageCode(NLMISC::CConfigFile::CVar &var);
|
||||
|
||||
private:
|
||||
CMainWindow(const CMainWindow &);
|
||||
CMainWindow &operator=(const CMainWindow &);
|
||||
|
||||
private:
|
||||
CConfiguration m_Configuration;
|
||||
CSoundUtilities m_SoundUtilities;
|
||||
|
||||
QUndoStack *m_UndoStack;
|
||||
|
||||
bool m_IsExiting;
|
||||
bool m_IsGraphicsInitialized, m_IsGraphicsEnabled;
|
||||
bool m_IsSoundInitialized, m_IsSoundEnabled;
|
||||
|
||||
QTimer *m_Timer;
|
||||
CGraphicsViewport *m_GraphicsViewport;
|
||||
|
||||
NLQT::CCommandLogDisplayer *m_CommandLog;
|
||||
QDockWidget *m_CommandLogDock;
|
||||
|
||||
NLQT::CErrorList *m_ErrorList;
|
||||
QDockWidget *m_ErrorListDock;
|
||||
|
||||
CGraphicsConfig *m_GraphicsConfig;
|
||||
QScrollArea *m_GraphicsConfigScroll;
|
||||
QDockWidget *m_GraphicsConfigDock;
|
||||
|
||||
QTreeView *m_AssetTreeView;
|
||||
QDirModel *m_AssetTreeModel;
|
||||
QDockWidget *m_AssetTreeDock;
|
||||
|
||||
QMenu *m_FileMenu;
|
||||
QMenu *m_EditMenu;
|
||||
QMenu *m_ViewportMenu;
|
||||
QMenu *m_WidgetsMenu;
|
||||
QMenu *m_HelpMenu;
|
||||
|
||||
QToolBar *m_FileToolBar;
|
||||
QToolBar *m_EditToolBar;
|
||||
|
||||
QAction *m_AboutAct;
|
||||
QAction *m_QuitAct;
|
||||
QAction *m_PrintDebugAct;
|
||||
QAction *m_UndoAct;
|
||||
QAction *m_RedoAct;
|
||||
QAction *m_SaveScreenshotAct;
|
||||
|
||||
//NLMISC::CConfigFile *ConfigFile; // owned by CConfiguration
|
||||
//CLoadingScreen LoadingScreen; // owned by CLoading (special case, always available)
|
||||
//NL3D::UDriver *Driver; // owned by CGraphics
|
||||
//NL3D::UTextContext *TextContext; // owned by CGraphics
|
||||
//NLSOUND::UAudioMixer *AudioMixer; // owned by CSound
|
||||
//NLSOUND::CSoundAnimManager *SoundAnimManager; // owned by CSound
|
||||
//THCOMMON::CSheetLoader *SheetLoader; // owned by initSheets and releaseSheets
|
||||
//NL3D::UScene *Scene; // owned by CEnvironment
|
||||
//NLPACS::UMoveContainer *MoveContainer; // owned by CEnvironment
|
||||
//NLPACS::UGlobalRetriever *GlobalRetriever; /// The global retriever used for pacs // owned by CEnvironment
|
||||
//NL3D::UVisualCollisionManager *VisualCollisionManager; /// The collision manager for ground snapping // owned by CEnvironment
|
||||
//THCLIENT::CKeyBinder *KeyBinder; // owned by CInterface
|
||||
|
||||
//NLMISC::TLocalTime LocalTime; // use for delta only // owned by CGameTime
|
||||
//NLMISC::TLocalTime LocalTimeDelta; // owned by CGameTime
|
||||
//NL3D::TGlobalAnimationTime AnimationTime; // owned by CGameTime
|
||||
//NL3D::TAnimationTime AnimationTimeDelta; // owned by CGameTime
|
||||
//float FramesPerSecond; // owned by CGameTime
|
||||
//float FramesPerSecondSmooth; // owned by CGameTime
|
||||
|
||||
//NLMISC::CVector DetailTargetPosition; // player or camera position for lod improvements // owned by camera
|
||||
|
||||
}; /* class CMainWindow */
|
||||
|
||||
#endif /* #ifndef NLQT_MAIN_WINDOW_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,952 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of a Qt Solutions component.
|
||||
**
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Solutions Commercial License Agreement provided
|
||||
** with the Software or, alternatively, in accordance with the terms
|
||||
** contained in a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain
|
||||
** additional rights. These rights are described in the Nokia Qt LGPL
|
||||
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
|
||||
** package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Please note Third Party Software included with Qt Solutions may impose
|
||||
** additional restrictions and it is the user's responsibility to ensure
|
||||
** that they have met the licensing requirements of the GPL, LGPL, or Qt
|
||||
** Solutions Commercial license and the relevant license of the Third
|
||||
** Party Software they are using.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact Nokia at qt-info@nokia.com.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qtcolorpicker_p.h"
|
||||
|
||||
/*!
|
||||
Constructs a QtColorPicker widget. The popup will display a grid
|
||||
with \a cols columns, or if \a cols is -1, the number of columns
|
||||
will be calculated automatically.
|
||||
|
||||
If \a enableColorDialog is true, the popup will also have a "More"
|
||||
button (signified by an ellipsis "...") that presents a
|
||||
QColorDialog when clicked.
|
||||
|
||||
After constructing a QtColorPicker, call insertColor() to add
|
||||
individual colors to the popup grid, or call setStandardColors()
|
||||
to add all the standard colors in one go.
|
||||
|
||||
The \a parent argument is passed to QFrame's constructor.
|
||||
|
||||
\sa QFrame
|
||||
*/
|
||||
QtColorPicker::QtColorPicker(QWidget *parent,
|
||||
int cols, bool enableColorDialog)
|
||||
: QPushButton(parent), popup(0), withColorDialog(enableColorDialog)
|
||||
{
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
setAutoDefault(false);
|
||||
setAutoFillBackground(true);
|
||||
setCheckable(true);
|
||||
|
||||
// Set text
|
||||
setText(tr("Black"));
|
||||
firstInserted = false;
|
||||
|
||||
// Create and set icon
|
||||
col = Qt::black;
|
||||
dirty = true;
|
||||
|
||||
// Create color grid popup and connect to it.
|
||||
popup = new ColorPickerPopup(cols, withColorDialog, this);
|
||||
connect(popup, SIGNAL(selected(const QColor &)),
|
||||
SLOT(setCurrentColor(const QColor &)));
|
||||
connect(popup, SIGNAL(hid()), SLOT(popupClosed()));
|
||||
|
||||
// Connect this push button's pressed() signal.
|
||||
connect(this, SIGNAL(toggled(bool)), SLOT(buttonPressed(bool)));
|
||||
}
|
||||
|
||||
/*!
|
||||
Destructs the QtColorPicker.
|
||||
*/
|
||||
QtColorPicker::~QtColorPicker()
|
||||
{
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
Pops up the color grid, and makes sure the status of
|
||||
QtColorPicker's button is right.
|
||||
*/
|
||||
void QtColorPicker::buttonPressed(bool toggled)
|
||||
{
|
||||
if (!toggled)
|
||||
return;
|
||||
|
||||
const QRect desktop = QApplication::desktop()->geometry();
|
||||
// Make sure the popup is inside the desktop.
|
||||
QPoint pos = mapToGlobal(rect().bottomLeft());
|
||||
if (pos.x() < desktop.left())
|
||||
pos.setX(desktop.left());
|
||||
if (pos.y() < desktop.top())
|
||||
pos.setY(desktop.top());
|
||||
|
||||
if ((pos.x() + popup->sizeHint().width()) > desktop.width())
|
||||
pos.setX(desktop.width() - popup->sizeHint().width());
|
||||
if ((pos.y() + popup->sizeHint().height()) > desktop.bottom())
|
||||
pos.setY(desktop.bottom() - popup->sizeHint().height());
|
||||
popup->move(pos);
|
||||
|
||||
if (ColorPickerItem *item = popup->find(col))
|
||||
item->setSelected(true);
|
||||
|
||||
// Remove focus from this widget, preventing the focus rect
|
||||
// from showing when the popup is shown. Order an update to
|
||||
// make sure the focus rect is cleared.
|
||||
clearFocus();
|
||||
update();
|
||||
|
||||
// Allow keyboard navigation as soon as the popup shows.
|
||||
popup->setFocus();
|
||||
|
||||
// Execute the popup. The popup will enter the event loop.
|
||||
popup->show();
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
void QtColorPicker::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
if (dirty) {
|
||||
int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize);
|
||||
QPixmap pix(iconSize, iconSize);
|
||||
pix.fill(palette().button().color());
|
||||
|
||||
QPainter p(&pix);
|
||||
|
||||
int w = pix.width(); // width of cell in pixels
|
||||
int h = pix.height(); // height of cell in pixels
|
||||
p.setPen(QPen(Qt::gray));
|
||||
p.setBrush(col);
|
||||
p.drawRect(2, 2, w - 5, h - 5);
|
||||
setIcon(QIcon(pix));
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
QPushButton::paintEvent(e);
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
Makes sure the button isn't pressed when the popup hides.
|
||||
*/
|
||||
void QtColorPicker::popupClosed()
|
||||
{
|
||||
setChecked(false);
|
||||
setFocus();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the currently selected color.
|
||||
|
||||
\sa text()
|
||||
*/
|
||||
QColor QtColorPicker::currentColor() const
|
||||
{
|
||||
return col;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the color at position \a index.
|
||||
*/
|
||||
QColor QtColorPicker::color(int index) const
|
||||
{
|
||||
return popup->color(index);
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds the 17 predefined colors from the Qt namespace.
|
||||
|
||||
(The names given to the colors, "Black", "White", "Red", etc., are
|
||||
all translatable.)
|
||||
|
||||
\sa insertColor()
|
||||
*/
|
||||
void QtColorPicker::setStandardColors()
|
||||
{
|
||||
insertColor(Qt::black, tr("Black"));
|
||||
insertColor(Qt::white, tr("White"));
|
||||
insertColor(Qt::red, tr("Red"));
|
||||
insertColor(Qt::darkRed, tr("Dark red"));
|
||||
insertColor(Qt::green, tr("Green"));
|
||||
insertColor(Qt::darkGreen, tr("Dark green"));
|
||||
insertColor(Qt::blue, tr("Blue"));
|
||||
insertColor(Qt::darkBlue, tr("Dark blue"));
|
||||
insertColor(Qt::cyan, tr("Cyan"));
|
||||
insertColor(Qt::darkCyan, tr("Dark cyan"));
|
||||
insertColor(Qt::magenta, tr("Magenta"));
|
||||
insertColor(Qt::darkMagenta, tr("Dark magenta"));
|
||||
insertColor(Qt::yellow, tr("Yellow"));
|
||||
insertColor(Qt::darkYellow, tr("Dark yellow"));
|
||||
insertColor(Qt::gray, tr("Gray"));
|
||||
insertColor(Qt::darkGray, tr("Dark gray"));
|
||||
insertColor(Qt::lightGray, tr("Light gray"));
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Makes \a color current. If \a color is not already in the color grid, it
|
||||
is inserted with the text "Custom".
|
||||
|
||||
This function emits the colorChanged() signal if the new color is
|
||||
valid, and different from the old one.
|
||||
*/
|
||||
void QtColorPicker::setCurrentColor(const QColor &color)
|
||||
{
|
||||
if (col == color || !color.isValid())
|
||||
return;
|
||||
|
||||
ColorPickerItem *item = popup->find(color);
|
||||
if (!item) {
|
||||
insertColor(color, tr("Custom"));
|
||||
item = popup->find(color);
|
||||
}
|
||||
|
||||
col = color;
|
||||
setText(item->text());
|
||||
|
||||
dirty = true;
|
||||
|
||||
popup->hide();
|
||||
repaint();
|
||||
|
||||
item->setSelected(true);
|
||||
emit colorChanged(color);
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds the color \a color with the name \a text to the color grid,
|
||||
at position \a index. If index is -1, the color is assigned
|
||||
automatically assigned a position, starting from left to right,
|
||||
top to bottom.
|
||||
*/
|
||||
void QtColorPicker::insertColor(const QColor &color, const QString &text, int index)
|
||||
{
|
||||
popup->insertColor(color, text, index);
|
||||
if (!firstInserted) {
|
||||
col = color;
|
||||
setText(text);
|
||||
firstInserted = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*! \property QtColorPicker::colorDialog
|
||||
\brief Whether the ellipsis "..." (more) button is available.
|
||||
|
||||
If this property is set to TRUE, the color grid popup will include
|
||||
a "More" button (signified by an ellipsis, "...") which pops up a
|
||||
QColorDialog when clicked. The user will then be able to select
|
||||
any custom color they like.
|
||||
*/
|
||||
void QtColorPicker::setColorDialogEnabled(bool enabled)
|
||||
{
|
||||
withColorDialog = enabled;
|
||||
}
|
||||
bool QtColorPicker::colorDialogEnabled() const
|
||||
{
|
||||
return withColorDialog;
|
||||
}
|
||||
|
||||
/*!
|
||||
Pops up a color grid with Qt default colors at \a point, using
|
||||
global coordinates. If \a allowCustomColors is true, there will
|
||||
also be a button on the popup that invokes QColorDialog.
|
||||
|
||||
For example:
|
||||
|
||||
\code
|
||||
void Drawer::mouseReleaseEvent(QMouseEvent *e)
|
||||
{
|
||||
if (e->button() & RightButton) {
|
||||
QColor color = QtColorPicker::getColor(mapToGlobal(e->pos()));
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
QColor QtColorPicker::getColor(const QPoint &point, bool allowCustomColors)
|
||||
{
|
||||
ColorPickerPopup popup(-1, allowCustomColors);
|
||||
|
||||
popup.insertColor(Qt::black, tr("Black"), 0);
|
||||
popup.insertColor(Qt::white, tr("White"), 1);
|
||||
popup.insertColor(Qt::red, tr("Red"), 2);
|
||||
popup.insertColor(Qt::darkRed, tr("Dark red"), 3);
|
||||
popup.insertColor(Qt::green, tr("Green"), 4);
|
||||
popup.insertColor(Qt::darkGreen, tr("Dark green"), 5);
|
||||
popup.insertColor(Qt::blue, tr("Blue"), 6);
|
||||
popup.insertColor(Qt::darkBlue, tr("Dark blue"), 7);
|
||||
popup.insertColor(Qt::cyan, tr("Cyan"), 8);
|
||||
popup.insertColor(Qt::darkCyan, tr("Dark cyan"), 9);
|
||||
popup.insertColor(Qt::magenta, tr("Magenta"), 10);
|
||||
popup.insertColor(Qt::darkMagenta, tr("Dark magenta"), 11);
|
||||
popup.insertColor(Qt::yellow, tr("Yellow"), 12);
|
||||
popup.insertColor(Qt::darkYellow, tr("Dark yellow"), 13);
|
||||
popup.insertColor(Qt::gray, tr("Gray"), 14);
|
||||
popup.insertColor(Qt::darkGray, tr("Dark gray"), 15);
|
||||
popup.insertColor(Qt::lightGray, tr("Light gray"), 16);
|
||||
|
||||
popup.move(point);
|
||||
popup.exec();
|
||||
return popup.lastSelected();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
Constructs the popup widget.
|
||||
*/
|
||||
ColorPickerPopup::ColorPickerPopup(int width, bool withColorDialog,
|
||||
QWidget *parent)
|
||||
: QFrame(parent, Qt::Popup)
|
||||
{
|
||||
setFrameStyle(QFrame::StyledPanel);
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setMouseTracking(true);
|
||||
cols = width;
|
||||
|
||||
if (withColorDialog)
|
||||
{
|
||||
moreButton = new ColorPickerButton(this);
|
||||
moreButton->setFixedWidth(24);
|
||||
moreButton->setFixedHeight(21);
|
||||
moreButton->setFrameRect(QRect(2, 2, 20, 17));
|
||||
connect(moreButton, SIGNAL(clicked()), SLOT(getColorFromDialog()));
|
||||
}
|
||||
else
|
||||
{
|
||||
moreButton = 0;
|
||||
}
|
||||
|
||||
eventLoop = 0;
|
||||
grid = 0;
|
||||
regenerateGrid();
|
||||
}
|
||||
|
||||
|
||||
/*! \internal
|
||||
|
||||
Destructs the popup widget.
|
||||
*/
|
||||
ColorPickerPopup::~ColorPickerPopup()
|
||||
{
|
||||
if (eventLoop)
|
||||
eventLoop->exit();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
If there is an item whole color is equal to \a col, returns a
|
||||
pointer to this item; otherwise returns 0.
|
||||
*/
|
||||
ColorPickerItem *ColorPickerPopup::find(const QColor &col) const
|
||||
{
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
if (items.at(i) && items.at(i)->color() == col)
|
||||
return items.at(i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
Adds \a item to the grid. The items are added from top-left to
|
||||
bottom-right.
|
||||
*/
|
||||
void ColorPickerPopup::insertColor(const QColor &col, const QString &text, int index)
|
||||
{
|
||||
// Don't add colors that we have already.
|
||||
ColorPickerItem *existingItem = find(col);
|
||||
ColorPickerItem *lastSelectedItem = find(lastSelected());
|
||||
|
||||
if (existingItem) {
|
||||
if (lastSelectedItem && existingItem != lastSelectedItem)
|
||||
lastSelectedItem->setSelected(false);
|
||||
existingItem->setFocus();
|
||||
existingItem->setSelected(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ColorPickerItem *item = new ColorPickerItem(col, text, this);
|
||||
|
||||
if (lastSelectedItem) {
|
||||
lastSelectedItem->setSelected(false);
|
||||
}
|
||||
else {
|
||||
item->setSelected(true);
|
||||
lastSel = col;
|
||||
}
|
||||
item->setFocus();
|
||||
|
||||
connect(item, SIGNAL(selected()), SLOT(updateSelected()));
|
||||
|
||||
if (index == -1)
|
||||
index = items.count();
|
||||
|
||||
items.insert((unsigned int)index, item);
|
||||
regenerateGrid();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
*/
|
||||
QColor ColorPickerPopup::color(int index) const
|
||||
{
|
||||
if (index < 0 || index > (int) items.count() - 1)
|
||||
return QColor();
|
||||
|
||||
ColorPickerPopup *that = (ColorPickerPopup *)this;
|
||||
return that->items.at(index)->color();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
*/
|
||||
void ColorPickerPopup::exec()
|
||||
{
|
||||
show();
|
||||
|
||||
QEventLoop e;
|
||||
eventLoop = &e;
|
||||
(void) e.exec();
|
||||
eventLoop = 0;
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
*/
|
||||
void ColorPickerPopup::updateSelected()
|
||||
{
|
||||
QLayoutItem *layoutItem;
|
||||
int i = 0;
|
||||
while ((layoutItem = grid->itemAt(i)) != 0) {
|
||||
QWidget *w = layoutItem->widget();
|
||||
if (w && w->inherits("ColorPickerItem")) {
|
||||
ColorPickerItem *litem = reinterpret_cast<ColorPickerItem *>(layoutItem->widget());
|
||||
if (litem != sender())
|
||||
litem->setSelected(false);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (sender() && sender()->inherits("ColorPickerItem")) {
|
||||
ColorPickerItem *item = (ColorPickerItem *)sender();
|
||||
lastSel = item->color();
|
||||
emit selected(item->color());
|
||||
}
|
||||
|
||||
hide();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
*/
|
||||
void ColorPickerPopup::mouseReleaseEvent(QMouseEvent *e)
|
||||
{
|
||||
if (!rect().contains(e->pos()))
|
||||
hide();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
Controls keyboard navigation and selection on the color grid.
|
||||
*/
|
||||
void ColorPickerPopup::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
int curRow = 0;
|
||||
int curCol = 0;
|
||||
|
||||
bool foundFocus = false;
|
||||
for (int j = 0; !foundFocus && j < grid->rowCount(); ++j) {
|
||||
for (int i = 0; !foundFocus && i < grid->columnCount(); ++i) {
|
||||
if (widgetAt[j][i] && widgetAt[j][i]->hasFocus()) {
|
||||
curRow = j;
|
||||
curCol = i;
|
||||
foundFocus = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (e->key()) {
|
||||
case Qt::Key_Left:
|
||||
if (curCol > 0) --curCol;
|
||||
else if (curRow > 0) { --curRow; curCol = grid->columnCount() - 1; }
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
if (curCol < grid->columnCount() - 1 && widgetAt[curRow][curCol + 1]) ++curCol;
|
||||
else if (curRow < grid->rowCount() - 1) { ++curRow; curCol = 0; }
|
||||
break;
|
||||
case Qt::Key_Up:
|
||||
if (curRow > 0) --curRow;
|
||||
else curCol = 0;
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
if (curRow < grid->rowCount() - 1) {
|
||||
QWidget *w = widgetAt[curRow + 1][curCol];
|
||||
if (w) {
|
||||
++curRow;
|
||||
} else for (int i = 1; i < grid->columnCount(); ++i) {
|
||||
if (!widgetAt[curRow + 1][i]) {
|
||||
curCol = i - 1;
|
||||
++curRow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Space:
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter: {
|
||||
QWidget *w = widgetAt[curRow][curCol];
|
||||
if (w && w->inherits("ColorPickerItem")) {
|
||||
ColorPickerItem *wi = reinterpret_cast<ColorPickerItem *>(w);
|
||||
wi->setSelected(true);
|
||||
|
||||
QLayoutItem *layoutItem;
|
||||
int i = 0;
|
||||
while ((layoutItem = grid->itemAt(i)) != 0) {
|
||||
QWidget *w = layoutItem->widget();
|
||||
if (w && w->inherits("ColorPickerItem")) {
|
||||
ColorPickerItem *litem
|
||||
= reinterpret_cast<ColorPickerItem *>(layoutItem->widget());
|
||||
if (litem != wi)
|
||||
litem->setSelected(false);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
lastSel = wi->color();
|
||||
emit selected(wi->color());
|
||||
hide();
|
||||
} else if (w && w->inherits("QPushButton")) {
|
||||
ColorPickerItem *wi = reinterpret_cast<ColorPickerItem *>(w);
|
||||
wi->setSelected(true);
|
||||
|
||||
QLayoutItem *layoutItem;
|
||||
int i = 0;
|
||||
while ((layoutItem = grid->itemAt(i)) != 0) {
|
||||
QWidget *w = layoutItem->widget();
|
||||
if (w && w->inherits("ColorPickerItem")) {
|
||||
ColorPickerItem *litem
|
||||
= reinterpret_cast<ColorPickerItem *>(layoutItem->widget());
|
||||
if (litem != wi)
|
||||
litem->setSelected(false);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
lastSel = wi->color();
|
||||
emit selected(wi->color());
|
||||
hide();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Escape:
|
||||
hide();
|
||||
break;
|
||||
default:
|
||||
e->ignore();
|
||||
break;
|
||||
}
|
||||
|
||||
widgetAt[curRow][curCol]->setFocus();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
*/
|
||||
void ColorPickerPopup::hideEvent(QHideEvent *e)
|
||||
{
|
||||
if (eventLoop) {
|
||||
eventLoop->exit();
|
||||
}
|
||||
|
||||
setFocus();
|
||||
|
||||
emit hid();
|
||||
QFrame::hideEvent(e);
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
*/
|
||||
QColor ColorPickerPopup::lastSelected() const
|
||||
{
|
||||
return lastSel;
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
Sets focus on the popup to enable keyboard navigation. Draws
|
||||
focusRect and selection rect.
|
||||
*/
|
||||
void ColorPickerPopup::showEvent(QShowEvent *)
|
||||
{
|
||||
bool foundSelected = false;
|
||||
for (int i = 0; i < grid->columnCount(); ++i) {
|
||||
for (int j = 0; j < grid->rowCount(); ++j) {
|
||||
QWidget *w = widgetAt[j][i];
|
||||
if (w && w->inherits("ColorPickerItem")) {
|
||||
if (((ColorPickerItem *)w)->isSelected()) {
|
||||
w->setFocus();
|
||||
foundSelected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundSelected) {
|
||||
if (items.count() == 0)
|
||||
setFocus();
|
||||
else
|
||||
widgetAt[0][0]->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerPopup::regenerateGrid()
|
||||
{
|
||||
widgetAt.clear();
|
||||
|
||||
int columns = cols;
|
||||
if (columns == -1)
|
||||
columns = (int) ceil(sqrt((float) items.count()));
|
||||
|
||||
// When the number of columns grows, the number of rows will
|
||||
// fall. There's no way to shrink a grid, so we create a new
|
||||
// one.
|
||||
if (grid) delete grid;
|
||||
grid = new QGridLayout(this);
|
||||
grid->setMargin(1);
|
||||
grid->setSpacing(0);
|
||||
|
||||
int ccol = 0, crow = 0;
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
if (items.at(i)) {
|
||||
widgetAt[crow][ccol] = items.at(i);
|
||||
grid->addWidget(items.at(i), crow, ccol++);
|
||||
if (ccol == columns) {
|
||||
++crow;
|
||||
ccol = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (moreButton) {
|
||||
grid->addWidget(moreButton, crow, ccol);
|
||||
widgetAt[crow][ccol] = moreButton;
|
||||
}
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
|
||||
Copies the color dialog's currently selected item and emits
|
||||
itemSelected().
|
||||
*/
|
||||
void ColorPickerPopup::getColorFromDialog()
|
||||
{
|
||||
bool ok;
|
||||
QRgb rgb = QColorDialog::getRgba(lastSel.rgba(), &ok, parentWidget());
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
QColor col = QColor::fromRgba(rgb);
|
||||
insertColor(col, tr("Custom"), -1);
|
||||
lastSel = col;
|
||||
emit selected(col);
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a ColorPickerItem whose color is set to \a color, and
|
||||
whose name is set to \a text.
|
||||
*/
|
||||
ColorPickerItem::ColorPickerItem(const QColor &color, const QString &text,
|
||||
QWidget *parent)
|
||||
: QFrame(parent), c(color), t(text), sel(false)
|
||||
{
|
||||
setToolTip(t);
|
||||
setFixedWidth(24);
|
||||
setFixedHeight(21);
|
||||
}
|
||||
|
||||
/*!
|
||||
Destructs a ColorPickerItem.
|
||||
*/
|
||||
ColorPickerItem::~ColorPickerItem()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the item's color.
|
||||
|
||||
\sa text()
|
||||
*/
|
||||
QColor ColorPickerItem::color() const
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the item's text.
|
||||
|
||||
\sa color()
|
||||
*/
|
||||
QString ColorPickerItem::text() const
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
bool ColorPickerItem::isSelected() const
|
||||
{
|
||||
return sel;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerItem::setSelected(bool selected)
|
||||
{
|
||||
sel = selected;
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the item's color to \a color, and its name to \a text.
|
||||
*/
|
||||
void ColorPickerItem::setColor(const QColor &color, const QString &text)
|
||||
{
|
||||
c = color;
|
||||
t = text;
|
||||
setToolTip(t);
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerItem::mouseMoveEvent(QMouseEvent *)
|
||||
{
|
||||
setFocus();
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerItem::mouseReleaseEvent(QMouseEvent *)
|
||||
{
|
||||
sel = true;
|
||||
emit selected();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerItem::mousePressEvent(QMouseEvent *)
|
||||
{
|
||||
setFocus();
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerItem::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter p(this);
|
||||
int w = width(); // width of cell in pixels
|
||||
int h = height(); // height of cell in pixels
|
||||
|
||||
p.setPen( QPen( Qt::gray, 0, Qt::SolidLine ) );
|
||||
|
||||
if (sel)
|
||||
p.drawRect(1, 1, w - 3, h - 3);
|
||||
|
||||
p.setPen( QPen( Qt::black, 0, Qt::SolidLine ) );
|
||||
p.drawRect(3, 3, w - 7, h - 7);
|
||||
p.fillRect(QRect(4, 4, w - 8, h - 8), QBrush(c));
|
||||
|
||||
if (hasFocus())
|
||||
p.drawRect(0, 0, w - 1, h - 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
ColorPickerButton::ColorPickerButton(QWidget *parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
setFrameStyle(StyledPanel);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerButton::mousePressEvent(QMouseEvent *)
|
||||
{
|
||||
setFrameShadow(Sunken);
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerButton::mouseMoveEvent(QMouseEvent *)
|
||||
{
|
||||
setFocus();
|
||||
update();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerButton::mouseReleaseEvent(QMouseEvent *)
|
||||
{
|
||||
setFrameShadow(Raised);
|
||||
repaint();
|
||||
emit clicked();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerButton::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
if (e->key() == Qt::Key_Up
|
||||
|| e->key() == Qt::Key_Down
|
||||
|| e->key() == Qt::Key_Left
|
||||
|| e->key() == Qt::Key_Right)
|
||||
{
|
||||
qApp->sendEvent(parent(), e);
|
||||
}
|
||||
else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Space || e->key() == Qt::Key_Return)
|
||||
{
|
||||
setFrameShadow(Sunken);
|
||||
update();
|
||||
}
|
||||
else
|
||||
{
|
||||
QFrame::keyPressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerButton::keyReleaseEvent(QKeyEvent *e)
|
||||
{
|
||||
if (e->key() == Qt::Key_Up
|
||||
|| e->key() == Qt::Key_Down
|
||||
|| e->key() == Qt::Key_Left
|
||||
|| e->key() == Qt::Key_Right)
|
||||
{
|
||||
qApp->sendEvent(parent(), e);
|
||||
}
|
||||
else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Space || e->key() == Qt::Key_Return)
|
||||
{
|
||||
setFrameShadow(Raised);
|
||||
repaint();
|
||||
emit clicked();
|
||||
}
|
||||
else
|
||||
{
|
||||
QFrame::keyReleaseEvent(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerButton::focusInEvent(QFocusEvent *e)
|
||||
{
|
||||
setFrameShadow(Raised);
|
||||
update();
|
||||
QFrame::focusOutEvent(e);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerButton::focusOutEvent(QFocusEvent *e)
|
||||
{
|
||||
setFrameShadow(Raised);
|
||||
update();
|
||||
QFrame::focusOutEvent(e);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
void ColorPickerButton::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
QFrame::paintEvent(e);
|
||||
|
||||
QPainter p(this);
|
||||
p.fillRect(contentsRect(), palette().button());
|
||||
|
||||
QRect r = rect();
|
||||
|
||||
int offset = frameShadow() == Sunken ? 1 : 0;
|
||||
|
||||
QPen pen(palette().buttonText(), 1);
|
||||
p.setPen(pen);
|
||||
|
||||
p.drawRect(r.center().x() + offset - 4, r.center().y() + offset, 1, 1);
|
||||
p.drawRect(r.center().x() + offset , r.center().y() + offset, 1, 1);
|
||||
p.drawRect(r.center().x() + offset + 4, r.center().y() + offset, 1, 1);
|
||||
if (hasFocus()) {
|
||||
p.setPen( QPen( Qt::black, 0, Qt::SolidLine ) );
|
||||
p.drawRect(0, 0, width() - 1, height() - 1);
|
||||
}
|
||||
|
||||
p.end();
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of a Qt Solutions component.
|
||||
**
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Solutions Commercial License Agreement provided
|
||||
** with the Software or, alternatively, in accordance with the terms
|
||||
** contained in a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain
|
||||
** additional rights. These rights are described in the Nokia Qt LGPL
|
||||
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
|
||||
** package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Please note Third Party Software included with Qt Solutions may impose
|
||||
** additional restrictions and it is the user's responsibility to ensure
|
||||
** that they have met the licensing requirements of the GPL, LGPL, or Qt
|
||||
** Solutions Commercial license and the relevant license of the Third
|
||||
** Party Software they are using.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact Nokia at qt-info@nokia.com.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTCOLORPICKER_H
|
||||
#define QTCOLORPICKER_H
|
||||
#include <QPushButton>
|
||||
#include <QString>
|
||||
#include <QColor>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QEvent>
|
||||
#include <QFocusEvent>
|
||||
|
||||
#define QT_QTCOLORPICKER_EXPORT
|
||||
|
||||
class ColorPickerPopup;
|
||||
|
||||
class QT_QTCOLORPICKER_EXPORT QtColorPicker : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool colorDialog READ colorDialogEnabled WRITE setColorDialogEnabled)
|
||||
|
||||
public:
|
||||
QtColorPicker(QWidget *parent = 0,
|
||||
int columns = -1, bool enableColorDialog = true);
|
||||
|
||||
~QtColorPicker();
|
||||
|
||||
void insertColor(const QColor &color, const QString &text = QString::null, int index = -1);
|
||||
|
||||
QColor currentColor() const;
|
||||
|
||||
QColor color(int index) const;
|
||||
|
||||
void setColorDialogEnabled(bool enabled);
|
||||
bool colorDialogEnabled() const;
|
||||
|
||||
void setStandardColors();
|
||||
|
||||
static QColor getColor(const QPoint &pos, bool allowCustomColors = true);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setCurrentColor(const QColor &col);
|
||||
|
||||
Q_SIGNALS:
|
||||
void colorChanged(const QColor &);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
private Q_SLOTS:
|
||||
void buttonPressed(bool toggled);
|
||||
void popupClosed();
|
||||
|
||||
private:
|
||||
ColorPickerPopup *popup;
|
||||
QColor col;
|
||||
bool withColorDialog;
|
||||
bool dirty;
|
||||
bool firstInserted;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,251 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of a Qt Solutions component.
|
||||
**
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Solutions Commercial License Agreement provided
|
||||
** with the Software or, alternatively, in accordance with the terms
|
||||
** contained in a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain
|
||||
** additional rights. These rights are described in the Nokia Qt LGPL
|
||||
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
|
||||
** package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Please note Third Party Software included with Qt Solutions may impose
|
||||
** additional restrictions and it is the user's responsibility to ensure
|
||||
** that they have met the licensing requirements of the GPL, LGPL, or Qt
|
||||
** Solutions Commercial license and the relevant license of the Third
|
||||
** Party Software they are using.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact Nokia at qt-info@nokia.com.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QColorDialog>
|
||||
#include <QMap>
|
||||
#include <QLayout>
|
||||
#include <QStyle>
|
||||
#include <QLabel>
|
||||
#include <QToolTip>
|
||||
#include <QPixmap>
|
||||
#include <QFocusEvent>
|
||||
#include <QPaintEvent>
|
||||
#include <QGridLayout>
|
||||
#include <QHideEvent>
|
||||
#include <QKeyEvent>
|
||||
#include <QShowEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <math.h>
|
||||
|
||||
#include "qtcolorpicker.h"
|
||||
|
||||
/*! \class QtColorPicker
|
||||
|
||||
\brief The QtColorPicker class provides a widget for selecting
|
||||
colors from a popup color grid.
|
||||
|
||||
Users can invoke the color picker by clicking on it, or by
|
||||
navigating to it and pressing Space. They can use the mouse or
|
||||
arrow keys to navigate between colors on the grid, and select a
|
||||
color by clicking or by pressing Enter or Space. The
|
||||
colorChanged() signal is emitted whenever the color picker's color
|
||||
changes.
|
||||
|
||||
The widget also supports negative selection: Users can click and
|
||||
hold the mouse button on the QtColorPicker widget, then move the
|
||||
mouse over the color grid and release the mouse button over the
|
||||
color they wish to select.
|
||||
|
||||
The color grid shows a customized selection of colors. An optional
|
||||
ellipsis "..." button (signifying "more") can be added at the
|
||||
bottom of the grid; if the user presses this, a QColorDialog pops
|
||||
up and lets them choose any color they like. This button is made
|
||||
available by using setColorDialogEnabled().
|
||||
|
||||
When a color is selected, the QtColorPicker widget shows the color
|
||||
and its name. If the name cannot be determined, the translatable
|
||||
name "Custom" is used.
|
||||
|
||||
The QtColorPicker object is optionally initialized with the number
|
||||
of columns in the color grid. Colors are then added left to right,
|
||||
top to bottom using insertColor(). If the number of columns is not
|
||||
set, QtColorPicker calculates the number of columns and rows that
|
||||
will make the grid as square as possible.
|
||||
|
||||
\code
|
||||
DrawWidget::DrawWidget(QWidget *parent, const char *name)
|
||||
{
|
||||
QtColorPicker *picker = new QtColorPicker(this);
|
||||
picker->insertColor(red, "Red"));
|
||||
picker->insertColor(QColor("green"), "Green"));
|
||||
picker->insertColor(QColor(0, 0, 255), "Blue"));
|
||||
picker->insertColor(white);
|
||||
|
||||
connect(colors, SIGNAL(colorChanged(const QColor &)), SLOT(setCurrentColor(const QColor &)));
|
||||
}
|
||||
\endcode
|
||||
|
||||
An alternative to adding colors manually is to initialize the grid
|
||||
with QColorDialog's standard colors using setStandardColors().
|
||||
|
||||
QtColorPicker also provides a the static function getColor(),
|
||||
which pops up the grid of standard colors at any given point.
|
||||
|
||||
\img colorpicker1.png
|
||||
\img colorpicker2.png
|
||||
|
||||
\sa QColorDialog
|
||||
*/
|
||||
|
||||
/*! \fn QtColorPicker::colorChanged(const QColor &color)
|
||||
|
||||
This signal is emitted when the QtColorPicker's color is changed.
|
||||
\a color is the new color.
|
||||
|
||||
To obtain the color's name, use text().
|
||||
*/
|
||||
|
||||
/*
|
||||
A class that acts very much like a QPushButton. It's not styled,
|
||||
so we can expect the exact same look, feel and geometry
|
||||
everywhere. Also, this button always emits clicked on
|
||||
mouseRelease, even if the mouse button was not pressed inside the
|
||||
widget.
|
||||
*/
|
||||
class ColorPickerButton : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ColorPickerButton(QWidget *parent);
|
||||
|
||||
signals:
|
||||
void clicked();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void keyReleaseEvent(QKeyEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void focusInEvent(QFocusEvent *e);
|
||||
void focusOutEvent(QFocusEvent *e);
|
||||
};
|
||||
|
||||
/*
|
||||
This class represents each "color" or item in the color grid.
|
||||
*/
|
||||
class ColorPickerItem : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ColorPickerItem(const QColor &color = Qt::white, const QString &text = QString::null,
|
||||
QWidget *parent = 0);
|
||||
~ColorPickerItem();
|
||||
|
||||
QColor color() const;
|
||||
QString text() const;
|
||||
|
||||
void setSelected(bool);
|
||||
bool isSelected() const;
|
||||
signals:
|
||||
void clicked();
|
||||
void selected();
|
||||
|
||||
public slots:
|
||||
void setColor(const QColor &color, const QString &text = QString());
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
private:
|
||||
QColor c;
|
||||
QString t;
|
||||
bool sel;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
class ColorPickerPopup : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ColorPickerPopup(int width, bool withColorDialog,
|
||||
QWidget *parent = 0);
|
||||
~ColorPickerPopup();
|
||||
|
||||
void insertColor(const QColor &col, const QString &text, int index);
|
||||
void exec();
|
||||
|
||||
void setExecFlag();
|
||||
|
||||
QColor lastSelected() const;
|
||||
|
||||
ColorPickerItem *find(const QColor &col) const;
|
||||
QColor color(int index) const;
|
||||
|
||||
signals:
|
||||
void selected(const QColor &);
|
||||
void hid();
|
||||
|
||||
public slots:
|
||||
void getColorFromDialog();
|
||||
|
||||
protected slots:
|
||||
void updateSelected();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void showEvent(QShowEvent *e);
|
||||
void hideEvent(QHideEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
|
||||
void regenerateGrid();
|
||||
|
||||
private:
|
||||
QMap<int, QMap<int, QWidget *> > widgetAt;
|
||||
QList<ColorPickerItem *> items;
|
||||
QGridLayout *grid;
|
||||
ColorPickerButton *moreButton;
|
||||
QEventLoop *eventLoop;
|
||||
|
||||
int lastPos;
|
||||
int cols;
|
||||
QColor lastSel;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,170 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include "sound_utilities.h"
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
#include <nel/misc/hierarchical_timer.h>
|
||||
#include <nel/misc/config_file.h>
|
||||
#include <nel/sound/u_audio_mixer.h>
|
||||
#include <nel/sound/sound_anim_manager.h>
|
||||
#include <nel/misc/progress_callback.h>
|
||||
#include <nel/3d/u_particle_system_sound.h>
|
||||
|
||||
// Project includes
|
||||
#include "configuration.h"
|
||||
#include "graphics_viewport.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace NLMISC;
|
||||
using namespace NLSOUND;
|
||||
|
||||
CSoundUtilities::CSoundUtilities()
|
||||
: m_Configuration(NULL),
|
||||
m_GraphicsViewport(NULL),
|
||||
//m_LandscapeUtilities(NULL),
|
||||
//m_PacsUtilities(NULL),
|
||||
m_AudioMixer(NULL),
|
||||
m_SoundAnimManager(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CSoundUtilities::~CSoundUtilities()
|
||||
{
|
||||
// release();
|
||||
}
|
||||
|
||||
void CSoundUtilities::init(CConfiguration *configuration)
|
||||
{
|
||||
//H_AUTO2
|
||||
nldebug("CSoundUtilities::init");
|
||||
|
||||
// copy parameters
|
||||
m_Configuration = configuration;
|
||||
|
||||
// check stuff we need
|
||||
nlassert(m_Configuration);
|
||||
|
||||
// create audiomixer
|
||||
NL3D::UParticleSystemSound::setPSSound(NULL);
|
||||
nlassert(!m_AudioMixer);
|
||||
m_AudioMixer = UAudioMixer::createAudioMixer();
|
||||
nlassert(m_AudioMixer);
|
||||
|
||||
// init audiomixer
|
||||
std::vector<std::string> devices;
|
||||
m_AudioMixer->initDriver(m_Configuration->getValue("SoundDriver", string("Auto")));
|
||||
m_AudioMixer->getDevices(devices);
|
||||
UAudioMixer::CInitInfo audioInfo;
|
||||
audioInfo.AutoLoadSample = m_Configuration->getValue("SoundAutoLoadSample", true);
|
||||
audioInfo.EnableOccludeObstruct = m_Configuration->getValue("SoundEnableOccludeObstruct", true);
|
||||
audioInfo.EnableReverb = m_Configuration->getValue("SoundEnableReverb", true);
|
||||
audioInfo.ManualRolloff = m_Configuration->getValue("SoundManualRolloff", true);
|
||||
audioInfo.ForceSoftware = m_Configuration->getValue("SoundForceSoftware", false);
|
||||
audioInfo.MaxTrack = m_Configuration->getValue("SoundMaxTrack", 48);
|
||||
audioInfo.UseADPCM = m_Configuration->getValue("SoundUseADPCM", false);
|
||||
m_AudioMixer->initDevice(m_Configuration->getValue("SoundDevice", string("")), audioInfo, NULL);
|
||||
m_AudioMixer->setLowWaterMark(1);
|
||||
|
||||
// config callbacks
|
||||
// ...
|
||||
|
||||
// sound anim manager
|
||||
nlassert(!m_SoundAnimManager);
|
||||
m_SoundAnimManager = new CSoundAnimManager(m_AudioMixer);
|
||||
nlassert(m_SoundAnimManager);
|
||||
|
||||
// temp listener pos
|
||||
m_AudioMixer->setListenerPos(CVector(0.0f, 0.0f, 0.0f));
|
||||
|
||||
// init sources
|
||||
// ...
|
||||
}
|
||||
|
||||
void CSoundUtilities::release()
|
||||
{
|
||||
//H_AUTO2
|
||||
nldebug("CSoundUtilities::release");
|
||||
|
||||
// release sources
|
||||
// ...
|
||||
|
||||
// release sound anim manager
|
||||
if (m_SoundAnimManager)
|
||||
{
|
||||
delete m_SoundAnimManager;
|
||||
m_SoundAnimManager = NULL;
|
||||
}
|
||||
else nlwarning("!m_SoundAnimManager");
|
||||
|
||||
// drop config callbacks
|
||||
// ...
|
||||
|
||||
// release audiomixer (todo: +sources!!!)
|
||||
if (m_AudioMixer)
|
||||
{
|
||||
delete m_AudioMixer;
|
||||
m_AudioMixer = NULL;
|
||||
}
|
||||
else nlwarning("!m_AudioMixer");
|
||||
|
||||
// reset parameters
|
||||
m_Configuration = NULL;
|
||||
}
|
||||
|
||||
void CSoundUtilities::updateSound()
|
||||
{
|
||||
m_AudioMixer->update();
|
||||
}
|
||||
|
||||
void CSoundUtilities::initGraphics(CGraphicsViewport *graphicsViewport)
|
||||
{
|
||||
//H_AUTO2
|
||||
nldebug("CSoundUtilities::initGraphics");
|
||||
|
||||
// copy parameters
|
||||
m_GraphicsViewport = graphicsViewport;
|
||||
|
||||
// check stuff we need
|
||||
nlassert(m_GraphicsViewport);
|
||||
|
||||
// set particle system sound
|
||||
NL3D::UParticleSystemSound::setPSSound(m_AudioMixer);
|
||||
|
||||
// ...
|
||||
// todo: displayers for all the test sound sources :)
|
||||
}
|
||||
|
||||
void CSoundUtilities::releaseGraphics()
|
||||
{
|
||||
//H_AUTO2
|
||||
nldebug("CSoundUtilities::releaseGraphics");
|
||||
|
||||
// ..
|
||||
|
||||
// clear particle system sound
|
||||
NL3D::UParticleSystemSound::setPSSound(NULL);
|
||||
|
||||
// reset parameters
|
||||
m_GraphicsViewport = NULL;
|
||||
}
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,83 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef NLQT_SOUND_UTILITIES_H
|
||||
#define NLQT_SOUND_UTILITIES_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
|
||||
// Project includes
|
||||
|
||||
namespace NLSOUND {
|
||||
class UAudioMixer;
|
||||
class CSoundAnimManager;
|
||||
}
|
||||
|
||||
class CConfiguration;
|
||||
class CGraphicsViewport;
|
||||
//class CLandscapeUtilities;
|
||||
//class CPacsUtilities;
|
||||
|
||||
/**
|
||||
* CSoundUtilities
|
||||
* \brief CSoundUtilities
|
||||
* \date 2010-02-06 12:26GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CSoundUtilities
|
||||
{
|
||||
public:
|
||||
CSoundUtilities();
|
||||
virtual ~CSoundUtilities();
|
||||
|
||||
void init(CConfiguration *configuration);
|
||||
void release();
|
||||
|
||||
void initGraphics(CGraphicsViewport *graphicsViewport);
|
||||
void releaseGraphics();
|
||||
|
||||
//void initLandscape(CLandscapeUtilities *landscapeUtilities);
|
||||
//void releaseLandscape();
|
||||
|
||||
//void initPacs(CPacsUtilities *pacsUtilities);
|
||||
//void releasePacs();
|
||||
|
||||
void updateSound();
|
||||
|
||||
inline NLSOUND::UAudioMixer *getAudioMixer() { return m_AudioMixer; }
|
||||
inline NLSOUND::CSoundAnimManager *getSoundAnimManager() { return m_SoundAnimManager; }
|
||||
|
||||
private:
|
||||
CConfiguration *m_Configuration;
|
||||
CGraphicsViewport *m_GraphicsViewport;
|
||||
//CLandscapeUtilities *m_LandscapeUtilities;
|
||||
//CPacsUtilities *m_PacsUtilities;
|
||||
|
||||
NLSOUND::UAudioMixer *m_AudioMixer;
|
||||
NLSOUND::CSoundAnimManager *m_SoundAnimManager;
|
||||
|
||||
private:
|
||||
CSoundUtilities(const CSoundUtilities &);
|
||||
CSoundUtilities &operator=(const CSoundUtilities &);
|
||||
|
||||
}; /* class CSoundUtilities */
|
||||
|
||||
#endif /* #ifndef NLQT_SOUND_UTILITIES_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,200 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2016 Winch Gate Property Limited
|
||||
// Author: Jan Boon <jan.boon@kaetemi.be>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include "texture_browser.h"
|
||||
|
||||
// STL includes
|
||||
#include <functional>
|
||||
|
||||
// Qt includes
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QPixmap>
|
||||
#include <QListWidget>
|
||||
#include <QFileInfo>
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
#include <nel/misc/common.h>
|
||||
#include <nel/misc/bitmap.h>
|
||||
#include <nel/misc/file.h>
|
||||
#include <nel/misc/sha1.h>
|
||||
#include <nel/pipeline/project_config.h>
|
||||
|
||||
// Project includes
|
||||
#include "../shared_widgets/event_loop.h"
|
||||
|
||||
// See also: studio/.../gui_editor/texture_chooser.cpp
|
||||
|
||||
// UTILITY ->
|
||||
QImage qImageFromCBitmap(NLMISC::CBitmap &bitmap, bool alpha)
|
||||
{
|
||||
QImage img(bitmap.getWidth(), bitmap.getHeight(), alpha ? QImage::Format_ARGB32 : QImage::Format_RGB32);
|
||||
NLMISC::CObjectVector<uint8> &pixels = bitmap.getPixels();
|
||||
|
||||
uint height = bitmap.getHeight();
|
||||
uint stride = bitmap.getWidth() * sizeof(NLMISC::CRGBA);
|
||||
for (uint y = 0; y < height; ++y)
|
||||
{
|
||||
// memcpy(img.scanLine(y), &pixels[y * stride], stride);
|
||||
// Convert from ABGR to ARGB
|
||||
uint8 *dst = img.scanLine(y);
|
||||
uint8 *src = &pixels[y * stride];
|
||||
for (uint x = 0; x < stride; x += 4)
|
||||
{
|
||||
dst[x] = src[x + 2];
|
||||
dst[x + 1] = src[x + 1];
|
||||
dst[x + 2] = src[x];
|
||||
dst[x + 3] = src[x + 3];
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
// <- UTILITY
|
||||
|
||||
CTextureBrowser::CTextureBrowser(QWidget *parent) : QListWidget(parent)
|
||||
{
|
||||
qRegisterMetaType<CStdFunctionVoid>("CStdFunctionVoid");
|
||||
m_Thread = new CEventLoop();
|
||||
m_Thread->run();
|
||||
|
||||
setViewMode(QListWidget::IconMode);
|
||||
setIconSize(QSize(128, 128));
|
||||
setResizeMode(QListWidget::Adjust);
|
||||
|
||||
setGridSize(QSize(144, 160));
|
||||
|
||||
// setDirectory("W:/database/stuff/fyros/agents/_textures/actors/");
|
||||
}
|
||||
|
||||
CTextureBrowser::~CTextureBrowser()
|
||||
{
|
||||
m_Thread->clear();
|
||||
delete m_Thread;
|
||||
}
|
||||
|
||||
std::string CTextureBrowser::getSelectedTextureFile() const
|
||||
{
|
||||
std::string res;
|
||||
QList<QListWidgetItem *> items = selectedItems();
|
||||
if (items.size() > 0)
|
||||
res = items[0]->text().toUtf8().data();
|
||||
return res;
|
||||
}
|
||||
|
||||
void CTextureBrowser::setDirectory(const QString &dir)
|
||||
{
|
||||
if (dir == m_CurrentDirectory)
|
||||
return;
|
||||
|
||||
// Remove any pending stuff
|
||||
m_Thread->clear();
|
||||
|
||||
// Sync up, clear, and start processing
|
||||
m_Thread->immediate([this, dir]() -> void {
|
||||
invokeStdFunction([this, dir]() -> void {
|
||||
clear();
|
||||
std::string cacheDir = NLMISC::CPath::getApplicationDirectory("NeL", true) + "cache/thumbnails/";
|
||||
NLMISC::CFile::createDirectoryTree(cacheDir);
|
||||
std::vector<std::string> files;
|
||||
NLMISC::CPath::getPathContent(dir.toUtf8().data(), false, false, true, files);
|
||||
QImage dummyimg = QImage(128, 128, QImage::Format_ARGB32);
|
||||
dummyimg.fill(0);
|
||||
QIcon dummy = QIcon(QPixmap::fromImage(dummyimg));
|
||||
for (size_t i = 0; i < files.size(); ++i)
|
||||
{
|
||||
std::string &file = files[i];
|
||||
QString fileName = QFileInfo(QString::fromUtf8(file.c_str())).fileName();
|
||||
std::string ext = NLMISC::toLower(NLMISC::CFile::getExtension(file));
|
||||
if (ext == "dds" || ext == "tga" || ext == "png" || ext == "jpg" || ext == "jpeg")
|
||||
{
|
||||
QListWidgetItem *item = new QListWidgetItem(dummy, fileName);
|
||||
item->setSizeHint(gridSize());
|
||||
addItem(item);
|
||||
m_Thread->immediate([this, file, cacheDir, item]() -> void {
|
||||
CHashKey filePathHash = getSHA1((uint8 *)file.c_str(), file.size()); // Get SHA1 of filepath
|
||||
std::string hash = NLMISC::toLower(filePathHash.toString()); // Hash in text format
|
||||
std::string cacheFile = cacheDir + hash + ".png";
|
||||
QString cacheFilePath = QString::fromUtf8(cacheFile.c_str());
|
||||
uint32 assetModification = NLMISC::CFile::getFileModificationDate(file);
|
||||
uint32 assetSize = NLMISC::CFile::getFileSize(file);
|
||||
QImage image;
|
||||
if (NLMISC::CFile::isExists(cacheFile))
|
||||
{
|
||||
if (image.load(QString::fromUtf8(cacheFile.c_str()), "PNG"))
|
||||
{
|
||||
// Use thumnbail if it matches only
|
||||
uint32 thumbnailModification = image.text("NL_ASSET_MODIFICATION").toUInt();
|
||||
uint32 thumbnailSize = image.text("NL_ASSET_SIZE").toUInt();
|
||||
if (thumbnailSize != assetSize || thumbnailModification != assetModification)
|
||||
{
|
||||
image = QImage();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
image = QImage();
|
||||
}
|
||||
}
|
||||
if (image.isNull())
|
||||
{
|
||||
if (NLMISC::CFile::isExists(cacheFile))
|
||||
NLMISC::CFile::deleteFile(cacheFile);
|
||||
NLMISC::CIFile f;
|
||||
if (f.open(file))
|
||||
{
|
||||
NLMISC::CBitmap bitmap;
|
||||
bitmap.load(f);
|
||||
uint w = bitmap.getWidth();
|
||||
uint h = bitmap.getHeight();
|
||||
if (w == h) bitmap.resample(128, 128);
|
||||
else if (w > h) bitmap.resample(128, h * 128 / w);
|
||||
else bitmap.resample(w * 128 / h, 128);
|
||||
image = qImageFromCBitmap(bitmap, false);
|
||||
image.setText("NL_ASSET_MODIFICATION", QString::number(assetModification));
|
||||
image.setText("NL_ASSET_SIZE", QString::number(assetSize));
|
||||
image.save(cacheFilePath, "PNG");
|
||||
}
|
||||
}
|
||||
if (!image.isNull())
|
||||
{
|
||||
QIcon icon = QIcon(QPixmap::fromImage(image));
|
||||
invokeStdFunction([this, icon, item]() -> void {
|
||||
item->setIcon(icon); // IMPORANT: Must set icon with exact size of existing so the Qt UI doesn't flicker...
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void CTextureBrowser::invokeStdFunction(CStdFunctionVoid f)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "callStdFunction", Qt::QueuedConnection, Q_ARG(CStdFunctionVoid, f));
|
||||
}
|
||||
|
||||
void CTextureBrowser::callStdFunction(CStdFunctionVoid f)
|
||||
{
|
||||
f();
|
||||
}
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,71 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2016 Winch Gate Property Limited
|
||||
// Author: Jan Boon <jan.boon@kaetemi.be>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef NL_TEXTURE_BROWSER_H
|
||||
#define NL_TEXTURE_BROWSER_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
#include <functional>
|
||||
|
||||
// Qt includes
|
||||
#include <QListWidget>
|
||||
|
||||
// NeL includes
|
||||
// ...
|
||||
|
||||
class CEventLoop;
|
||||
typedef std::function<void()> CStdFunctionVoid;
|
||||
|
||||
/**
|
||||
* CTextureBrowser
|
||||
* \brief CTextureBrowser
|
||||
* \date 2016-02-18 14:06GMT
|
||||
* \author Jan Boon <jan.boon@kaetemi.be>
|
||||
*/
|
||||
class CTextureBrowser : public QListWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CTextureBrowser(QWidget *parent = NULL);
|
||||
virtual ~CTextureBrowser();
|
||||
|
||||
std::string getSelectedTextureFile() const;
|
||||
|
||||
void setDirectory(const QString &dir);
|
||||
|
||||
// STD INVOKE ->
|
||||
public:
|
||||
void invokeStdFunction(CStdFunctionVoid f);
|
||||
private slots:
|
||||
void callStdFunction(CStdFunctionVoid f);
|
||||
// <- STD INVOKE
|
||||
|
||||
private:
|
||||
CEventLoop *m_Thread;
|
||||
QString m_CurrentDirectory;
|
||||
|
||||
private:
|
||||
CTextureBrowser(const CTextureBrowser &);
|
||||
CTextureBrowser &operator=(const CTextureBrowser &);
|
||||
|
||||
}; /* class CTextureBrowser */
|
||||
|
||||
#endif /* #ifndef NL_TEXTURE_BROWSER_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,113 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2016 Winch Gate Property Limited
|
||||
// Author: Jan Boon <jan.boon@kaetemi.be>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include "texture_select_dialog.h"
|
||||
|
||||
// STL includes
|
||||
#include <functional>
|
||||
|
||||
// Qt includes
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QPixmap>
|
||||
#include <QListWidget>
|
||||
#include <QFileInfo>
|
||||
#include <QSplitter>
|
||||
#include <QPushButton>
|
||||
#include <QDir>
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
#include <nel/misc/common.h>
|
||||
#include <nel/misc/bitmap.h>
|
||||
#include <nel/misc/file.h>
|
||||
#include <nel/misc/sha1.h>
|
||||
#include <nel/pipeline/project_config.h>
|
||||
|
||||
// Project includes
|
||||
#include "texture_browser.h"
|
||||
|
||||
CTextureSelectDialog::CTextureSelectDialog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
resize(640, 400);
|
||||
setWindowTitle(tr("Select Texture"));
|
||||
|
||||
m_TextureBrowser = new CTextureBrowser(this);
|
||||
|
||||
QVBoxLayout *outer = new QVBoxLayout(this);
|
||||
setLayout(outer);
|
||||
|
||||
QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
|
||||
outer->addWidget(splitter);
|
||||
|
||||
QListWidget *folderList = new QListWidget(this);
|
||||
splitter->addWidget(folderList);
|
||||
splitter->addWidget(m_TextureBrowser);
|
||||
|
||||
QList<int> sizes;
|
||||
sizes << 160 << 480;
|
||||
splitter->setSizes(sizes);
|
||||
|
||||
QHBoxLayout *buttons = new QHBoxLayout(this);
|
||||
outer->addLayout(buttons);
|
||||
buttons->addStretch();
|
||||
|
||||
QPushButton *select = new QPushButton("Select", this);
|
||||
buttons->addWidget(select);
|
||||
|
||||
QPushButton *cancel = new QPushButton("Cancel", this);
|
||||
buttons->addWidget(cancel);
|
||||
|
||||
connect(select, &QPushButton::clicked, this, &QDialog::accept);
|
||||
connect(cancel, &QPushButton::clicked, this, &QDialog::reject);
|
||||
|
||||
std::vector<std::string> paths;
|
||||
NLPIPELINE::CProjectConfig::getDatabaseTextureSearchPaths(paths);
|
||||
QString assetRoot = QString::fromUtf8(NLPIPELINE::CProjectConfig::getAssetRoot().c_str());
|
||||
|
||||
QIcon folder(":/icons/folder-open-image.png");
|
||||
for (uint i = 0; i < paths.size(); ++i)
|
||||
{
|
||||
QString path = QString::fromUtf8(paths[i].c_str());
|
||||
if (path.startsWith(assetRoot))
|
||||
path = path.mid(assetRoot.size());
|
||||
folderList->addItem(new QListWidgetItem(folder, path));
|
||||
}
|
||||
|
||||
auto textChanged = [this, assetRoot](const QString &text) -> void {
|
||||
if (text.isEmpty()) return;
|
||||
else if (QDir::isRelativePath(text)) m_TextureBrowser->setDirectory(assetRoot + text);
|
||||
else m_TextureBrowser->setDirectory(text);
|
||||
};
|
||||
|
||||
if (folderList->count())
|
||||
{
|
||||
folderList->item(0)->setSelected(true);
|
||||
textChanged(folderList->item(0)->text());
|
||||
}
|
||||
|
||||
connect(folderList, &QListWidget::currentTextChanged, this, textChanged);
|
||||
}
|
||||
|
||||
CTextureSelectDialog::~CTextureSelectDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,60 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2016 Winch Gate Property Limited
|
||||
// Author: Jan Boon <jan.boon@kaetemi.be>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef NL_TEXTURE_SELECT_DIALOG_H
|
||||
#define NL_TEXTURE_SELECT_DIALOG_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QDialog>
|
||||
|
||||
// NeL includes
|
||||
// ...
|
||||
|
||||
// Project includes
|
||||
#include "texture_browser.h"
|
||||
|
||||
/**
|
||||
* CTextureSelectDialog
|
||||
* \brief CTextureSelectDialog
|
||||
* \date 2016-02-18 14:06GMT
|
||||
* \author Jan Boon <jan.boon@kaetemi.be>
|
||||
*/
|
||||
class CTextureSelectDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CTextureSelectDialog(QWidget *parent = NULL);
|
||||
virtual ~CTextureSelectDialog();
|
||||
|
||||
inline std::string getSelectedTextureFile() const { return m_TextureBrowser->getSelectedTextureFile(); }
|
||||
|
||||
private:
|
||||
CTextureBrowser *m_TextureBrowser;
|
||||
|
||||
private:
|
||||
CTextureSelectDialog(const CTextureSelectDialog &);
|
||||
CTextureSelectDialog &operator=(const CTextureSelectDialog &);
|
||||
|
||||
}; /* class CTextureSelectDialog */
|
||||
|
||||
#endif /* #ifndef NL_TEXTURE_SELECT_DIALOG_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,363 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include "undo_redo_binders.h"
|
||||
|
||||
// STL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QUndoStack>
|
||||
#include <QAbstractButton>
|
||||
#include <QLineEdit>
|
||||
#include <QComboBox>
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/debug.h>
|
||||
|
||||
// Project includes
|
||||
#include "qtcolorpicker.h"
|
||||
|
||||
// using namespace std;
|
||||
// using namespace NLMISC;
|
||||
|
||||
namespace {
|
||||
|
||||
int a_UndoCommandId = 9000;
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
CUndoRedoBinderButton::CUndoRedoBinderButton(QAbstractButton *abstractButton, QUndoStack *undoStack)
|
||||
: QObject(abstractButton), m_AbstractButton(abstractButton), m_UndoStack(undoStack)
|
||||
{
|
||||
nlassert(m_AbstractButton);
|
||||
bool c;
|
||||
m_Checked = m_AbstractButton->isChecked();
|
||||
c = connect(m_AbstractButton, SIGNAL(toggled(bool)), this, SLOT(abstractButtonToggled(bool)));
|
||||
nlassertex(c, ("connect toggled(bool)"));
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
CUndoRedoBinderButton::~CUndoRedoBinderButton()
|
||||
{
|
||||
m_UndoStack->clear(); // may contain commands on a deleted button
|
||||
}
|
||||
|
||||
void CUndoRedoBinderButton::abstractButtonToggled(bool checked)
|
||||
{
|
||||
if (m_Enabled)
|
||||
{
|
||||
if (checked != m_Checked)
|
||||
{
|
||||
bool undo = m_Checked;
|
||||
/* bool redo = checked; */
|
||||
m_Checked = checked; /* redo; */
|
||||
m_UndoStack->push(new CUndoRedoCommandButton(this, m_AbstractButton, undo));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Checked = checked;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
CUndoRedoCommandButton::CUndoRedoCommandButton(CUndoRedoBinderButton *binder, QAbstractButton *abstractButton, bool undo/*, bool redo*/)
|
||||
: QUndoCommand(), m_Binder(binder), m_AbstractButton(abstractButton), m_Undo(undo)/*, m_Redo(redo)*/
|
||||
{
|
||||
// nldebug("CUndoRedoCommandButton::CUndoRedoCommandButton()");
|
||||
nlassert(m_AbstractButton);
|
||||
}
|
||||
|
||||
CUndoRedoCommandButton::~CUndoRedoCommandButton()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CUndoRedoCommandButton::undo()
|
||||
{
|
||||
// nldebug("CUndoRedoCommandButton::undo()");
|
||||
// nlassert(m_AbstractButton);
|
||||
|
||||
m_Binder->enable(false);
|
||||
if (m_AbstractButton->isChecked() != m_Undo)
|
||||
m_AbstractButton->setChecked(m_Undo);
|
||||
m_Binder->enable(true);
|
||||
}
|
||||
|
||||
void CUndoRedoCommandButton::redo()
|
||||
{
|
||||
// nldebug("CUndoRedoCommandButton::redo()");
|
||||
// nlassert(m_AbstractButton);
|
||||
|
||||
m_Binder->enable(false);
|
||||
if (m_AbstractButton->isChecked() == m_Undo) /* != m_Redo) */
|
||||
m_AbstractButton->setChecked(!m_Undo); /* (m_Redo); */
|
||||
m_Binder->enable(true);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
CUndoRedoBinderLineEdit::CUndoRedoBinderLineEdit(QLineEdit *lineEdit, QUndoStack *undoStack)
|
||||
: QObject(lineEdit), m_LineEdit(lineEdit), m_UndoStack(undoStack)
|
||||
{
|
||||
nlassert(m_LineEdit);
|
||||
m_Id = ++a_UndoCommandId;
|
||||
bool c;
|
||||
m_LastValue = m_LineEdit->text();
|
||||
c = connect(m_LineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(lineEditTextChanged(const QString &)));
|
||||
nlassertex(c, ("connect textChanged(const QString &)"));
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
CUndoRedoBinderLineEdit::~CUndoRedoBinderLineEdit()
|
||||
{
|
||||
m_UndoStack->clear(); // may contain commands on a deleted LineEdit
|
||||
}
|
||||
|
||||
void CUndoRedoBinderLineEdit::lineEditTextChanged(const QString &text)
|
||||
{
|
||||
if (m_LineEdit->isRedoAvailable())
|
||||
{
|
||||
// workaround internal undo redo of lineedit
|
||||
m_LineEdit->redo();
|
||||
m_UndoStack->undo();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_Enabled)
|
||||
{
|
||||
if (text != m_LastValue)
|
||||
{
|
||||
QString undo = m_LastValue;
|
||||
const QString &redo = text;
|
||||
m_LastValue = redo;
|
||||
m_UndoStack->push(new CUndoRedoCommandLineEdit(this, m_LineEdit, undo, redo, m_Id));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LastValue = text;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
CUndoRedoCommandLineEdit::CUndoRedoCommandLineEdit(CUndoRedoBinderLineEdit *binder, QLineEdit *lineEdit, const QString &undo, const QString &redo, int id)
|
||||
: QUndoCommand(), m_Binder(binder), m_LineEdit(lineEdit), m_Undo(undo), m_Redo(redo), m_Id(id)
|
||||
{
|
||||
// nldebug("CUndoRedoCommandLineEdit::CUndoRedoCommandLineEdit()");
|
||||
nlassert(m_LineEdit);
|
||||
}
|
||||
|
||||
CUndoRedoCommandLineEdit::~CUndoRedoCommandLineEdit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CUndoRedoCommandLineEdit::mergeWith(const QUndoCommand *other)
|
||||
{
|
||||
if (m_Id != other->id()) return false;
|
||||
m_Redo = static_cast<const CUndoRedoCommandLineEdit *>(other)->m_Redo;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CUndoRedoCommandLineEdit::undo()
|
||||
{
|
||||
// nldebug("CUndoRedoCommandLineEdit::undo()");
|
||||
// nlassert(m_LineEdit);
|
||||
|
||||
m_Binder->enable(false);
|
||||
if (m_LineEdit->text() != m_Undo)
|
||||
m_LineEdit->setText(m_Undo);
|
||||
m_Binder->enable(true);
|
||||
}
|
||||
|
||||
void CUndoRedoCommandLineEdit::redo()
|
||||
{
|
||||
// nldebug("CUndoRedoCommandLineEdit::redo()");
|
||||
// nlassert(m_LineEdit);
|
||||
|
||||
m_Binder->enable(false);
|
||||
if (m_LineEdit->text() != m_Redo)
|
||||
m_LineEdit->setText(m_Redo);
|
||||
m_Binder->enable(true);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
CUndoRedoBinderComboBox::CUndoRedoBinderComboBox(QComboBox *comboBox, QUndoStack *undoStack)
|
||||
: QObject(comboBox), m_ComboBox(comboBox), m_UndoStack(undoStack)
|
||||
{
|
||||
nlassert(m_ComboBox);
|
||||
bool c;
|
||||
m_LastValue = m_ComboBox->currentIndex();
|
||||
c = connect(m_ComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(comboBoxCurrentIndexChanged(int)));
|
||||
nlassertex(c, ("connect currentIndexChanged(int)"));
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
CUndoRedoBinderComboBox::~CUndoRedoBinderComboBox()
|
||||
{
|
||||
m_UndoStack->clear(); // may contain commands on a deleted ComboBox
|
||||
}
|
||||
|
||||
void CUndoRedoBinderComboBox::comboBoxCurrentIndexChanged(int index)
|
||||
{
|
||||
if (m_Enabled)
|
||||
{
|
||||
if (index != m_LastValue)
|
||||
{
|
||||
int undo = m_LastValue;
|
||||
int redo = index;
|
||||
m_LastValue = redo;
|
||||
m_UndoStack->push(new CUndoRedoCommandComboBox(this, m_ComboBox, undo, redo));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LastValue = index;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
CUndoRedoCommandComboBox::CUndoRedoCommandComboBox(CUndoRedoBinderComboBox *binder, QComboBox *comboBox, int undo, int redo)
|
||||
: QUndoCommand(), m_Binder(binder), m_ComboBox(comboBox), m_Undo(undo), m_Redo(redo)
|
||||
{
|
||||
// nldebug("CUndoRedoCommandComboBox::CUndoRedoCommandComboBox()");
|
||||
nlassert(m_ComboBox);
|
||||
}
|
||||
|
||||
CUndoRedoCommandComboBox::~CUndoRedoCommandComboBox()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CUndoRedoCommandComboBox::undo()
|
||||
{
|
||||
// nldebug("CUndoRedoCommandComboBox::undo()");
|
||||
// nlassert(m_ComboBox);
|
||||
|
||||
m_Binder->enable(false);
|
||||
if (m_ComboBox->currentIndex() != m_Undo)
|
||||
m_ComboBox->setCurrentIndex(m_Undo);
|
||||
m_Binder->enable(true);
|
||||
}
|
||||
|
||||
void CUndoRedoCommandComboBox::redo()
|
||||
{
|
||||
// nldebug("CUndoRedoCommandComboBox::redo()");
|
||||
// nlassert(m_ComboBox);
|
||||
|
||||
m_Binder->enable(false);
|
||||
if (m_ComboBox->currentIndex() != m_Redo)
|
||||
m_ComboBox->setCurrentIndex(m_Redo);
|
||||
m_Binder->enable(true);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
CUndoRedoBinderColorPicker::CUndoRedoBinderColorPicker(QtColorPicker *colorPicker, QUndoStack *undoStack)
|
||||
: QObject(colorPicker), m_ColorPicker(colorPicker), m_UndoStack(undoStack)
|
||||
{
|
||||
nlassert(m_ColorPicker);
|
||||
bool c;
|
||||
m_LastValue = m_ColorPicker->currentColor();
|
||||
c = connect(m_ColorPicker, SIGNAL(colorChanged(const QColor &)), this, SLOT(colorPickerColorChanged(const QColor &)));
|
||||
nlassertex(c, ("connect colorChanged(const QColor &)"));
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
CUndoRedoBinderColorPicker::~CUndoRedoBinderColorPicker()
|
||||
{
|
||||
m_UndoStack->clear(); // may contain commands on a deleted ColorPicker
|
||||
}
|
||||
|
||||
void CUndoRedoBinderColorPicker::colorPickerColorChanged(const QColor &col)
|
||||
{
|
||||
if (m_Enabled)
|
||||
{
|
||||
if (col != m_LastValue)
|
||||
{
|
||||
QColor undo = m_LastValue;
|
||||
const QColor &redo = col;
|
||||
m_LastValue = redo;
|
||||
m_UndoStack->push(new CUndoRedoCommandColorPicker(this, m_ColorPicker, undo, redo));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LastValue = col;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
CUndoRedoCommandColorPicker::CUndoRedoCommandColorPicker(CUndoRedoBinderColorPicker *binder, QtColorPicker *colorPicker, const QColor &undo, const QColor &redo)
|
||||
: QUndoCommand(), m_Binder(binder), m_ColorPicker(colorPicker), m_Undo(undo), m_Redo(redo)
|
||||
{
|
||||
// nldebug("CUndoRedoCommandColorPicker::CUndoRedoCommandColorPicker()");
|
||||
nlassert(m_ColorPicker);
|
||||
}
|
||||
|
||||
CUndoRedoCommandColorPicker::~CUndoRedoCommandColorPicker()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CUndoRedoCommandColorPicker::undo()
|
||||
{
|
||||
// nldebug("CUndoRedoCommandColorPicker::undo()");
|
||||
// nlassert(m_ColorPicker);
|
||||
|
||||
m_Binder->enable(false);
|
||||
if (m_ColorPicker->currentColor() != m_Undo)
|
||||
m_ColorPicker->setCurrentColor(m_Undo);
|
||||
m_Binder->enable(true);
|
||||
}
|
||||
|
||||
void CUndoRedoCommandColorPicker::redo()
|
||||
{
|
||||
// nldebug("CUndoRedoCommandColorPicker::redo()");
|
||||
// nlassert(m_ColorPicker);
|
||||
|
||||
m_Binder->enable(false);
|
||||
if (m_ColorPicker->currentColor() != m_Redo)
|
||||
m_ColorPicker->setCurrentColor(m_Redo);
|
||||
m_Binder->enable(true);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,314 @@
|
||||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef NLQT_UNDO_REDO_BINDERS_H
|
||||
#define NLQT_UNDO_REDO_BINDERS_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// Qt includes
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QColor>
|
||||
#include <QUndoCommand>
|
||||
|
||||
// NeL includes
|
||||
|
||||
// Project includes
|
||||
|
||||
class QUndoStack;
|
||||
class QAbstractButton;
|
||||
class QLineEdit;
|
||||
class QComboBox;
|
||||
class QtColorPicker;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* CUndoRedoBinderButton
|
||||
* \brief CUndoRedoBinderButton
|
||||
* \date 2010-02-13 14:02GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CUndoRedoBinderButton : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CUndoRedoBinderButton(QAbstractButton *abstractButton, QUndoStack *undoStack);
|
||||
virtual ~CUndoRedoBinderButton();
|
||||
|
||||
inline void enable(bool enabled) { m_Enabled = enabled; }
|
||||
|
||||
private slots:
|
||||
void abstractButtonToggled(bool checked);
|
||||
|
||||
private:
|
||||
bool m_Enabled; // binder enabled
|
||||
bool m_Checked;
|
||||
QAbstractButton *m_AbstractButton;
|
||||
QUndoStack *m_UndoStack;
|
||||
|
||||
private:
|
||||
CUndoRedoBinderButton(const CUndoRedoBinderButton &);
|
||||
CUndoRedoBinderButton &operator=(const CUndoRedoBinderButton &);
|
||||
|
||||
}; /* class CUndoRedoBinderButton */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* CUndoRedoCommandButton
|
||||
* \brief CUndoRedoCommandButton
|
||||
* \date 2010-02-13 14:02GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CUndoRedoCommandButton : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
CUndoRedoCommandButton(CUndoRedoBinderButton *binder, QAbstractButton *abstractButton, bool undo/*, bool redo*/);
|
||||
virtual ~CUndoRedoCommandButton();
|
||||
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
private:
|
||||
bool m_Undo;
|
||||
/*bool m_Redo;*/
|
||||
CUndoRedoBinderButton *m_Binder;
|
||||
QAbstractButton *m_AbstractButton;
|
||||
QUndoStack *m_UndoStack;
|
||||
|
||||
private:
|
||||
CUndoRedoCommandButton(const CUndoRedoCommandButton &);
|
||||
CUndoRedoCommandButton &operator=(const CUndoRedoCommandButton &);
|
||||
|
||||
}; /* class CUndoRedoCommandButton */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* CUndoRedoBinderLineEdit
|
||||
* \brief CUndoRedoBinderLineEdit
|
||||
* \date 2010-02-13 14:02GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CUndoRedoBinderLineEdit : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CUndoRedoBinderLineEdit(QLineEdit *lineEdit, QUndoStack *undoStack);
|
||||
virtual ~CUndoRedoBinderLineEdit();
|
||||
|
||||
inline void enable(bool enabled) { m_Enabled = enabled; }
|
||||
|
||||
private slots:
|
||||
void lineEditTextChanged(const QString &text);
|
||||
|
||||
private:
|
||||
bool m_Enabled; // binder enabled
|
||||
QString m_LastValue;
|
||||
QLineEdit *m_LineEdit;
|
||||
QUndoStack *m_UndoStack;
|
||||
int m_Id;
|
||||
|
||||
private:
|
||||
CUndoRedoBinderLineEdit(const CUndoRedoBinderLineEdit &);
|
||||
CUndoRedoBinderLineEdit &operator=(const CUndoRedoBinderLineEdit &);
|
||||
|
||||
}; /* class CUndoRedoBinderLineEdit */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* CUndoRedoCommandLineEdit
|
||||
* \brief CUndoRedoCommandLineEdit
|
||||
* \date 2010-02-13 14:02GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CUndoRedoCommandLineEdit : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
CUndoRedoCommandLineEdit(CUndoRedoBinderLineEdit *binder, QLineEdit *abtractLineEdit, const QString &undo, const QString &redo, int id);
|
||||
virtual ~CUndoRedoCommandLineEdit();
|
||||
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
virtual int id() const { return m_Id; };
|
||||
virtual bool mergeWith(const QUndoCommand *other);
|
||||
|
||||
private:
|
||||
QString m_Undo;
|
||||
QString m_Redo;
|
||||
CUndoRedoBinderLineEdit *m_Binder;
|
||||
QLineEdit *m_LineEdit;
|
||||
QUndoStack *m_UndoStack;
|
||||
int m_Id;
|
||||
|
||||
private:
|
||||
CUndoRedoCommandLineEdit(const CUndoRedoCommandLineEdit &);
|
||||
CUndoRedoCommandLineEdit &operator=(const CUndoRedoCommandLineEdit &);
|
||||
|
||||
}; /* class CUndoRedoCommandLineEdit */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* CUndoRedoBinderComboBox
|
||||
* \brief CUndoRedoBinderComboBox
|
||||
* \date 2010-02-13 14:02GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CUndoRedoBinderComboBox : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CUndoRedoBinderComboBox(QComboBox *comboBox, QUndoStack *undoStack);
|
||||
virtual ~CUndoRedoBinderComboBox();
|
||||
|
||||
inline void enable(bool enabled) { m_Enabled = enabled; }
|
||||
|
||||
private slots:
|
||||
void comboBoxCurrentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
bool m_Enabled; // binder enabled
|
||||
int m_LastValue;
|
||||
QComboBox *m_ComboBox;
|
||||
QUndoStack *m_UndoStack;
|
||||
|
||||
private:
|
||||
CUndoRedoBinderComboBox(const CUndoRedoBinderComboBox &);
|
||||
CUndoRedoBinderComboBox &operator=(const CUndoRedoBinderComboBox &);
|
||||
|
||||
}; /* class CUndoRedoBinderComboBox */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* CUndoRedoCommandComboBox
|
||||
* \brief CUndoRedoCommandComboBox
|
||||
* \date 2010-02-13 14:02GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CUndoRedoCommandComboBox : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
CUndoRedoCommandComboBox(CUndoRedoBinderComboBox *binder, QComboBox *abtractComboBox, int undo, int redo);
|
||||
virtual ~CUndoRedoCommandComboBox();
|
||||
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
private:
|
||||
int m_Undo;
|
||||
int m_Redo;
|
||||
CUndoRedoBinderComboBox *m_Binder;
|
||||
QComboBox *m_ComboBox;
|
||||
QUndoStack *m_UndoStack;
|
||||
|
||||
private:
|
||||
CUndoRedoCommandComboBox(const CUndoRedoCommandComboBox &);
|
||||
CUndoRedoCommandComboBox &operator=(const CUndoRedoCommandComboBox &);
|
||||
|
||||
}; /* class CUndoRedoCommandComboBox */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* CUndoRedoBinderColorPicker
|
||||
* \brief CUndoRedoBinderColorPicker
|
||||
* \date 2010-02-13 14:02GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CUndoRedoBinderColorPicker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CUndoRedoBinderColorPicker(QtColorPicker *colorPicker, QUndoStack *undoStack);
|
||||
virtual ~CUndoRedoBinderColorPicker();
|
||||
|
||||
inline void enable(bool enabled) { m_Enabled = enabled; }
|
||||
|
||||
private slots:
|
||||
void colorPickerColorChanged(const QColor &col);
|
||||
|
||||
private:
|
||||
bool m_Enabled; // binder enabled
|
||||
QColor m_LastValue;
|
||||
QtColorPicker *m_ColorPicker;
|
||||
QUndoStack *m_UndoStack;
|
||||
|
||||
private:
|
||||
CUndoRedoBinderColorPicker(const CUndoRedoBinderColorPicker &);
|
||||
CUndoRedoBinderColorPicker &operator=(const CUndoRedoBinderColorPicker &);
|
||||
|
||||
}; /* class CUndoRedoBinderColorPicker */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* CUndoRedoCommandColorPicker
|
||||
* \brief CUndoRedoCommandColorPicker
|
||||
* \date 2010-02-13 14:02GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
*/
|
||||
class CUndoRedoCommandColorPicker : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
CUndoRedoCommandColorPicker(CUndoRedoBinderColorPicker *binder, QtColorPicker *abtractColorPicker, const QColor &undo, const QColor &redo);
|
||||
virtual ~CUndoRedoCommandColorPicker();
|
||||
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
private:
|
||||
QColor m_Undo;
|
||||
QColor m_Redo;
|
||||
CUndoRedoBinderColorPicker *m_Binder;
|
||||
QtColorPicker *m_ColorPicker;
|
||||
QUndoStack *m_UndoStack;
|
||||
|
||||
private:
|
||||
CUndoRedoCommandColorPicker(const CUndoRedoCommandColorPicker &);
|
||||
CUndoRedoCommandColorPicker &operator=(const CUndoRedoCommandColorPicker &);
|
||||
|
||||
}; /* class CUndoRedoCommandColorPicker */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif /* #ifndef NLQT_UNDO_REDO_BINDERS_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,477 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2015 by authors
|
||||
Author: Jan Boon <jan.boon@kaetemi.be>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
// Source: https://github.com/kaetemi/errorlist
|
||||
|
||||
#include "error_list.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QListWidget>
|
||||
#include <QListWidgetItem>
|
||||
#include <QTextEdit>
|
||||
#include <QSplitter>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace NLQT {
|
||||
|
||||
#define DATAROLE_TYPE (Qt::UserRole + 0)
|
||||
#define DATAROLE_TIMESTAMP (Qt::UserRole + 1)
|
||||
#define DATAROLE_GROUP (Qt::UserRole + 2)
|
||||
#define DATAROLE_MESSAGE (Qt::UserRole + 3)
|
||||
#define DATAROLE_LINE (Qt::UserRole + 4)
|
||||
#define DATAROLE_USERDATA (Qt::UserRole + 5)
|
||||
#define DATAROLE_COLLAPSED (Qt::UserRole + 6)
|
||||
|
||||
class CErrorListItem : public QListWidgetItem
|
||||
{
|
||||
public:
|
||||
CErrorListItem(const QIcon &icon, const QString &message) : QListWidgetItem(icon, message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual bool operator<(const QListWidgetItem &other) const Q_DECL_OVERRIDE
|
||||
{
|
||||
time_t this_timestamp = data(DATAROLE_TIMESTAMP).toInt();
|
||||
time_t other_timestamp = other.data(DATAROLE_TIMESTAMP).toInt();
|
||||
return this_timestamp < other_timestamp;
|
||||
}
|
||||
};
|
||||
|
||||
const char *iconNames[] = {
|
||||
":/icons/cross-circle.png",
|
||||
":/icons/exclamation.png",
|
||||
":/icons/information-white.png"
|
||||
};
|
||||
|
||||
const char *filterText[] = {
|
||||
"Errors",
|
||||
"Warnings",
|
||||
"Messages"
|
||||
};
|
||||
|
||||
CErrorList::CErrorList(QWidget *parent) : QWidget(parent), m_Collapse(true), m_CollapseBtn(NULL), m_Message(NULL)
|
||||
{
|
||||
m_Filter[0] = true;
|
||||
m_Filter[1] = true;
|
||||
m_Filter[2] = true;
|
||||
m_FilterBtn[0] = NULL;
|
||||
m_FilterBtn[1] = NULL;
|
||||
m_FilterBtn[2] = NULL;
|
||||
m_FilterCounts[0] = 0;
|
||||
m_FilterCounts[1] = 0;
|
||||
m_FilterCounts[2] = 0;
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
QHBoxLayout *buttons = new QHBoxLayout(this);
|
||||
|
||||
QPushButton *clearBtn = new QPushButton(this);
|
||||
clearBtn->setText(tr("Clear"));
|
||||
connect(clearBtn, SIGNAL(clicked()), this, SLOT(clear()));
|
||||
buttons->addWidget(clearBtn);
|
||||
|
||||
QPushButton *collapseBtn = new QPushButton(this);
|
||||
m_CollapseBtn = collapseBtn;
|
||||
collapseBtn->setText(tr("Collapse"));
|
||||
collapseBtn->setCheckable(true);
|
||||
collapseBtn->setChecked(m_Collapse);
|
||||
connect(collapseBtn, SIGNAL(toggled(bool)), this, SLOT(collapse(bool)));
|
||||
buttons->addWidget(collapseBtn);
|
||||
|
||||
buttons->addStretch();
|
||||
|
||||
QPushButton *errorBtn = new QPushButton(this);
|
||||
m_FilterBtn[0] = errorBtn;
|
||||
errorBtn->setIcon(QIcon(iconNames[0]));
|
||||
updateFilterCount(0);
|
||||
errorBtn->setCheckable(true);
|
||||
errorBtn->setChecked(m_Filter[0]);
|
||||
connect(errorBtn, SIGNAL(toggled(bool)), this, SLOT(filterError(bool)));
|
||||
buttons->addWidget(errorBtn);
|
||||
|
||||
QPushButton *warningBtn = new QPushButton(this);
|
||||
m_FilterBtn[1] = warningBtn;
|
||||
warningBtn->setIcon(QIcon(iconNames[1]));
|
||||
updateFilterCount(1);
|
||||
warningBtn->setCheckable(true);
|
||||
warningBtn->setChecked(m_Filter[1]);
|
||||
connect(warningBtn, SIGNAL(toggled(bool)), this, SLOT(filterWarning(bool)));
|
||||
buttons->addWidget(warningBtn);
|
||||
|
||||
QPushButton *messageBtn = new QPushButton(this);
|
||||
m_FilterBtn[2] = messageBtn;
|
||||
messageBtn->setIcon(QIcon(iconNames[2]));
|
||||
updateFilterCount(2);
|
||||
messageBtn->setCheckable(true);
|
||||
messageBtn->setChecked(m_Filter[2]);
|
||||
connect(messageBtn, SIGNAL(toggled(bool)), this, SLOT(filterMessage(bool)));
|
||||
buttons->addWidget(messageBtn);
|
||||
|
||||
layout->addLayout(buttons);
|
||||
|
||||
QSplitter *splitter = new QSplitter(Qt::Vertical, this);
|
||||
|
||||
m_List = new QListWidget(this);
|
||||
m_List->setTextElideMode(Qt::ElideRight);
|
||||
m_List->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
// m_List->setSortingEnabled(true);
|
||||
connect(m_List, &QListWidget::itemClicked, this, &CErrorList::listItemClicked);
|
||||
connect(m_List, &QListWidget::itemDoubleClicked, this, &CErrorList::listItemDoubleClicked);
|
||||
splitter->addWidget(m_List);
|
||||
|
||||
QTextEdit *messageText = new QTextEdit(this);
|
||||
m_Message = messageText;
|
||||
messageText->setReadOnly(true);
|
||||
messageText->setVisible(false);
|
||||
messageText->setAcceptRichText(true);
|
||||
splitter->addWidget(messageText);
|
||||
|
||||
layout->addWidget(splitter);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
CErrorList::~CErrorList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CErrorList::clear()
|
||||
{
|
||||
m_CurrentMessage = NULL;
|
||||
m_Message->setVisible(false);
|
||||
m_CollapseItems.clear();
|
||||
m_List->clear();
|
||||
m_FilterCounts[0] = 0;
|
||||
m_FilterCounts[1] = 0;
|
||||
m_FilterCounts[2] = 0;
|
||||
updateFilterCount(0);
|
||||
updateFilterCount(1);
|
||||
updateFilterCount(2);
|
||||
}
|
||||
|
||||
void CErrorList::clear(const QString &group)
|
||||
{
|
||||
for (int i = 0; i < m_List->count(); ++i)
|
||||
{
|
||||
QListWidgetItem *item = m_List->item(i);
|
||||
if (item->data(DATAROLE_GROUP).toString() == group)
|
||||
{
|
||||
if (m_CurrentMessage == item)
|
||||
{
|
||||
m_CurrentMessage = NULL;
|
||||
m_Message->setVisible(false);
|
||||
}
|
||||
if (m_Collapse)
|
||||
{
|
||||
QString cs = getCollapseString(item);
|
||||
std::map<QString, QListWidgetItem *>::iterator it
|
||||
= m_CollapseItems.find(cs);
|
||||
if (it != m_CollapseItems.end())
|
||||
m_CollapseItems.erase(it);
|
||||
}
|
||||
--m_FilterCounts[(int)item->data(DATAROLE_TYPE).toInt()];
|
||||
delete item;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
updateFilterCount(0);
|
||||
updateFilterCount(1);
|
||||
updateFilterCount(2);
|
||||
}
|
||||
|
||||
void CErrorList::collapse(bool c)
|
||||
{
|
||||
if (c != m_Collapse)
|
||||
{
|
||||
m_Collapse = c;
|
||||
m_CollapseBtn->setChecked(c);
|
||||
|
||||
if (c)
|
||||
{
|
||||
for (int i = 0; i < m_List->count(); ++i)
|
||||
{
|
||||
QListWidgetItem *item = m_List->item(i);
|
||||
QString cs = getCollapseString(item);
|
||||
QListWidgetItem *ref = m_CollapseItems[cs];
|
||||
|
||||
if (ref != NULL)
|
||||
{
|
||||
ref->setData(DATAROLE_COLLAPSED, ref->data(DATAROLE_COLLAPSED).toInt() + 1);
|
||||
updateCollapseText(ref);
|
||||
item->setData(DATAROLE_COLLAPSED, 0);
|
||||
item->setHidden(true);
|
||||
if (m_CurrentMessage == item)
|
||||
{
|
||||
m_CurrentMessage = NULL;
|
||||
m_Message->setHidden(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CollapseItems[cs] = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CollapseItems.clear();
|
||||
for (int i = 0; i < m_List->count(); ++i)
|
||||
{
|
||||
int cc = m_List->item(i)->data(DATAROLE_COLLAPSED).toInt();
|
||||
if (cc > 1)
|
||||
{
|
||||
m_List->item(i)->setText(m_List->item(i)->data(DATAROLE_LINE).toString());
|
||||
}
|
||||
if (cc == 0)
|
||||
{
|
||||
bool hide = !m_Filter[m_List->item(i)->data(DATAROLE_TYPE).toInt()];
|
||||
m_List->item(i)->setHidden(hide);
|
||||
}
|
||||
if (cc != 1)
|
||||
{
|
||||
m_List->item(i)->setData(DATAROLE_COLLAPSED, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CErrorList::filter(ErrorType type, bool f)
|
||||
{
|
||||
if (f != m_Filter[(int)type])
|
||||
{
|
||||
m_Filter[(int)type] = f;
|
||||
m_FilterBtn[(int)type]->setChecked(f);
|
||||
|
||||
for (int i = 0; i < m_List->count(); ++i)
|
||||
{
|
||||
if (m_List->item(i)->data(DATAROLE_TYPE).toInt() == (int)type)
|
||||
{
|
||||
bool hide =
|
||||
m_List->item(i)->data(DATAROLE_COLLAPSED).toInt() == 0
|
||||
|| !f;
|
||||
m_List->item(i)->setHidden(hide);
|
||||
if (hide && m_CurrentMessage == m_List->item(i))
|
||||
{
|
||||
m_CurrentMessage = NULL;
|
||||
m_Message->setHidden(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CErrorList::updateFilterCount(int filter)
|
||||
{
|
||||
m_FilterBtn[filter]->setText(QString(" ") + QString::number(m_FilterCounts[filter]) + " " + filterText[filter]);
|
||||
}
|
||||
|
||||
void CErrorList::filterError(bool f)
|
||||
{
|
||||
filter(Error, f);
|
||||
}
|
||||
|
||||
void CErrorList::filterWarning(bool f)
|
||||
{
|
||||
filter(Warning, f);
|
||||
}
|
||||
|
||||
void CErrorList::filterMessage(bool f)
|
||||
{
|
||||
filter(Message, f);
|
||||
}
|
||||
|
||||
void CErrorList::markClear(const QString &group)
|
||||
{
|
||||
for (int i = 0; i < m_List->count(); ++i)
|
||||
{
|
||||
QListWidgetItem *item = m_List->item(i);
|
||||
if (item->data(DATAROLE_GROUP).toString() == group)
|
||||
{
|
||||
QString cs = getCollapseString(item);
|
||||
m_MarkedClear.insert(cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CErrorList::clearMarked()
|
||||
{
|
||||
for (int i = 0; i < m_List->count(); ++i)
|
||||
{
|
||||
QListWidgetItem *item = m_List->item(i);
|
||||
QString cs = getCollapseString(item);
|
||||
if (m_MarkedClear.find(cs) != m_MarkedClear.end())
|
||||
{
|
||||
if (m_CurrentMessage == item)
|
||||
{
|
||||
m_CurrentMessage = NULL;
|
||||
m_Message->setVisible(false);
|
||||
}
|
||||
if (m_Collapse)
|
||||
{
|
||||
QString cs = getCollapseString(item);
|
||||
std::map<QString, QListWidgetItem *>::iterator it
|
||||
= m_CollapseItems.find(cs);
|
||||
if (it != m_CollapseItems.end())
|
||||
m_CollapseItems.erase(it);
|
||||
}
|
||||
--m_FilterCounts[(int)item->data(DATAROLE_TYPE).toInt()];
|
||||
delete item;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CErrorList::listItemClicked(QListWidgetItem *item)
|
||||
{
|
||||
if (item != m_CurrentMessage)
|
||||
{
|
||||
if (item->isSelected())
|
||||
{
|
||||
QString text = item->data(DATAROLE_MESSAGE).toString();
|
||||
m_Message->setHtml(text);
|
||||
m_Message->setVisible(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrentMessage = NULL;
|
||||
m_Message->setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CErrorList::listItemDoubleClicked(QListWidgetItem *item)
|
||||
{
|
||||
emit request(item->data(DATAROLE_GROUP).toString(), item->data(DATAROLE_USERDATA).toMap());
|
||||
}
|
||||
|
||||
QString CErrorList::getCollapseString(QListWidgetItem *item)
|
||||
{
|
||||
return item->data(DATAROLE_GROUP).toString() + " / " + item->data(DATAROLE_LINE).toString();
|
||||
}
|
||||
|
||||
void CErrorList::updateCollapseText(QListWidgetItem *item)
|
||||
{
|
||||
item->setText(QString("(" + QString::number(item->data(DATAROLE_COLLAPSED).toInt()) + "x) " + item->data(DATAROLE_LINE).toString()));// .replace('\n', ' ').replace('\r', ' ')));
|
||||
}
|
||||
|
||||
void CErrorList::add(ErrorType type, const QString &group, time_t timestamp, const QString &message, const QMap<QString, QVariant> &userData)
|
||||
{
|
||||
QTextDocument doc;
|
||||
doc.setHtml(message);
|
||||
QString line = doc.toPlainText().replace('\n', ' ').replace('\r', ' ');
|
||||
|
||||
CErrorListItem *item = new CErrorListItem(QIcon(iconNames[(int)type]), line);
|
||||
item->setData(DATAROLE_TYPE, (int)type);
|
||||
item->setData(DATAROLE_TIMESTAMP, timestamp);
|
||||
item->setData(DATAROLE_GROUP, group);
|
||||
item->setData(DATAROLE_MESSAGE, message);
|
||||
item->setData(DATAROLE_LINE, line);
|
||||
item->setData(DATAROLE_USERDATA, userData);
|
||||
|
||||
QString cs = getCollapseString(item);
|
||||
if (m_MarkedClear.find(cs) != m_MarkedClear.end())
|
||||
{
|
||||
m_MarkedClear.erase(cs);
|
||||
return;
|
||||
}
|
||||
|
||||
bool hide = m_Collapse;
|
||||
if (hide)
|
||||
{
|
||||
QListWidgetItem *ref = m_CollapseItems[cs];
|
||||
hide = ref != NULL;
|
||||
if (hide)
|
||||
{
|
||||
ref->setData(DATAROLE_COLLAPSED, ref->data(DATAROLE_COLLAPSED).toInt() + 1);
|
||||
updateCollapseText(ref);
|
||||
item->setData(DATAROLE_COLLAPSED, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CollapseItems[cs] = item;
|
||||
}
|
||||
}
|
||||
if (!hide)
|
||||
{
|
||||
item->setData(DATAROLE_COLLAPSED, 1);
|
||||
hide = !m_Filter[(int)type];
|
||||
}
|
||||
|
||||
m_List->addItem(item);
|
||||
item->setHidden(hide);
|
||||
++m_FilterCounts[(int)type];
|
||||
updateFilterCount((int)type);
|
||||
}
|
||||
|
||||
void CErrorList::update(const QString &group, const QString &message)
|
||||
{
|
||||
// NOTE: This does not play well with collapse, so you should only have one message present in the category
|
||||
// Automatically adds a message if no message exists in the category
|
||||
for (int i = 0; i < m_List->count(); ++i)
|
||||
{
|
||||
QListWidgetItem *item = m_List->item(i);
|
||||
if (item->data(DATAROLE_GROUP).toString() == group)
|
||||
{
|
||||
QTextDocument doc;
|
||||
doc.setHtml(message);
|
||||
QString line = doc.toPlainText().replace('\n', ' ').replace('\r', ' ');
|
||||
item->setData(DATAROLE_MESSAGE, message);
|
||||
item->setData(DATAROLE_LINE, line);
|
||||
item->setText(line);
|
||||
return;
|
||||
}
|
||||
}
|
||||
add(Message, group, message);
|
||||
}
|
||||
|
||||
void CErrorList::add(ErrorType type, const QString &group, time_t timestamp, const QString &message)
|
||||
{
|
||||
QMap<QString, QVariant> nullMap;
|
||||
add(type, group, timestamp, message, nullMap);
|
||||
}
|
||||
|
||||
void CErrorList::add(ErrorType type, const QString &group, const QString &message, const QMap<QString, QVariant> &userData)
|
||||
{
|
||||
add(type, group, QDateTime::currentDateTime().toTime_t(), message, userData);
|
||||
}
|
||||
|
||||
void CErrorList::add(ErrorType type, const QString &group, const QString &message)
|
||||
{
|
||||
QMap<QString, QVariant> nullMap;
|
||||
add(type, group, message, nullMap);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2015 by authors
|
||||
Author: Jan Boon <jan.boon@kaetemi.be>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
// Source: https://github.com/kaetemi/errorlist
|
||||
|
||||
#ifndef ERRORLIST_H
|
||||
#define ERRORLIST_H
|
||||
|
||||
#define ERRORLIST_EXPORT
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
|
||||
class QListWidgetItem;
|
||||
class QListWidget;
|
||||
class QPushButton;
|
||||
class QTextEdit;
|
||||
|
||||
namespace NLQT {
|
||||
|
||||
class ERRORLIST_EXPORT CErrorList : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum ErrorType
|
||||
{
|
||||
Error,
|
||||
Warning,
|
||||
Message
|
||||
};
|
||||
|
||||
public:
|
||||
CErrorList(QWidget *parent);
|
||||
virtual ~CErrorList();
|
||||
|
||||
void add(ErrorType type, const QString &group, time_t timestamp, const QString &message, const QMap<QString, QVariant> &userData);
|
||||
void add(ErrorType type, const QString &group, time_t timestamp, const QString &message);
|
||||
void add(ErrorType type, const QString &group, const QString &message, const QMap<QString, QVariant> &userData);
|
||||
void add(ErrorType type, const QString &group, const QString &message);
|
||||
|
||||
void update(const QString &group, const QString &message);
|
||||
|
||||
void markClear(const QString &group);
|
||||
void clearMarked();
|
||||
|
||||
void clear(const QString &group);
|
||||
void filter(ErrorType type, bool f);
|
||||
|
||||
signals:
|
||||
void request(const QString &group, const QMap<QString, QVariant> &userData);
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
void collapse(bool c);
|
||||
void filterError(bool f);
|
||||
void filterWarning(bool f);
|
||||
void filterMessage(bool f);
|
||||
|
||||
private slots:
|
||||
void listItemClicked(QListWidgetItem *item);
|
||||
void listItemDoubleClicked(QListWidgetItem *item);
|
||||
|
||||
private:
|
||||
void updateFilterCount(int filter);
|
||||
static QString getCollapseString(QListWidgetItem *item);
|
||||
static void updateCollapseText(QListWidgetItem *item);
|
||||
|
||||
private:
|
||||
QListWidget *m_List;
|
||||
std::map<QString, QListWidgetItem *> m_CollapseItems;
|
||||
bool m_Collapse;
|
||||
QPushButton *m_CollapseBtn;
|
||||
bool m_Filter[3];
|
||||
QPushButton *m_FilterBtn[3];
|
||||
int m_FilterCounts[3];
|
||||
QTextEdit *m_Message;
|
||||
QListWidgetItem *m_CurrentMessage;
|
||||
std::set<QString> m_MarkedClear;
|
||||
|
||||
}; /* class CErrorList */
|
||||
|
||||
}
|
||||
|
||||
#endif /* ERRORLIST_H */
|
||||
|
||||
/* end of file */
|
@ -0,0 +1,281 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2016 by authors
|
||||
Author: Jan Boon <jan.boon@kaetemi.be>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
// Source: https://github.com/kaetemi/threadutil/blob/master/threadutil/eventloop.h
|
||||
|
||||
#ifndef NL_EVENT_LOOP_H
|
||||
#define NL_EVENT_LOOP_H
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
class CEventLoop
|
||||
{
|
||||
public:
|
||||
CEventLoop() : m_Running(false), m_Handle(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~CEventLoop()
|
||||
{
|
||||
stop();
|
||||
clear();
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
stop();
|
||||
m_Running = true;
|
||||
m_Thread = std::move(std::thread(&CEventLoop::loop, this));
|
||||
}
|
||||
|
||||
void runSync()
|
||||
{
|
||||
stop();
|
||||
m_Running = true;
|
||||
loop();
|
||||
}
|
||||
|
||||
void stop() // thread-safe
|
||||
{
|
||||
m_Running = false;
|
||||
poke();
|
||||
if (m_Thread.joinable())
|
||||
m_Thread.join();
|
||||
}
|
||||
|
||||
void clear() // thread-safe
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_QueueLock);
|
||||
std::unique_lock<std::mutex> tlock(m_QueueTimeoutLock);
|
||||
m_Immediate = std::move(std::queue<std::function<void()>>());
|
||||
m_Timeout = std::move(std::priority_queue<timeout_func>());
|
||||
}
|
||||
|
||||
void clear(int handle) // thread-safe, relatively slow, not recommended nor reliable to do this for timeouts, only reliable for intervals
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_QueueTimeoutLock);
|
||||
std::priority_queue<timeout_func> timeout;
|
||||
while (m_Timeout.size())
|
||||
{
|
||||
if (m_Timeout.top().handle != handle)
|
||||
timeout.push(m_Timeout.top());
|
||||
m_Timeout.pop();
|
||||
}
|
||||
m_Timeout = std::move(timeout);
|
||||
}
|
||||
|
||||
void join() // thread-safe
|
||||
{
|
||||
std::mutex syncLock;
|
||||
std::condition_variable syncCond;
|
||||
std::unique_lock<std::mutex> lock(syncLock);
|
||||
immediate([this, &syncCond]() -> void {
|
||||
syncCond.notify_one();
|
||||
});
|
||||
m_PokeCond.wait(lock);
|
||||
}
|
||||
|
||||
public:
|
||||
void immediate(std::function<void()> f) // thread-safe
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_QueueLock);
|
||||
m_Immediate.push(f);
|
||||
poke();
|
||||
}
|
||||
|
||||
template<class rep, class period>
|
||||
int timeout(std::function<void()> f, const std::chrono::duration<rep, period>& delta) // thread-safe
|
||||
{
|
||||
timeout_func tf;
|
||||
tf.f = f;
|
||||
tf.time = std::chrono::steady_clock::now() + delta;
|
||||
tf.interval = std::chrono::nanoseconds::zero();
|
||||
tf.handle = ++m_Handle;
|
||||
; {
|
||||
std::unique_lock<std::mutex> lock(m_QueueTimeoutLock);
|
||||
m_Timeout.push(tf);
|
||||
poke();
|
||||
}
|
||||
return tf.handle;
|
||||
}
|
||||
|
||||
template<class rep, class period>
|
||||
int interval(std::function<void()> f, const std::chrono::duration<rep, period>& interval) // thread-safe
|
||||
{
|
||||
timeout_func tf;
|
||||
tf.f = f;
|
||||
tf.time = std::chrono::steady_clock::now() + interval;
|
||||
tf.interval = interval;
|
||||
tf.handle = ++m_Handle;
|
||||
; {
|
||||
std::unique_lock<std::mutex> lock(m_QueueTimeoutLock);
|
||||
m_Timeout.push(tf);
|
||||
poke();
|
||||
}
|
||||
return tf.handle;
|
||||
}
|
||||
|
||||
int timed(std::function<void()> f, const std::chrono::steady_clock::time_point &point) // thread-safe
|
||||
{
|
||||
timeout_func tf;
|
||||
tf.f = f;
|
||||
tf.time = point;
|
||||
tf.interval = std::chrono::steady_clock::duration::zero();
|
||||
tf.handle = ++m_Handle;
|
||||
; {
|
||||
std::unique_lock<std::mutex> lock(m_QueueTimeoutLock);
|
||||
m_Timeout.push(tf);
|
||||
poke();
|
||||
}
|
||||
return tf.handle;
|
||||
}
|
||||
|
||||
public:
|
||||
void thread(std::function<void()> f, std::function<void()> callback)
|
||||
{
|
||||
std::thread t([this, f, callback]() -> void {
|
||||
f();
|
||||
immediate(callback);
|
||||
});
|
||||
t.detach();
|
||||
}
|
||||
|
||||
private:
|
||||
void loop()
|
||||
{
|
||||
while (m_Running)
|
||||
{
|
||||
m_Poked = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
m_QueueLock.lock();
|
||||
if (!m_Immediate.size())
|
||||
{
|
||||
m_QueueLock.unlock();
|
||||
break;
|
||||
}
|
||||
std::function<void()> f = m_Immediate.front();
|
||||
m_Immediate.pop();
|
||||
m_QueueLock.unlock();
|
||||
f();
|
||||
}
|
||||
|
||||
bool poked = false;
|
||||
for (;;)
|
||||
{
|
||||
m_QueueTimeoutLock.lock();
|
||||
if (!m_Timeout.size())
|
||||
{
|
||||
m_QueueTimeoutLock.unlock();
|
||||
break;
|
||||
}
|
||||
const timeout_func &tfr = m_Timeout.top();
|
||||
if (tfr.time > std::chrono::steady_clock::now()) // wait
|
||||
{
|
||||
m_QueueTimeoutLock.unlock();
|
||||
; {
|
||||
std::unique_lock<std::mutex> lock(m_PokeLock);
|
||||
if (!m_Poked)
|
||||
m_PokeCond.wait_until(lock, tfr.time);
|
||||
}
|
||||
poked = true;
|
||||
break;
|
||||
}
|
||||
timeout_func tf = tfr;
|
||||
m_Timeout.pop();
|
||||
m_QueueTimeoutLock.unlock();
|
||||
tf.f(); // call
|
||||
if (tf.interval > std::chrono::nanoseconds::zero()) // repeat
|
||||
{
|
||||
tf.time += tf.interval;
|
||||
; {
|
||||
std::unique_lock<std::mutex> lock(m_QueueTimeoutLock);
|
||||
m_Timeout.push(tf);
|
||||
poke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!poked)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_PokeLock);
|
||||
if (!m_Poked)
|
||||
m_PokeCond.wait(lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void poke() // private
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_PokeLock);
|
||||
m_PokeCond.notify_one();
|
||||
m_Poked = true;
|
||||
}
|
||||
|
||||
private:
|
||||
struct timeout_func
|
||||
{
|
||||
std::function<void()> f;
|
||||
std::chrono::steady_clock::time_point time;
|
||||
std::chrono::steady_clock::duration interval;
|
||||
int handle;
|
||||
|
||||
bool operator <(const timeout_func &o) const
|
||||
{
|
||||
return time > o.time;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
volatile bool m_Running;
|
||||
volatile bool m_Poked;
|
||||
std::thread m_Thread;
|
||||
std::mutex m_PokeLock;
|
||||
std::condition_variable m_PokeCond;
|
||||
|
||||
std::mutex m_QueueLock;
|
||||
std::queue<std::function<void()>> m_Immediate;
|
||||
std::mutex m_QueueTimeoutLock;
|
||||
std::priority_queue<timeout_func> m_Timeout;
|
||||
int m_Handle;
|
||||
|
||||
};
|
||||
|
||||
#endif /* NL_EVENT_LOOP_H */
|
||||
|
||||
/* end of file */
|
Loading…
Reference in New Issue